uwrap: Extend support for syscalls called from threads or main process.
authorRobin Hack <hack.robin@gmail.com>
Fri, 23 Jan 2015 14:24:39 +0000 (15:24 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Wed, 28 Jan 2015 16:17:07 +0000 (17:17 +0100)
We need to distinguish if the syscall is called from main process or
from a thread.

Signed-off-by: Robin Hack <hack.robin@gmail.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
lib/uid_wrapper/uid_wrapper.c

index 9b35a1810f4168cab4ac15d6d3278f88d11236d8..a2ad6665bc794da7a42f153f43d4ca259f4f93b2 100644 (file)
@@ -234,6 +234,8 @@ struct uwrap_thread {
 };
 
 struct uwrap {
+       pthread_t tid;
+
        struct {
                void *handle;
                struct uwrap_libc_fns fns;
@@ -587,6 +589,9 @@ static void uwrap_thread_child(void)
 {
        uwrap.enabled = true;
 
+       /* We need to update to the new tid if we fork */
+       uwrap.tid = pthread_self();
+
        UWRAP_UNLOCK(libc_symbol_binding);
        UWRAP_UNLOCK(uwrap_id);
 }
@@ -649,6 +654,7 @@ static void uwrap_init(void)
                        exit(-1);
                }
 
+               uwrap.tid = tid;
                uwrap.enabled = true;
 
                UWRAP_LOG(UWRAP_LOG_DEBUG,
@@ -695,6 +701,22 @@ static int uwrap_setresuid_thread(uid_t ruid, uid_t euid, uid_t suid)
        if (suid != (uid_t)-1) {
                id->suid = suid;
        }
+
+       /* Check If syscall is called from main thread. */
+       if (pthread_equal(id->tid, uwrap.tid)) {
+               if (ruid != (uid_t)-1) {
+                   uwrap.ruid = ruid;
+               }
+
+               if (euid != (uid_t)-1) {
+                   uwrap.euid = euid;
+               }
+
+               if (suid != (uid_t)-1) {
+                   uwrap.suid = suid;
+               }
+       }
+
        UWRAP_UNLOCK(uwrap_id);
 
        return 0;
@@ -882,6 +904,20 @@ static int uwrap_setresgid_thread(gid_t rgid, gid_t egid, gid_t sgid)
        if (sgid != (gid_t)-1) {
                id->sgid = sgid;
        }
+
+       if (pthread_equal(id->tid, uwrap.tid)) {
+               if (rgid != (gid_t)-1) {
+                       uwrap.rgid = rgid;
+               }
+
+               if (egid != (gid_t)-1) {
+                       uwrap.egid = egid;
+               }
+
+               if (sgid != (gid_t)-1) {
+                       uwrap.sgid = sgid;
+               }
+       }
        UWRAP_UNLOCK(uwrap_id);
 
        return 0;