From 22e59566403f3da5524919324b763df724b53ebb Mon Sep 17 00:00:00 2001 From: Sooyoung Ha Date: Sat, 25 Mar 2017 00:46:21 +0900 Subject: [PATCH] service: change method of create_process function On some case, System privileged shell is needed(ex: appcmd). I provide functions for creating System privileged process as create_subprocess() and create_userprocess() for User::Shell privileged. And I also clarify the equivocal definition name. Change-Id: Iac129b81e2534ec2a54dc29969098ca8014f582c Signed-off-by: Sooyoung Ha --- src/services.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 8 deletions(-) diff --git a/src/services.c b/src/services.c index f6c1df6..1daaa43 100644 --- a/src/services.c +++ b/src/services.c @@ -371,6 +371,100 @@ static int create_service_thread(void (*func)(int, void *), void *cookie) } #if !SDB_HOST + +static void redirect_and_exec(int pts, const char *cmd, char * const argv[], char * const envp[]) +{ + dup2(pts, 0); + dup2(pts, 1); + dup2(pts, 2); + + sdb_close(pts); + + execve(cmd, argv, envp); +} + +int create_subprocess(const char *cmd, pid_t *pid, char * const argv[], char * const envp[]) +{ + char devname[64]; + int ptm; + + ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY); + if(ptm < 0){ + D("[ cannot open /dev/ptmx - errno:%d ]\n",errno); + return -1; + } + if (fcntl(ptm, F_SETFD, FD_CLOEXEC) < 0) { + D("[ cannot set cloexec to /dev/ptmx - errno:%d ]\n",errno); + } + + if(grantpt(ptm) || unlockpt(ptm) || + ptsname_r(ptm, devname, sizeof(devname)) != 0 ){ + D("[ trouble with /dev/ptmx - errno:%d ]\n", errno); + sdb_close(ptm); + return -1; + } + + *pid = fork(); + if(*pid < 0) { + D("- fork failed: errno:%d -\n", errno); + sdb_close(ptm); + return -1; + } + + if(*pid == 0){ + int pts; + + setsid(); + + pts = unix_open(devname, O_RDWR); + if(pts < 0) { + fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); + exit(-1); + } + + sdb_close(ptm); + + // set OOM adjustment to zero + { + char text[64]; + //snprintf(text, sizeof text, "/proc/%d/oom_score_adj", getpid()); + snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid()); + int fd = sdb_open(text, O_WRONLY); + if (fd >= 0) { + sdb_write(fd, "0", 1); + sdb_close(fd); + } else { + // FIXME: not supposed to be here + D("sdb: unable to open %s due to errno:%d\n", text, errno); + } + } + + if (should_drop_privileges()) { + if (argv[2] != NULL && request_validity_to_plugin(PLUGIN_SYNC_CMD_VERIFY_ROOTCMD, argv[2])) { + // do nothing + D("sdb: executes root commands!!:%s\n", argv[2]); + } else { + if (getuid() != g_sdk_user_id && set_sdk_user_privileges(RESERVE_CAPABILITIES_AFTER_FORK) < 0) { + fprintf(stderr, "failed to set SDK user privileges\n"); + exit(-1); + } + } + } else { + set_root_privileges(); + } + redirect_and_exec(pts, cmd, argv, envp); + fprintf(stderr, "- exec '%s' failed: (errno:%d) -\n", + cmd, errno); + exit(-1); + } else { + // Don't set child's OOM adjustment to zero. + // Let the child do it itself, as sometimes the parent starts + // running before the child has a /proc/pid/oom_adj. + // """sdb: unable to open /proc/644/oom_adj""" seen in some logs. + return ptm; + } +} + /* receive the ptm from child, sdbd-user */ static ssize_t recv_fd(int fd, void *ptr, size_t nbytes, int *recvfd) { @@ -416,7 +510,7 @@ static ssize_t recv_fd(int fd, void *ptr, size_t nbytes, int *recvfd) return ret; } -int create_subprocess(const char *cmd, pid_t *pid, char * const argv[], char * const envp[]) +int create_userprocess(const char *cmd, pid_t *pid, char * const argv[], char * const envp[]) { *pid = fork(); if(*pid < 0) { @@ -512,7 +606,7 @@ int create_subprocess(const char *cmd, pid_t *pid, char * const argv[], char * c } #endif /* !SDB_HOST */ -#define SHELL_COMMAND "/usr/sbin/sdbd-user" +#define USER_DAEMON_COMMAND "/usr/sbin/sdbd-user" #define LOGIN_COMMAND "/bin/login" #define SUPER_USER "root" #define LOGIN_CONFIG "/etc/login.defs" @@ -688,14 +782,14 @@ static int create_subproc_thread(const char *name, int lines, int columns) D("converted cmd : %s\n", new_cmd); char *args[] = { - SHELL_COMMAND, + USER_DAEMON_COMMAND, "-c", NULL, NULL, }; args[2] = new_cmd; - ret_fd = create_subprocess(SHELL_COMMAND, &pid, (char * const*)args, (char * const*)envp); + ret_fd = create_userprocess(USER_DAEMON_COMMAND, &pid, (char * const*)args, (char * const*)envp); free(new_cmd); } else { // in case of shell interactively // Check the capability for interactive shell support. @@ -705,19 +799,19 @@ static int create_subproc_thread(const char *name, int lines, int columns) } char * const args[] = { - SHELL_COMMAND, + USER_DAEMON_COMMAND, "-", NULL, }; - ret_fd = create_subprocess(SHELL_COMMAND, &pid, (char * const*)args, (char * const*)envp); + ret_fd = create_userprocess(USER_DAEMON_COMMAND, &pid, (char * const*)args, (char * const*)envp); #if 0 // FIXME: should call login command instead of /bin/sh if (should_drop_privileges()) { char *args[] = { - SHELL_COMMAND, + USER_DAEMON_COMMAND, "-", NULL, }; - ret_fd = create_subprocess(SHELL_COMMAND, &pid, args, envp); + ret_fd = create_userprocess(USER_DAEMON_COMMAND, &pid, args, envp); } else { char *args[] = { LOGIN_COMMAND, -- 2.7.4