From 0a9b6f58d090f2e5cff3876a8244363cdf9cbe50 Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Wed, 23 Jan 2013 14:26:18 -0500 Subject: [PATCH] Try procatt speedup patch again --- libselinux-rhat.patch | 246 ++++++++++++++++++++++++++++++++++++++++++ libselinux.spec | 5 +- 2 files changed, 250 insertions(+), 1 deletion(-) diff --git a/libselinux-rhat.patch b/libselinux-rhat.patch index 074a7f1..de58d4f 100644 --- a/libselinux-rhat.patch +++ b/libselinux-rhat.patch @@ -6699,6 +6699,252 @@ index 2d7369e..2a00807 100644 va_end(ap); } +diff --git a/libselinux/src/procattr.c b/libselinux/src/procattr.c +index 83381e4..c1d4990 100644 +--- a/libselinux/src/procattr.c ++++ b/libselinux/src/procattr.c +@@ -1,6 +1,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -8,33 +9,135 @@ + #include "selinux_internal.h" + #include "policy.h" + ++static __thread pid_t cpid; ++static __thread pid_t tid; ++static __thread security_context_t prev_current; ++static __thread security_context_t prev_exec; ++static __thread security_context_t prev_fscreate; ++static __thread security_context_t prev_keycreate; ++static __thread security_context_t prev_sockcreate; ++ ++static pthread_once_t once = PTHREAD_ONCE_INIT; ++static pthread_key_t destructor_key; ++static int destructor_key_initialized = 0; ++static __thread char destructor_initialized; ++ + static pid_t gettid(void) + { + return syscall(__NR_gettid); + } + +-static int getprocattrcon_raw(security_context_t * context, +- pid_t pid, const char *attr) ++static void procattr_thread_destructor(void __attribute__((unused)) *unused) ++{ ++ free(prev_current); ++ free(prev_exec); ++ free(prev_fscreate); ++ free(prev_keycreate); ++ free(prev_sockcreate); ++} ++ ++static void free_procattr(void) ++{ ++ procattr_thread_destructor(NULL); ++ tid = 0; ++ cpid = getpid(); ++ prev_current = prev_exec = prev_fscreate = prev_keycreate = prev_sockcreate = NULL; ++} ++ ++void __attribute__((destructor)) procattr_destructor(void); ++ ++void hidden __attribute__((destructor)) procattr_destructor(void) ++{ ++ if (destructor_key_initialized) ++ __selinux_key_delete(destructor_key); ++} ++ ++static inline void init_thread_destructor(void) ++{ ++ if (destructor_initialized == 0) { ++ __selinux_setspecific(destructor_key, (void *)1); ++ destructor_initialized = 1; ++ } ++} ++ ++static void init_procattr(void) ++{ ++ if (__selinux_key_create(&destructor_key, procattr_thread_destructor) == 0) { ++ pthread_atfork(NULL, NULL, free_procattr); ++ destructor_key_initialized = 1; ++ } ++} ++ ++static int openattr(pid_t pid, const char *attr, int flags) + { +- char *path, *buf; +- size_t size; + int fd, rc; +- ssize_t ret; +- pid_t tid; +- int errno_hold; ++ char *path; + + if (pid > 0) + rc = asprintf(&path, "/proc/%d/attr/%s", pid, attr); + else { +- tid = gettid(); ++ if (!tid) ++ tid = gettid(); + rc = asprintf(&path, "/proc/self/task/%d/attr/%s", tid, attr); + } + if (rc < 0) + return -1; + +- fd = open(path, O_RDONLY); ++ fd = open(path, flags); + free(path); +- if (fd < 0) ++ return fd; ++} ++ ++static int getprocattrcon_raw(security_context_t * context, ++ pid_t pid, const char *attr) ++{ ++ char *buf; ++ size_t size; ++ int fd; ++ ssize_t ret; ++ int errno_hold; ++ security_context_t prev_context; ++ ++ __selinux_once(once, init_procattr); ++ init_thread_destructor(); ++ ++ if (cpid != getpid()) ++ free_procattr(); ++ ++ switch (attr[0]) { ++ case 'c': ++ prev_context = prev_current; ++ break; ++ case 'e': ++ prev_context = prev_exec; ++ break; ++ case 'f': ++ prev_context = prev_fscreate; ++ break; ++ case 'k': ++ prev_context = prev_keycreate; ++ break; ++ case 's': ++ prev_context = prev_sockcreate; ++ break; ++ case 'p': ++ prev_context = NULL; ++ break; ++ default: ++ errno = ENOENT; ++ return -1; ++ }; ++ ++ if (prev_context) { ++ *context = strdup(prev_context); ++ if (!(*context)) { ++ return -1; ++ } ++ return 0; ++ } ++ ++ fd = openattr(pid, attr, O_RDONLY); ++ if (fd < 0) + return -1; + + size = selinux_page_size; +@@ -90,40 +193,70 @@ static int getprocattrcon(security_context_t * context, + static int setprocattrcon_raw(security_context_t context, + pid_t pid, const char *attr) + { +- char *path; +- int fd, rc; +- pid_t tid; ++ int fd; + ssize_t ret; + int errno_hold; ++ security_context_t *prev_context; + +- if (pid > 0) +- rc = asprintf(&path, "/proc/%d/attr/%s", pid, attr); +- else { +- tid = gettid(); +- rc = asprintf(&path, "/proc/self/task/%d/attr/%s", tid, attr); +- } +- if (rc < 0) +- return -1; ++ __selinux_once(once, init_procattr); ++ init_thread_destructor(); + +- fd = open(path, O_RDWR); +- free(path); ++ if (cpid != getpid()) ++ free_procattr(); ++ ++ switch (attr[0]) { ++ case 'c': ++ prev_context = &prev_current; ++ break; ++ case 'e': ++ prev_context = &prev_exec; ++ break; ++ case 'f': ++ prev_context = &prev_fscreate; ++ break; ++ case 'k': ++ prev_context = &prev_keycreate; ++ break; ++ case 's': ++ prev_context = &prev_sockcreate; ++ break; ++ default: ++ errno = ENOENT; ++ return -1; ++ }; ++ ++ if (!context && !*prev_context) ++ return 0; ++ if (context && *prev_context && !strcmp(context, *prev_context)) ++ return 0; ++ ++ fd = openattr(pid, attr, O_RDWR); + if (fd < 0) + return -1; +- if (context) ++ if (context) { ++ ret = -1; ++ context = strdup(context); ++ if (!context) ++ goto out; + do { + ret = write(fd, context, strlen(context) + 1); + } while (ret < 0 && errno == EINTR); +- else ++ } else { + do { + ret = write(fd, NULL, 0); /* clear */ + } while (ret < 0 && errno == EINTR); ++ } ++out: + errno_hold = errno; + close(fd); + errno = errno_hold; +- if (ret < 0) ++ if (ret < 0) { ++ free(context); + return -1; +- else ++ } else { ++ *prev_context = context; + return 0; ++ } + } + + static int setprocattrcon(const security_context_t context, diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c index 296f357..cb65666 100644 --- a/libselinux/src/selinux_config.c diff --git a/libselinux.spec b/libselinux.spec index 8b8b430..5d7d0ef 100644 --- a/libselinux.spec +++ b/libselinux.spec @@ -10,7 +10,7 @@ Summary: SELinux library and simple utilities Name: libselinux Version: 2.1.12 -Release: 17%{?dist} +Release: 18%{?dist} License: Public Domain Group: System Environment/Libraries Source: %{name}-%{version}.tgz @@ -241,6 +241,9 @@ rm -rf %{buildroot} %{ruby_sitearch}/selinux.so %changelog +* Wed Jan 23 2013 Dan Walsh - 2.1.12-18 +- Try procatt speedup patch again + * Wed Jan 23 2013 Dan Walsh - 2.1.12-17 - Roll back procattr speedups since it seems to be screwing up systemd labeling.