X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Frpm-fake.c;h=6d52e98b6dc23428994ad5051892f4d9bf121f2a;hb=2fbc46a92318904f1414f1aeaf256970e80e845a;hp=c751dc8d59ab5997131dbcddb6733f2c18fc88fb;hpb=724ab5b8c85dd45b6ad3c682d402f554f862f549;p=util-vserver.git diff --git a/src/rpm-fake.c b/src/rpm-fake.c index c751dc8..6d52e98 100644 --- a/src/rpm-fake.c +++ b/src/rpm-fake.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include @@ -49,7 +49,7 @@ #include #include #include -#include + // from selinux.h // FIXME: add configure autodetection and include directly @@ -419,22 +419,30 @@ initPwSocket() static void reduceCapabilities() { + int retried = 0; struct __user_cap_header_struct header; - struct __user_cap_data_struct user; + struct __user_cap_data_struct user[2]; - header.version = _LINUX_CAPABILITY_VERSION; + header.version = _LINUX_CAPABILITY_VERSION_3; header.pid = 0; - if (capget(&header, &user)==-1) { +retry: + if (capget(&header, user)==-1) { + if (!retried && + header.version != _LINUX_CAPABILITY_VERSION_3) { + header.version = _LINUX_CAPABILITY_VERSION_1; + retried = 1; + goto retry; + } perror("capget()"); exit(wrapper_exit_code); } - user.effective &= ~(1<mnts)+1], *ptr; - strcpy(buf, mnts); + strcpy(buf, params->mnts); ptr = strtok(buf, ":"); while (ptr) { if (umount2(ptr, 0)==-1) { @@ -648,28 +664,54 @@ removeNamespaceMounts(char const *mnts) ptr = strtok(0, ":"); } - return 0; + return execvWorker(params->path, params->argv, params->envp); } static int -execv_main(char const *path, char * const argv[], char * const envp[]) +removeNamespaceMounts(char const *path, + char * const argv[], char * const envp[]) { - int rc = 0; + if (mnts==0) return execvWorker(path, argv, envp); - if (sys_unshare(CLONE_NEWNS)==-1) { - perror("unshare()"); - return -1; - } + { + int status; + pid_t p, pid; + struct ExecvParams params; - if (mnts) - rc = removeNamespaceMounts(mnts); + params.path = path; + params.argv = argv; + params.envp = envp; + params.mnts = mnts; - if (rc!=0) - return rc; - - return execvWorker(path, argv, envp); + // the rpmlib signal-handler is still active; use the default one to + // make wait4() working... + signal(SIGCHLD, SIG_DFL); + +#ifdef NDEBUG + pid = sys_clone(CLONE_NEWNS|SIGCHLD|CLONE_VFORK, 0); +#else + pid = sys_clone(CLONE_NEWNS|SIGCHLD, 0); +#endif + + switch (pid) { + case -1 : return -1; + case 0 : _exit(removeNamespaceMountsChild(¶ms)); + default : break; + } + + while ((p=wait4(pid, &status, 0,0))==-1 && + (errno==EINTR || errno==EAGAIN)) ; + + if (p==-1) return -1; + + if (WIFEXITED(status)) _exit(WEXITSTATUS(status)); + if (WIFSIGNALED(status)) kill(getpid(), WTERMSIG(status)); + + return -1; + } } + int execv(char const *path, char * const argv[]) { @@ -681,7 +723,7 @@ execv(char const *path, char * const argv[]) WRITE_MSG(2, "', ...)\n"); } - return execv_main(path, argv, environ); + return removeNamespaceMounts(path, argv, environ); } int @@ -695,7 +737,7 @@ rpm_execcon(unsigned int UNUSED verified, WRITE_MSG(2, "', ...)\n"); } - return execv_main(filename, argv, envp); + return removeNamespaceMounts(filename, argv, envp); } int