X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust-fork%2Fustfork.c;h=983ed04f83e11316690430e494ffe4939a44bd9b;hb=32974710aab75d01a8ae48d0be3641c2f56e45a9;hp=43b8d8f69a39e3683f59a02d1a4db76b990df3f2;hpb=eb2b066ff35dcafa727fae7e8853a9750233063e;p=lttng-ust.git diff --git a/liblttng-ust-fork/ustfork.c b/liblttng-ust-fork/ustfork.c index 43b8d8f6..983ed04f 100644 --- a/liblttng-ust-fork/ustfork.c +++ b/liblttng-ust-fork/ustfork.c @@ -33,6 +33,7 @@ pid_t fork(void) static pid_t (*plibc_func)(void) = NULL; sigset_t sigset; pid_t retval; + int saved_errno; if (plibc_func == NULL) { plibc_func = dlsym(RTLD_NEXT, "fork"); @@ -46,12 +47,14 @@ pid_t fork(void) ust_before_fork(&sigset); /* Do the real fork */ retval = plibc_func(); + saved_errno = errno; if (retval == 0) { /* child */ ust_after_fork_child(&sigset); } else { ust_after_fork_parent(&sigset); } + errno = saved_errno; return retval; } @@ -60,6 +63,7 @@ int daemon(int nochdir, int noclose) static int (*plibc_func)(int nochdir, int noclose) = NULL; sigset_t sigset; int retval; + int saved_errno; if (plibc_func == NULL) { plibc_func = dlsym(RTLD_NEXT, "daemon"); @@ -73,6 +77,7 @@ int daemon(int nochdir, int noclose) ust_before_fork(&sigset); /* Do the real daemon call */ retval = plibc_func(nochdir, noclose); + saved_errno = errno; if (retval == 0) { /* child, parent called _exit() directly */ ust_after_fork_child(&sigset); @@ -80,6 +85,157 @@ int daemon(int nochdir, int noclose) /* on error in the parent */ ust_after_fork_parent(&sigset); } + errno = saved_errno; + return retval; +} + +int setuid(uid_t uid) +{ + static int (*plibc_func)(uid_t uid) = NULL; + int retval; + int saved_errno; + + if (plibc_func == NULL) { + plibc_func = dlsym(RTLD_NEXT, "setuid"); + if (plibc_func == NULL) { + fprintf(stderr, "libustfork: unable to find \"setuid\" symbol\n"); + errno = ENOSYS; + return -1; + } + } + + /* Do the real setuid */ + retval = plibc_func(uid); + saved_errno = errno; + + ust_after_setuid(); + + errno = saved_errno; + return retval; +} + +int setgid(gid_t gid) +{ + static int (*plibc_func)(gid_t gid) = NULL; + int retval; + int saved_errno; + + if (plibc_func == NULL) { + plibc_func = dlsym(RTLD_NEXT, "setgid"); + if (plibc_func == NULL) { + fprintf(stderr, "libustfork: unable to find \"setgid\" symbol\n"); + errno = ENOSYS; + return -1; + } + } + + /* Do the real setgid */ + retval = plibc_func(gid); + saved_errno = errno; + + ust_after_setgid(); + + errno = saved_errno; + return retval; +} + +int seteuid(uid_t euid) +{ + static int (*plibc_func)(uid_t euid) = NULL; + int retval; + int saved_errno; + + if (plibc_func == NULL) { + plibc_func = dlsym(RTLD_NEXT, "seteuid"); + if (plibc_func == NULL) { + fprintf(stderr, "libustfork: unable to find \"seteuid\" symbol\n"); + errno = ENOSYS; + return -1; + } + } + + /* Do the real seteuid */ + retval = plibc_func(euid); + saved_errno = errno; + + ust_after_seteuid(); + + errno = saved_errno; + return retval; +} + +int setegid(gid_t egid) +{ + static int (*plibc_func)(gid_t egid) = NULL; + int retval; + int saved_errno; + + if (plibc_func == NULL) { + plibc_func = dlsym(RTLD_NEXT, "setegid"); + if (plibc_func == NULL) { + fprintf(stderr, "libustfork: unable to find \"setegid\" symbol\n"); + errno = ENOSYS; + return -1; + } + } + + /* Do the real setegid */ + retval = plibc_func(egid); + saved_errno = errno; + + ust_after_setegid(); + + errno = saved_errno; + return retval; +} + +int setreuid(uid_t ruid, uid_t euid) +{ + static int (*plibc_func)(uid_t ruid, uid_t euid) = NULL; + int retval; + int saved_errno; + + if (plibc_func == NULL) { + plibc_func = dlsym(RTLD_NEXT, "setreuid"); + if (plibc_func == NULL) { + fprintf(stderr, "libustfork: unable to find \"setreuid\" symbol\n"); + errno = ENOSYS; + return -1; + } + } + + /* Do the real setreuid */ + retval = plibc_func(ruid, euid); + saved_errno = errno; + + ust_after_setreuid(); + + errno = saved_errno; + return retval; +} + +int setregid(gid_t rgid, gid_t egid) +{ + static int (*plibc_func)(gid_t rgid, gid_t egid) = NULL; + int retval; + int saved_errno; + + if (plibc_func == NULL) { + plibc_func = dlsym(RTLD_NEXT, "setregid"); + if (plibc_func == NULL) { + fprintf(stderr, "libustfork: unable to find \"setregid\" symbol\n"); + errno = ENOSYS; + return -1; + } + } + + /* Do the real setregid */ + retval = plibc_func(rgid, egid); + saved_errno = errno; + + ust_after_setregid(); + + errno = saved_errno; return retval; } @@ -114,6 +270,7 @@ int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) /* end of var args */ va_list ap; int retval; + int saved_errno; va_start(ap, arg); ptid = va_arg(ap, pid_t *); @@ -137,6 +294,7 @@ int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) */ retval = plibc_func(fn, child_stack, flags, arg, ptid, tls, ctid); + saved_errno = errno; } else { /* Creating a real process, we need to intervene. */ struct ustfork_clone_info info = { .fn = fn, .arg = arg }; @@ -144,9 +302,111 @@ int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) ust_before_fork(&info.sigset); retval = plibc_func(clone_fn, child_stack, flags, &info, ptid, tls, ctid); + saved_errno = errno; /* The child doesn't get here. */ ust_after_fork_parent(&info.sigset); } + errno = saved_errno; + return retval; +} + +int setns(int fd, int nstype) +{ + static int (*plibc_func)(int fd, int nstype) = NULL; + int retval; + int saved_errno; + + if (plibc_func == NULL) { + plibc_func = dlsym(RTLD_NEXT, "setns"); + if (plibc_func == NULL) { + fprintf(stderr, "libustfork: unable to find \"setns\" symbol\n"); + errno = ENOSYS; + return -1; + } + } + + /* Do the real setns */ + retval = plibc_func(fd, nstype); + saved_errno = errno; + + ust_after_setns(); + + errno = saved_errno; + return retval; +} + +int unshare(int flags) +{ + static int (*plibc_func)(int flags) = NULL; + int retval; + int saved_errno; + + if (plibc_func == NULL) { + plibc_func = dlsym(RTLD_NEXT, "unshare"); + if (plibc_func == NULL) { + fprintf(stderr, "libustfork: unable to find \"unshare\" symbol\n"); + errno = ENOSYS; + return -1; + } + } + + /* Do the real setns */ + retval = plibc_func(flags); + saved_errno = errno; + + ust_after_unshare(); + + errno = saved_errno; + return retval; +} + +int setresuid(uid_t ruid, uid_t euid, uid_t suid) +{ + static int (*plibc_func)(uid_t ruid, uid_t euid, uid_t suid) = NULL; + int retval; + int saved_errno; + + if (plibc_func == NULL) { + plibc_func = dlsym(RTLD_NEXT, "setresuid"); + if (plibc_func == NULL) { + fprintf(stderr, "libustfork: unable to find \"setresuid\" symbol\n"); + errno = ENOSYS; + return -1; + } + } + + /* Do the real setresuid */ + retval = plibc_func(ruid, euid, suid); + saved_errno = errno; + + ust_after_setresuid(); + + errno = saved_errno; + return retval; +} + +int setresgid(gid_t rgid, gid_t egid, gid_t sgid) +{ + static int (*plibc_func)(gid_t rgid, gid_t egid, gid_t sgid) = NULL; + int retval; + int saved_errno; + + if (plibc_func == NULL) { + plibc_func = dlsym(RTLD_NEXT, "setresgid"); + if (plibc_func == NULL) { + fprintf(stderr, "libustfork: unable to find \"setresgid\" symbol\n"); + errno = ENOSYS; + return -1; + } + } + + /* Do the real setresgid */ + retval = plibc_func(rgid, egid, sgid); + saved_errno = errno; + + ust_after_setresgid(); + + errno = saved_errno; return retval; } @@ -157,6 +417,7 @@ pid_t rfork(int flags) static pid_t (*plibc_func)(void) = NULL; sigset_t sigset; pid_t retval; + int saved_errno; if (plibc_func == NULL) { plibc_func = dlsym(RTLD_NEXT, "rfork"); @@ -170,12 +431,14 @@ pid_t rfork(int flags) ust_before_fork(&sigset); /* Do the real rfork */ retval = plibc_func(); + saved_errno = errno; if (retval == 0) { /* child */ ust_after_fork_child(&sigset); } else { ust_after_fork_parent(&sigset); } + errno = saved_errno; return retval; }