X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Frpm-fake.c;h=b3b641a9436c94f88e2bed380ace2d5c3c19a1cd;hb=090a340dad3e79a3ccfa6954c779f5abf71f0f60;hp=7b279231b071c237b1753ffbb34c09321a5ad21c;hpb=8107139f08c72f5097129b525f473382c4e839e5;p=util-vserver.git diff --git a/util-vserver/src/rpm-fake.c b/util-vserver/src/rpm-fake.c index 7b27923..b3b641a 100644 --- a/util-vserver/src/rpm-fake.c +++ b/util-vserver/src/rpm-fake.c @@ -63,6 +63,9 @@ int rpm_execcon(unsigned int verified, #define ENSC_WRAPPERS_UNISTD 1 #include +#undef _POSIX_SOURCE +#include "capability-compat.h" + #ifndef CLONE_NEWNS # define CLONE_NEWNS 0x00020000 #endif @@ -73,11 +76,13 @@ int rpm_execcon(unsigned int verified, #define INIT(FILE,FUNC) FUNC##_func = ((__typeof__(FUNC) *) (xdlsym(FILE, #FUNC))) #define DECLARE(FUNC) static __typeof__(FUNC) * FUNC##_func = 0 +#define DEBUG 1 #define DBG_INIT 0x0001 #define DBG_VARIABLES 0x0002 #define DBG_RESOLVER 0x0004 #define DBG_EXECV 0x0008 +#define DBG_ENV 0x0010 #define DBG_VERBOSE0 0x8000 #define DBG_VERBOSE1 (0x4000 | DBG_VERBOSE0) #define DBG_VERBOSE2 (0x2000 | DBG_VERBOSE1) @@ -164,17 +169,72 @@ showVersion() exit(0); } +static void +unsetPreloadEnv() +{ + char *env = getenv("LD_PRELOAD"); + char *pos; + + // the const <-> non-const assignment is not an issue since the following + // modifying operations will not be executed in the const-case + env = env ? env : ""; + pos = strstr(env, LIBNAME); + + if (pos!=0) { + char *end_pos = pos + sizeof(LIBNAME); + bool is_end = (end_pos[-1]=='\0'); + char *start_pos; + + end_pos[-1] = '\0'; + start_pos = strrchr(env, ':'); + if (start_pos==0) start_pos = env; + else if (!is_end) ++start_pos; + + if (is_end) *start_pos = '\0'; + else memmove(start_pos, end_pos, strlen(end_pos)+1); + } + +#ifdef DEBUG + if (isDbgLevel(DBG_VERBOSE1|DBG_VARIABLES)) { + WRITE_MSG(2, "env='"); + WRITE_STR(2, env); + WRITE_MSG(2, "'\n"); + } +#endif + + if (*env=='\0') unsetenv("LD_PRELOAD"); +} + +static void +clearEnv() +{ + if (isDbgLevel(DBG_ENV)) WRITE_MSG(2, "clearEnv()\n"); + + unsetenv("RPM_FAKE_S_CONTEXT_REV"); + unsetenv("RPM_FAKE_S_CONTEXT_NR"); + unsetenv("RPM_FAKE_CTX"); + unsetenv("RPM_FAKE_FLAGS"); + unsetenv("RPM_FAKE_CHROOT"); + unsetenv("RPM_FAKE_NAMESPACE_MOUNTS"); + + unsetenv("RPM_FAKE_RESOLVER_GID"); + unsetenv("RPM_FAKE_RESOLVER_UID"); + unsetenv("RPM_FAKE_RESOLVER"); + unsetenv("RPM_FAKE_PWSOCKET"); + + unsetenv("RPM_FAKE_DEBUG"); + + unsetPreloadEnv(); +} + static int -getAndClearEnv(char const *key, int dflt) +getDefaultEnv(char const *key, int dflt) { char *env = getenv(key); int res; if (env==0 || env[0]=='\0') res = dflt; - else { - res = atoi(env); - unsetenv(key); - } + else res = atoi(env); return res; } @@ -253,7 +313,6 @@ initPwSocket() exit(255); } } - unsetenv("RPM_FAKE_PWSOCKET"); } #else static void @@ -293,6 +352,8 @@ initPwSocket() char const *xid_str; char flag_str[ sizeof(flags)*3 + 2]; char caps_str[ sizeof(caps)*3 + 2]; + + clearEnv(); setsid(); dup2(res_sock[1], 0); @@ -347,15 +408,35 @@ initPwSocket() exit(255); } } - - unsetenv("RPM_FAKE_RESOLVER_GID"); - unsetenv("RPM_FAKE_RESOLVER_UID"); - unsetenv("RPM_FAKE_RESOLVER"); } } #endif static void +reduceCapabilities() +{ + struct __user_cap_header_struct header; + struct __user_cap_data_struct user; + + header.version = _LINUX_CAPABILITY_VERSION; + header.pid = 0; + + if (capget(&header, &user)==-1) { + perror("capget()"); + exit(wrapper_exit_code); + } + + user.effective &= ~(1< non-const assignment is not an issue since the following - // modifying operations will not be executed in the const-case - env = env ? env : ""; - pos = strstr(env, LIBNAME); - - if (pos!=0) { - char *end_pos = pos + sizeof(LIBNAME); - bool is_end = (end_pos[-1]=='\0'); - char *start_pos; - - end_pos[-1] = '\0'; - start_pos = strrchr(env, ':'); - if (start_pos==0) start_pos = env; - else if (!is_end) ++start_pos; - - if (is_end) *start_pos = '\0'; - else memmove(start_pos, end_pos, strlen(end_pos)+1); - } - -#ifdef DEBUG - if (isDbgLevel(DBG_VERBOSE1|DBG_VARIABLES)) { - WRITE_MSG(2, "env='"); - WRITE_STR(2, env); - WRITE_MSG(2, "'\n"); - } -#endif - - if (*env=='\0') unsetenv("LD_PRELOAD"); -} - void initRPMFake() { if (getenv("RPM_FAKE_VERSION")) showVersion(); if (getenv("RPM_FAKE_HELP")) showHelp(); - debug_level = getAndClearEnv("RPM_FAKE_DEBUG", 0); + debug_level = getDefaultEnv("RPM_FAKE_DEBUG", 0); if (isDbgLevel(DBG_INIT)) WRITE_MSG(2, ">>>>> initRPMFake <<<<<\n"); - fixPreloadEnv(); + reduceCapabilities(); initSymbols(); initEnvironment(); initPwSocket(); @@ -550,12 +597,15 @@ execvWorker(char const *path, char * const argv[], char * const envp[]) if (vc_isSupported(vcFEATURE_MIGRATE)) res = vc_ctx_migrate(ctx); - else + else { #ifdef VC_ENABLE_API_COMPAT res = vc_new_s_context(ctx,caps,flags); #else WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "can not change context: migrate kernel feature missing and 'compat' API disabled\n"); #endif + } + + clearEnv(); if (res!=-1) res=execve(path, argv, envp); @@ -643,6 +693,12 @@ execv(char const *path, char * const argv[]) { extern char **environ; + if (isDbgLevel(DBG_EXECV)) { + WRITE_MSG(2, "execv('"); + WRITE_STR(2, path); + WRITE_MSG(2, "', ...)\n"); + } + return removeNamespaceMounts(path, argv, environ); } @@ -651,5 +707,11 @@ rpm_execcon(unsigned int UNUSED verified, const char *filename, char *const argv[], char *const envp[]) { + if (isDbgLevel(DBG_EXECV)) { + WRITE_MSG(2, "rpm_execcon(..., '"); + WRITE_STR(2, filename); + WRITE_MSG(2, "', ...)\n"); + } + return removeNamespaceMounts(filename, argv, envp); }