Reimplement su -z

This commit is contained in:
LoveSy 2023-05-18 01:25:05 +08:00 committed by John Wu
parent 0e36e86dbf
commit af5bdee78f
3 changed files with 9 additions and 1 deletions

View File

@ -30,6 +30,7 @@ int quit_signals[] = { SIGALRM, SIGABRT, SIGHUP, SIGPIPE, SIGQUIT, SIGTERM, SIGI
"Usage: su [options] [-] [user[:group,...] [argument...]]\n\n" "Usage: su [options] [-] [user[:group,...] [argument...]]\n\n"
"Options:\n" "Options:\n"
" -c, --command COMMAND pass COMMAND to the invoked shell\n" " -c, --command COMMAND pass COMMAND to the invoked shell\n"
" -z, --context CONTEXT change SELinux context\n"
" -h, --help display this help message and exit\n" " -h, --help display this help message and exit\n"
" -, -l, --login pretend the shell to be a login shell\n" " -, -l, --login pretend the shell to be a login shell\n"
" -m, -p,\n" " -m, -p,\n"
@ -127,7 +128,7 @@ int su_client_main(int argc, char *argv[]) {
printf("%s\n", MAGISK_VERSION ":MAGISKSU"); printf("%s\n", MAGISK_VERSION ":MAGISKSU");
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
case 'z': case 'z':
// Do nothing, placed here for legacy support :) su_req.context = optarg;
break; break;
case 'M': case 'M':
su_req.mount_master = true; su_req.mount_master = true;
@ -170,6 +171,7 @@ int su_client_main(int argc, char *argv[]) {
xwrite(fd, &su_req, sizeof(su_req_base)); xwrite(fd, &su_req, sizeof(su_req_base));
write_string(fd, su_req.shell); write_string(fd, su_req.shell);
write_string(fd, su_req.command); write_string(fd, su_req.command);
write_string(fd, su_req.context);
write_vector(fd, su_req.gids); write_vector(fd, su_req.gids);
// Wait for ack from daemon // Wait for ack from daemon

View File

@ -51,6 +51,7 @@ struct su_req_base {
struct su_request : public su_req_base { struct su_request : public su_req_base {
std::string shell = DEFAULT_SHELL; std::string shell = DEFAULT_SHELL;
std::string command; std::string command;
std::string context;
std::vector<gid_t> gids; std::vector<gid_t> gids;
}; };

View File

@ -264,6 +264,7 @@ void su_daemon_handler(int client, const sock_cred *cred) {
if (xxread(client, &ctx.req, sizeof(su_req_base)) < 0 if (xxread(client, &ctx.req, sizeof(su_req_base)) < 0
|| !read_string(client, ctx.req.shell) || !read_string(client, ctx.req.shell)
|| !read_string(client, ctx.req.command) || !read_string(client, ctx.req.command)
|| !read_string(client, ctx.req.context)
|| !read_vector(client, ctx.req.gids)) { || !read_vector(client, ctx.req.gids)) {
LOGW("su: remote process probably died, abort\n"); LOGW("su: remote process probably died, abort\n");
ctx.info.reset(); ctx.info.reset();
@ -453,6 +454,10 @@ void su_daemon_handler(int client, const sock_cred *cred) {
sigset_t block_set; sigset_t block_set;
sigemptyset(&block_set); sigemptyset(&block_set);
sigprocmask(SIG_SETMASK, &block_set, nullptr); sigprocmask(SIG_SETMASK, &block_set, nullptr);
if (!ctx.req.context.empty() && selinux_enabled()) {
auto f = xopen_file("/proc/self/attr/exec", "we");
if (f) fprintf(f.get(), "%s", ctx.req.context.data());
}
set_identity(ctx.req.uid, ctx.req.gids); set_identity(ctx.req.uid, ctx.req.gids);
execvp(ctx.req.shell.data(), (char **) argv); execvp(ctx.req.shell.data(), (char **) argv);
fprintf(stderr, "Cannot execute %s: %s\n", ctx.req.shell.data(), strerror(errno)); fprintf(stderr, "Cannot execute %s: %s\n", ctx.req.shell.data(), strerror(errno));