mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-27 12:05:30 +00:00
Add mnt ns attach support for su
This commit is contained in:
parent
af5bdee78f
commit
4327682120
@ -31,6 +31,7 @@ int quit_signals[] = { SIGALRM, SIGABRT, SIGHUP, SIGPIPE, SIGQUIT, SIGTERM, SIGI
|
||||
"Options:\n"
|
||||
" -c, --command COMMAND pass COMMAND to the invoked shell\n"
|
||||
" -z, --context CONTEXT change SELinux context\n"
|
||||
" -t, --target PID PID to take mount namespace from\n"
|
||||
" -h, --help display this help message and exit\n"
|
||||
" -, -l, --login pretend the shell to be a login shell\n"
|
||||
" -m, -p,\n"
|
||||
@ -86,6 +87,7 @@ int su_client_main(int argc, char *argv[]) {
|
||||
{ "version", no_argument, nullptr, 'v' },
|
||||
{ "context", required_argument, nullptr, 'z' },
|
||||
{ "mount-master", no_argument, nullptr, 'M' },
|
||||
{ "target", required_argument, nullptr, 't' },
|
||||
{ nullptr, 0, nullptr, 0 },
|
||||
};
|
||||
|
||||
@ -99,7 +101,7 @@ int su_client_main(int argc, char *argv[]) {
|
||||
strcpy(argv[i], "-M");
|
||||
}
|
||||
|
||||
while ((c = getopt_long(argc, argv, "c:hlmps:Vvuz:M", long_opts, nullptr)) != -1) {
|
||||
while ((c = getopt_long(argc, argv, "c:hlmps:Vvuz:Mt:", long_opts, nullptr)) != -1) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
for (int i = optind - 1; i < argc; ++i) {
|
||||
@ -131,7 +133,20 @@ int su_client_main(int argc, char *argv[]) {
|
||||
su_req.context = optarg;
|
||||
break;
|
||||
case 'M':
|
||||
su_req.mount_master = true;
|
||||
case 't':
|
||||
if (su_req.target != -1) {
|
||||
fprintf(stderr, "Can't use -M and -t at the same time\n");
|
||||
usage(EXIT_FAILURE);
|
||||
}
|
||||
if (optarg == nullptr) {
|
||||
su_req.target = 0;
|
||||
} else {
|
||||
su_req.target = parse_int(optarg);
|
||||
if (*optarg == '-' || su_req.target == -1) {
|
||||
fprintf(stderr, "Invalid PID: %s\n", optarg);
|
||||
usage(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Bionic getopt_long doesn't terminate its error output by newline */
|
||||
|
@ -45,7 +45,7 @@ struct su_req_base {
|
||||
uid_t uid = AID_ROOT;
|
||||
bool login = false;
|
||||
bool keepenv = false;
|
||||
bool mount_master = false;
|
||||
pid_t target = -1;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct su_request : public su_req_base {
|
||||
|
@ -395,20 +395,24 @@ void su_daemon_handler(int client, const sock_cred *cred) {
|
||||
close(client);
|
||||
|
||||
// Handle namespaces
|
||||
if (ctx.req.mount_master)
|
||||
if (ctx.req.target == -1)
|
||||
ctx.req.target = ctx.pid;
|
||||
else if (ctx.req.target == 0)
|
||||
ctx.info->cfg[SU_MNT_NS] = NAMESPACE_MODE_GLOBAL;
|
||||
else if (ctx.info->cfg[SU_MNT_NS] == NAMESPACE_MODE_GLOBAL)
|
||||
ctx.info->cfg[SU_MNT_NS] = NAMESPACE_MODE_REQUESTER;
|
||||
switch (ctx.info->cfg[SU_MNT_NS]) {
|
||||
case NAMESPACE_MODE_GLOBAL:
|
||||
LOGD("su: use global namespace\n");
|
||||
break;
|
||||
case NAMESPACE_MODE_REQUESTER:
|
||||
LOGD("su: use namespace of pid=[%d]\n", ctx.pid);
|
||||
if (switch_mnt_ns(ctx.pid))
|
||||
LOGD("su: use namespace of pid=[%d]\n", ctx.req.target);
|
||||
if (switch_mnt_ns(ctx.req.target))
|
||||
LOGD("su: setns failed, fallback to global\n");
|
||||
break;
|
||||
case NAMESPACE_MODE_ISOLATE:
|
||||
LOGD("su: use new isolated namespace\n");
|
||||
switch_mnt_ns(ctx.pid);
|
||||
switch_mnt_ns(ctx.req.target);
|
||||
xunshare(CLONE_NEWNS);
|
||||
xmount(nullptr, "/", nullptr, MS_PRIVATE | MS_REC, nullptr);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user