aboutsummaryrefslogtreecommitdiff
path: root/daemon/Command.cpp
diff options
context:
space:
mode:
authorDrew Richardson <drew.richardson@arm.com>2015-07-22 12:00:00 -0700
committerDrew Richardson <drew.richardson@arm.com>2015-07-24 07:41:39 -0700
commit7ca6004c0b05138c49b9b21e0045487f55a60ab6 (patch)
tree74cdc2c608e28891189b58e68992b3a8acf140e0 /daemon/Command.cpp
parentc2fdcde9f26fff5eebbcc2ab34adb9d4202e0d55 (diff)
gator: Version 5.22HEAD5.22master
Signed-off-by: Drew Richardson <drew.richardson@arm.com>
Diffstat (limited to 'daemon/Command.cpp')
-rw-r--r--daemon/Command.cpp69
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: