[PATCH] libselinux: simplify procattr cache

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



https://github.com/systemd/systemd/issues/475 identified a problem
in libselinux with using getpid(3) rather than getpid(2) due to direct
use of the clone() system call by systemd.  We could change libselinux
to use getpid(2) instead, but this would impose a getpid(2) system call
overhead on each get*con() or set*con() call.  Rather than do this,
we can instead simplify the procattr cache and get rid of the
caching of the pid and tid entirely, along with the atfork handler.
With commit 3430519109c0423a49b9350aa8444beec798d5a7 ("use
/proc/thread-self when available"), we only need the tid when
on Linux < 3.17, so we can just always call gettid() in that case (as
done prior to the procattr cache) and drop the cached tid. The cached
pid and atfork handlers were only needed to reset the cached tid, so
those can also be dropped. The rest of the cached attributes are not
reset by the kernel on fork, only on exec, so we do not need to
flush them upon fork/clone.

Signed-off-by: Stephen Smalley <sds@xxxxxxxxxxxxx>
---
 libselinux/src/procattr.c | 34 +++-------------------------------
 1 file changed, 3 insertions(+), 31 deletions(-)

diff --git a/libselinux/src/procattr.c b/libselinux/src/procattr.c
index e444571..527a0a5 100644
--- a/libselinux/src/procattr.c
+++ b/libselinux/src/procattr.c
@@ -11,8 +11,6 @@
 
 #define UNSET (char *) -1
 
-static __thread pid_t cpid;
-static __thread pid_t tid;
 static __thread char *prev_current = UNSET;
 static __thread char * prev_exec = UNSET;
 static __thread char * prev_fscreate = UNSET;
@@ -24,15 +22,6 @@ static pthread_key_t destructor_key;
 static int destructor_key_initialized = 0;
 static __thread char destructor_initialized;
 
-extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden")));
-extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *);
-
-static int __selinux_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void))
-{
-  return __register_atfork (prepare, parent, child,
-                            &__dso_handle == NULL ? NULL : __dso_handle);
-}
-
 static pid_t gettid(void)
 {
 	return syscall(__NR_gettid);
@@ -52,14 +41,6 @@ static void procattr_thread_destructor(void __attribute__((unused)) *unused)
 		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 = UNSET;
-}
-
 void __attribute__((destructor)) procattr_destructor(void);
 
 void hidden __attribute__((destructor)) procattr_destructor(void)
@@ -79,7 +60,6 @@ static inline void init_thread_destructor(void)
 static void init_procattr(void)
 {
 	if (__selinux_key_create(&destructor_key, procattr_thread_destructor) == 0) {
-		__selinux_atfork(NULL, NULL, free_procattr);
 		destructor_key_initialized = 1;
 	}
 }
@@ -88,9 +68,7 @@ static int openattr(pid_t pid, const char *attr, int flags)
 {
 	int fd, rc;
 	char *path;
-
-	if (cpid != getpid())
-		free_procattr();
+	pid_t tid;
 
 	if (pid > 0)
 		rc = asprintf(&path, "/proc/%d/attr/%s", pid, attr);
@@ -101,8 +79,8 @@ static int openattr(pid_t pid, const char *attr, int flags)
 		fd = open(path, flags | O_CLOEXEC);
 		if (fd >= 0 || errno != ENOENT)
 			goto out;
-		if (!tid)
-			tid = gettid();
+		free(path);
+		tid = gettid();
 		rc = asprintf(&path, "/proc/self/task/%d/attr/%s", tid, attr);
 	}
 	if (rc < 0)
@@ -127,9 +105,6 @@ static int getprocattrcon_raw(char ** context,
 	__selinux_once(once, init_procattr);
 	init_thread_destructor();
 
-	if (cpid != getpid())
-		free_procattr();
-
 	switch (attr[0]) {
 		case 'c':
 			prev_context = prev_current;
@@ -227,9 +202,6 @@ static int setprocattrcon_raw(const char * context,
 	__selinux_once(once, init_procattr);
 	init_thread_destructor();
 
-	if (cpid != getpid())
-		free_procattr();
-
 	switch (attr[0]) {
 		case 'c':
 			prev_context = &prev_current;
-- 
2.1.0

_______________________________________________
Selinux mailing list
Selinux@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.



[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux