Minor code refactoring

This commit is contained in:
topjohnwu
2021-01-12 00:07:48 -08:00
parent 79dfdb29e7
commit d2acd59ea8
12 changed files with 100 additions and 135 deletions

View File

@@ -30,7 +30,7 @@ enum {
? info->uid / 100000 : 0)
#define get_cmd(to) \
(to.command[0] ? to.command : to.shell[0] ? to.shell : DEFAULT_SHELL)
(to.command.empty() ? (to.shell.empty() ? DEFAULT_SHELL : to.shell.data()) : to.command.data())
class Extra {
const char *key;
@@ -42,7 +42,7 @@ class Extra {
union {
int int_val;
bool bool_val;
const char * str_val;
const char *str_val;
};
char buf[32];
public:

View File

@@ -43,18 +43,6 @@ static void usage(int status) {
exit(status);
}
static char *concat_commands(int argc, char *argv[]) {
char command[ARG_MAX];
command[0] = '\0';
for (int i = optind - 1; i < argc; ++i) {
if (command[0])
sprintf(command, "%s %s", command, argv[i]);
else
strcpy(command, argv[i]);
}
return strdup(command);
}
static void sighandler(int sig) {
restore_stdin();
@@ -114,7 +102,13 @@ int su_client_main(int argc, char *argv[]) {
while ((c = getopt_long(argc, argv, "c:hlmps:Vvuz:M", long_opts, nullptr)) != -1) {
switch (c) {
case 'c':
su_req.command = concat_commands(argc, argv);
for (int i = optind - 1; i < argc; ++i) {
if (!su_req.command.empty())
su_req.command += ' ';
su_req.command += '\'';
su_req.command += argv[i];
su_req.command += '\'';
}
optind = argc;
break;
case 'h':

View File

@@ -45,19 +45,9 @@ struct su_req_base {
} __attribute__((packed));
struct su_request : public su_req_base {
const char *shell = DEFAULT_SHELL;
const char *command = "";
su_request(bool dyn = false) : dyn(dyn) {}
~su_request() {
if (dyn) {
free(const_cast<char*>(shell));
free(const_cast<char*>(command));
}
}
private:
bool dyn;
} __attribute__((packed));
std::string shell = DEFAULT_SHELL;
std::string command;
};
struct su_context {
std::shared_ptr<su_info> info;

View File

@@ -163,14 +163,14 @@ void su_daemon_handler(int client, struct ucred *credential) {
su_context ctx = {
.info = get_su_info(credential->uid),
.req = su_request(true),
.req = su_request(),
.pid = credential->pid
};
// Read su_request
xxread(client, &ctx.req, sizeof(su_req_base));
ctx.req.shell = read_string(client);
ctx.req.command = read_string(client);
read_string(client, ctx.req.shell);
read_string(client, ctx.req.command);
if (ctx.info->access.log)
app_log(ctx);
@@ -223,18 +223,18 @@ void su_daemon_handler(int client, struct ucred *credential) {
xsetsid();
// Get pts_slave
char *pts_slave = read_string(client);
string pts_slave = read_string(client);
// The FDs for each of the streams
int infd = recv_fd(client);
int outfd = recv_fd(client);
int errfd = recv_fd(client);
if (pts_slave[0]) {
LOGD("su: pts_slave=[%s]\n", pts_slave);
if (!pts_slave.empty()) {
LOGD("su: pts_slave=[%s]\n", pts_slave.data());
// Check pts_slave file is owned by daemon_from_uid
struct stat st;
xstat(pts_slave, &st);
xstat(pts_slave.data(), &st);
// If caller is not root, ensure the owner of pts_slave is the caller
if(st.st_uid != ctx.info->uid && ctx.info->uid != 0)
@@ -243,7 +243,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
// Opening the TTY has to occur after the
// fork() and setsid() so that it becomes
// our controlling TTY and not the daemon's
int ptsfd = xopen(pts_slave, O_RDWR);
int ptsfd = xopen(pts_slave.data(), O_RDWR);
if (infd < 0)
infd = ptsfd;
@@ -253,8 +253,6 @@ void su_daemon_handler(int client, struct ucred *credential) {
errfd = ptsfd;
}
free(pts_slave);
// Swap out stdin, stdout, stderr
xdup2(infd, STDIN_FILENO);
xdup2(outfd, STDOUT_FILENO);
@@ -290,13 +288,13 @@ void su_daemon_handler(int client, struct ucred *credential) {
break;
}
const char *argv[] = { nullptr, nullptr, nullptr, nullptr };
const char *argv[4] = { nullptr };
argv[0] = ctx.req.login ? "-" : ctx.req.shell;
argv[0] = ctx.req.login ? "-" : ctx.req.shell.data();
if (ctx.req.command[0]) {
if (!ctx.req.command.empty()) {
argv[1] = "-c";
argv[2] = ctx.req.command;
argv[2] = ctx.req.command.data();
}
// Setup environment
@@ -321,7 +319,7 @@ void su_daemon_handler(int client, struct ucred *credential) {
setenv("HOME", pw->pw_dir, 1);
setenv("USER", pw->pw_name, 1);
setenv("LOGNAME", pw->pw_name, 1);
setenv("SHELL", ctx.req.shell, 1);
setenv("SHELL", ctx.req.shell.data(), 1);
}
}
@@ -330,8 +328,8 @@ void su_daemon_handler(int client, struct ucred *credential) {
sigemptyset(&block_set);
sigprocmask(SIG_SETMASK, &block_set, nullptr);
set_identity(ctx.req.uid);
execvp(ctx.req.shell, (char **) argv);
fprintf(stderr, "Cannot execute %s: %s\n", ctx.req.shell, strerror(errno));
execvp(ctx.req.shell.data(), (char **) argv);
fprintf(stderr, "Cannot execute %s: %s\n", ctx.req.shell.data(), strerror(errno));
PLOGE("exec");
exit(EXIT_FAILURE);
}