diff options
author | Drew Richardson <drew.richardson@arm.com> | 2015-07-22 12:00:00 -0700 |
---|---|---|
committer | Drew Richardson <drew.richardson@arm.com> | 2015-07-24 07:41:39 -0700 |
commit | 7ca6004c0b05138c49b9b21e0045487f55a60ab6 (patch) | |
tree | 74cdc2c608e28891189b58e68992b3a8acf140e0 /daemon/Command.cpp | |
parent | c2fdcde9f26fff5eebbcc2ab34adb9d4202e0d55 (diff) |
Signed-off-by: Drew Richardson <drew.richardson@arm.com>
Diffstat (limited to 'daemon/Command.cpp')
-rw-r--r-- | daemon/Command.cpp | 69 |
1 files changed, 31 insertions, 38 deletions
diff --git a/daemon/Command.cpp b/daemon/Command.cpp index 0a6e3b9..22f8be7 100644 --- a/daemon/Command.cpp +++ b/daemon/Command.cpp @@ -9,6 +9,7 @@ #include "Command.h" #include <fcntl.h> +#include <grp.h> #include <pwd.h> #include <stdio.h> #include <sys/prctl.h> @@ -23,14 +24,14 @@ #include "Logging.h" #include "SessionData.h" -static int getUid(const char *const name, char *const shPath, const char *const tmpDir) { +static int getUid(const char *const name, const char *const tmpDir, uid_t *const uid) { // Lookups may fail when using a different libc or a statically compiled executable char gatorTemp[32]; snprintf(gatorTemp, sizeof(gatorTemp), "%s/gator_temp", tmpDir); const int fd = open(gatorTemp, 600, O_CREAT | O_CLOEXEC); if (fd < 0) { - return -1; + return false; } close(fd); @@ -43,15 +44,7 @@ static int getUid(const char *const name, char *const shPath, const char *const handleException(); } if (pid == 0) { - char cargv1[] = "-c"; - char *cargv[] = { - shPath, - cargv1, - cmd, - NULL, - }; - - execv(cargv[0], cargv); + execlp("sh", "sh", "-c", cmd, NULL); exit(-1); } while ((waitpid(pid, NULL, 0) < 0) && (errno == EINTR)); @@ -62,38 +55,42 @@ static int getUid(const char *const name, char *const shPath, const char *const result = st.st_uid; } unlink(gatorTemp); - return result; + *uid = result; + return true; } -static int getUid(const char *const name) { +static bool getUid(const char *const name, uid_t *const uid, gid_t *const gid) { // Look up the username struct passwd *const user = getpwnam(name); if (user != NULL) { - return user->pw_uid; + *uid = user->pw_uid; + *gid = user->pw_gid; + return true; } + // Unable to get the user without getpwanm, so create a unique uid by adding a fixed number to the pid + *gid = 0x484560f8 + getpid(); // Are we on Linux - char cargv0l[] = "/bin/sh"; - if ((access(cargv0l, X_OK) == 0) && (access("/tmp", W_OK) == 0)) { - return getUid(name, cargv0l, "/tmp"); + if (access("/tmp", W_OK) == 0) { + return getUid(name, "/tmp", uid); } // Are we on android - char cargv0a[] = "/system/bin/sh"; - if ((access(cargv0a, X_OK) == 0) && (access("/data", W_OK) == 0)) { - return getUid(name, cargv0a, "/data"); + if (access("/data", W_OK) == 0) { + return getUid(name, "/data", uid); } - return -1; + return false; } void *commandThread(void *) { prctl(PR_SET_NAME, (unsigned long)&"gatord-command", 0, 0, 0); const char *const name = gSessionData->mCaptureUser == NULL ? "nobody" : gSessionData->mCaptureUser; - const int uid = getUid(name); - if (uid < 0) { + uid_t uid; + gid_t gid; + if (!getUid(name, &uid, &gid)) { logg->logError("Unable to look up the user %s, please double check that the user exists", name); handleException(); } @@ -113,16 +110,6 @@ void *commandThread(void *) { handleException(); } if (pid == 0) { - char cargv0l[] = "/bin/sh"; - char cargv0a[] = "/system/bin/sh"; - char cargv1[] = "-c"; - char *cargv[] = { - cargv0l, - cargv1, - gSessionData->mCaptureCommand, - NULL, - }; - buf[0] = '\0'; close(pipefd[0]); @@ -132,8 +119,16 @@ void *commandThread(void *) { goto fail_exit; } - if (setuid(uid) != 0) { - snprintf(buf, sizeof(buf), "setuid failed"); + if (setgroups(1, &gid) != 0) { + snprintf(buf, sizeof(buf), "setgroups failed"); + goto fail_exit; + } + if (setresgid(gid, gid, gid) != 0) { + snprintf(buf, sizeof(buf), "setresgid failed"); + goto fail_exit; + } + if (setresuid(uid, uid, uid) != 0) { + snprintf(buf, sizeof(buf), "setresuid failed"); goto fail_exit; } @@ -145,9 +140,7 @@ void *commandThread(void *) { } } - execv(cargv[0], cargv); - cargv[0] = cargv0a; - execv(cargv[0], cargv); + execlp("sh", "sh", "-c", gSessionData->mCaptureCommand, NULL); snprintf(buf, sizeof(buf), "execv failed"); fail_exit: |