@@ -10,6 +10,8 @@
#include <selinux/selinux.h>
#include "callbacks.h"
+pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
+
/* default implementations */
static int __attribute__ ((format(printf, 2, 3)))
default_selinux_log(int type __attribute__((unused)), const char *fmt, ...)
@@ -56,7 +58,7 @@ default_selinux_policyload(int seqno __attribute__((unused)))
/* callback pointers */
int __attribute__ ((format(printf, 2, 3)))
-(*selinux_log)(int, const char *, ...) =
+(*selinux_log_direct)(int, const char *, ...) =
default_selinux_log;
int
@@ -81,7 +83,7 @@ selinux_set_callback(int type, union selinux_callback cb)
{
switch (type) {
case SELINUX_CB_LOG:
- selinux_log = cb.func_log;
+ selinux_log_direct = cb.func_log;
break;
case SELINUX_CB_AUDIT:
selinux_audit = cb.func_audit;
@@ -106,7 +108,7 @@ selinux_get_callback(int type)
switch (type) {
case SELINUX_CB_LOG:
- cb.func_log = selinux_log;
+ cb.func_log = selinux_log_direct;
break;
case SELINUX_CB_AUDIT:
cb.func_audit = selinux_audit;
@@ -10,9 +10,11 @@
#include <string.h>
#include <selinux/selinux.h>
+#include "selinux_internal.h"
+
/* callback pointers */
extern int __attribute__ ((format(printf, 2, 3)))
-(*selinux_log) (int type, const char *, ...) ;
+(*selinux_log_direct) (int type, const char *, ...) ;
extern int
(*selinux_audit) (void *, security_class_t, char *, size_t) ;
@@ -26,4 +28,13 @@ extern int
extern int
(*selinux_netlink_policyload) (int seqno) ;
+/* Thread-safe selinux_log() function */
+extern pthread_mutex_t log_mutex;
+
+#define selinux_log(type, ...) do { \
+ __pthread_mutex_lock(&log_mutex); \
+ selinux_log_direct(type, __VA_ARGS__); \
+ __pthread_mutex_unlock(&log_mutex); \
+} while(0)
+
#endif /* _SELINUX_CALLBACKS_H_ */
Ensure that selinux_log() is thread-safe by guarding the call to the underlying callback with a mutex. Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> --- libselinux/src/callbacks.c | 8 +++++--- libselinux/src/callbacks.h | 13 ++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-)