HBSD: Use a mutex to protect feature list traversal

In the case that libhbsdcontrol is used in a multi-threaded context, we
need to add a mutex to protect the context's feature linked list.

Signed-off-by:	Shawn Webb <shawn.webb@hardenedbsd.org>
(cherry picked from commit 9b4f75a0ea)
Signed-off-by: Shawn Webb <shawn.webb@hardenedbsd.org>
This commit is contained in:
Shawn Webb 2024-03-19 20:20:45 +00:00
parent ba22fcda53
commit 4aadfd2ab8
No known key found for this signature in database
4 changed files with 55 additions and 4 deletions

View File

@ -13,6 +13,7 @@ SRCS+= libhbsdcontrol.c
INCS= libhbsdcontrol.h
MAN=
LIBADD= util
LIBADD+= pthread
LIBADD+= util
.include <bsd.lib.mk>

View File

@ -61,6 +61,12 @@ hbsdctrl_ctx_new(hbsdctrl_flag_t flags, const char *ns)
return (NULL);
}
memset(&(ctx->hc_mtx), 0, sizeof(ctx->hc_mtx));
if (pthread_mutex_init(&(ctx->hc_mtx), NULL)) {
free(ctx);
return (NULL);
}
ctx->hc_version = LIBHBSDCONTROL_VERSION;
ctx->hc_flags = flags;
@ -82,10 +88,13 @@ hbsdctrl_ctx_free(hbsdctrl_ctx_t **ctxp)
ctx = *ctxp;
*ctxp = NULL;
pthread_mutex_lock(&(ctx->hc_mtx));
LIST_FOREACH_SAFE(feature, &(ctx->hc_features), hf_entry, tfeature) {
LIST_REMOVE(feature, hf_entry);
hbsdctrl_feature_free(&feature);
}
pthread_mutex_unlock(&(ctx->hc_mtx));
pthread_mutex_destroy(&(ctx->hc_mtx));
free(ctx);
}
@ -169,7 +178,9 @@ hbsdctrl_ctx_add_feature(hbsdctrl_ctx_t *ctx, hbsdctrl_feature_t *feature)
return (false);
}
pthread_mutex_lock(&(ctx->hc_mtx));
LIST_INSERT_HEAD(&(ctx->hc_features), feature, hf_entry);
pthread_mutex_unlock(&(ctx->hc_mtx));
return (true);
}
@ -182,17 +193,19 @@ hbsdctrl_ctx_find_feature_by_name(hbsdctrl_ctx_t *ctx, const char *name)
return (NULL);
}
pthread_mutex_lock(&(ctx->hc_mtx));
LIST_FOREACH_SAFE(feature, &(ctx->hc_features), hf_entry, tfeature) {
if (feature->hf_name == NULL) {
continue;
}
if (!strcmp(feature->hf_name, name)) {
return (feature);
break;
}
}
pthread_mutex_unlock(&(ctx->hc_mtx));
return (NULL);
return (feature);
}
hbsdctrl_feature_t *
@ -444,6 +457,10 @@ hbsdctrl_feature_call_cb(hbsdctrl_feature_t *feature, const char *name,
return (feature->hf_unapply(feature->hf_ctx, feature, arg1,
arg2));
}
if (!strcasecmp(name, "get") && feature->hf_get != NULL) {
return (feature->hf_get(feature->hf_ctx, feature, arg1,
arg2));
}
return (RES_FAIL);
}
@ -579,3 +596,30 @@ hbsdctrl_feature_state_is_flag_set(hbsdctrl_feature_state_t *state,
return ((state->hfs_flags & flag) == flag);
}
hbsdctrl_feature_cb_res_t
hbsdctrl_exec_all_features(hbsdctrl_ctx_t *ctx, const char *cbname,
bool bail_on_error, const void *arg1, void *arg2)
{
hbsdctrl_feature_t *feature, *tfeature;
hbsdctrl_feature_cb_res_t res, ret;
res = RES_SUCCESS;
ret = RES_SUCCESS;
pthread_mutex_lock(&(ctx->hc_mtx));
LIST_FOREACH_SAFE(feature, &(ctx->hc_features), hf_entry, tfeature) {
res = hbsdctrl_feature_call_cb(feature, cbname, arg1, arg2);
if (res != RES_SUCCESS) {
if (bail_on_error) {
ret = res;
goto end;
}
ret = res;
}
}
end:
pthread_mutex_unlock(&(ctx->hc_mtx));
return (ret);
}

View File

@ -29,6 +29,7 @@
#ifndef _LIBHBSDCONTROL_H
#define _LIBHBSDCONTROL_H
#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
@ -83,6 +84,7 @@ struct _hbsdctrl_ctx {
uint64_t hc_version;
hbsdctrl_flag_t hc_flags;
int hc_namespace;
pthread_mutex_t hc_mtx;
LIST_HEAD(,_hbsdctrl_feature) hc_features;
uint64_t hc_spare[32];
};
@ -161,6 +163,9 @@ hbsdctrl_flag_t hbsdctrl_feature_state_set_flags(hbsdctrl_feature_state_t *,
bool hbsdctrl_feature_state_is_flag_set(hbsdctrl_feature_state_t *,
hbsdctrl_flag_t);
hbsdctrl_feature_cb_res_t hbsdctrl_exec_all_features(hbsdctrl_ctx_t *,
const char *, bool, const void *, void *);
/* aslr.c */
hbsdctrl_feature_t *hbsdctrl_feature_aslr_new(hbsdctrl_ctx_t *,
hbsdctrl_flag_t);

View File

@ -238,7 +238,8 @@ _LIBRARIES+= \
.if ${MK_HBSDCONTROL} != "no"
_LIBRARIES+= hbsdcontrol
_DP_hbsdcontrol= util
_DP_hbsdcontrol+= pthread
_DP_hbsdcontrol+= util
.endif
.if ${MK_OFED} != "no"