adb: add "adb unroot" to restart adb in non-root mode
Change-Id: Ice6b94a71a62648ac073d129914a07372411fb25
This commit is contained in:
parent
1ac334ec66
commit
9885881d06
51
adb/adb.c
51
adb/adb.c
|
@ -1261,35 +1261,36 @@ static void drop_capabilities_bounding_set_if_needed() {
|
|||
}
|
||||
}
|
||||
|
||||
static int should_drop_privileges() {
|
||||
#ifndef ALLOW_ADBD_ROOT
|
||||
return 1;
|
||||
#else /* ALLOW_ADBD_ROOT */
|
||||
int secure = 0;
|
||||
static bool should_drop_privileges() {
|
||||
#if defined(ALLOW_ADBD_ROOT)
|
||||
char value[PROPERTY_VALUE_MAX];
|
||||
|
||||
/* run adbd in secure mode if ro.secure is set and
|
||||
** we are not in the emulator
|
||||
*/
|
||||
// The emulator is never secure, so don't drop privileges there.
|
||||
// TODO: this seems like a bug --- shouldn't the emulator behave like a device?
|
||||
property_get("ro.kernel.qemu", value, "");
|
||||
if (strcmp(value, "1") != 0) {
|
||||
property_get("ro.secure", value, "1");
|
||||
if (strcmp(value, "1") == 0) {
|
||||
// don't run as root if ro.secure is set...
|
||||
secure = 1;
|
||||
|
||||
// ... except we allow running as root in userdebug builds if the
|
||||
// service.adb.root property has been set by the "adb root" command
|
||||
property_get("ro.debuggable", value, "");
|
||||
if (strcmp(value, "1") == 0) {
|
||||
property_get("service.adb.root", value, "");
|
||||
if (strcmp(value, "1") == 0) {
|
||||
secure = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strcmp(value, "1") == 0) {
|
||||
return false;
|
||||
}
|
||||
return secure;
|
||||
|
||||
// Don't run as root if ro.secure is set...
|
||||
property_get("ro.secure", value, "1");
|
||||
bool ro_secure = (strcmp(value, "1") == 0);
|
||||
|
||||
// ... except we allow running as root in userdebug builds if the
|
||||
// service.adb.root property has been set by the "adb root" command
|
||||
property_get("ro.debuggable", value, "");
|
||||
bool ro_debuggable = (strcmp(value, "1") == 0);
|
||||
|
||||
property_get("service.adb.root", value, "");
|
||||
bool adb_root = (strcmp(value, "1") == 0);
|
||||
bool adb_unroot = (strcmp(value, "0") == 0);
|
||||
if (adb_unroot) {
|
||||
return true; // The user explicitly wants us to drop privileges.
|
||||
}
|
||||
|
||||
return ro_secure || !ro_debuggable;
|
||||
#else
|
||||
return true; // "adb root" not allowed, always drop privileges.
|
||||
#endif /* ALLOW_ADBD_ROOT */
|
||||
}
|
||||
#endif /* !ADB_HOST */
|
||||
|
|
|
@ -210,6 +210,7 @@ void help()
|
|||
" adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
|
||||
" adb reboot-bootloader - reboots the device into the bootloader\n"
|
||||
" adb root - restarts the adbd daemon with root permissions\n"
|
||||
" adb unroot - restarts the adbd daemon without root permissions\n"
|
||||
" adb usb - restarts the adbd daemon listening on USB\n"
|
||||
" adb tcpip <port> - restarts the adbd daemon listening on TCP on the specified port\n"
|
||||
"networking:\n"
|
||||
|
@ -1473,6 +1474,7 @@ int adb_commandline(int argc, char **argv)
|
|||
!strcmp(argv[0], "tcpip") ||
|
||||
!strcmp(argv[0], "usb") ||
|
||||
!strcmp(argv[0], "root") ||
|
||||
!strcmp(argv[0], "unroot") ||
|
||||
!strcmp(argv[0], "disable-verity") ||
|
||||
!strcmp(argv[0], "enable-verity")) {
|
||||
char command[100];
|
||||
|
|
|
@ -82,6 +82,22 @@ void restart_root_service(int fd, void *cookie)
|
|||
}
|
||||
}
|
||||
|
||||
void restart_unroot_service(int fd, void *cookie)
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
if (getuid() != 0) {
|
||||
snprintf(buf, sizeof(buf), "adbd not running as root\n");
|
||||
writex(fd, buf, strlen(buf));
|
||||
adb_close(fd);
|
||||
} else {
|
||||
property_set("service.adb.root", "0");
|
||||
snprintf(buf, sizeof(buf), "restarting adbd as non root\n");
|
||||
writex(fd, buf, strlen(buf));
|
||||
adb_close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
void restart_tcp_service(int fd, void *cookie)
|
||||
{
|
||||
char buf[100];
|
||||
|
@ -437,6 +453,8 @@ int service_to_fd(const char *name)
|
|||
ret = create_service_thread(reboot_service, arg);
|
||||
} else if(!strncmp(name, "root:", 5)) {
|
||||
ret = create_service_thread(restart_root_service, NULL);
|
||||
} else if(!strncmp(name, "unroot:", 7)) {
|
||||
ret = create_service_thread(restart_unroot_service, NULL);
|
||||
} else if(!strncmp(name, "backup:", 7)) {
|
||||
char* arg = strdup(name + 7);
|
||||
if (arg == NULL) return -1;
|
||||
|
|
|
@ -430,12 +430,6 @@ asocket *create_local_socket(int fd)
|
|||
|
||||
asocket *create_local_service_socket(const char *name)
|
||||
{
|
||||
asocket *s;
|
||||
int fd;
|
||||
#if !ADB_HOST
|
||||
char debug[PROPERTY_VALUE_MAX];
|
||||
#endif
|
||||
|
||||
#if !ADB_HOST
|
||||
if (!strcmp(name,"jdwp")) {
|
||||
return create_jdwp_service_socket();
|
||||
|
@ -444,18 +438,19 @@ asocket *create_local_service_socket(const char *name)
|
|||
return create_jdwp_tracker_service_socket();
|
||||
}
|
||||
#endif
|
||||
fd = service_to_fd(name);
|
||||
int fd = service_to_fd(name);
|
||||
if(fd < 0) return 0;
|
||||
|
||||
s = create_local_socket(fd);
|
||||
asocket* s = create_local_socket(fd);
|
||||
D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);
|
||||
|
||||
#if !ADB_HOST
|
||||
char debug[PROPERTY_VALUE_MAX];
|
||||
if (!strncmp(name, "root:", 5))
|
||||
property_get("ro.debuggable", debug, "");
|
||||
|
||||
if ((!strncmp(name, "root:", 5) && getuid() != 0
|
||||
&& strcmp(debug, "1") == 0)
|
||||
if ((!strncmp(name, "root:", 5) && getuid() != 0 && strcmp(debug, "1") == 0)
|
||||
|| (!strncmp(name, "unroot:", 7) && getuid() == 0)
|
||||
|| !strncmp(name, "usb:", 4)
|
||||
|| !strncmp(name, "tcpip:", 6)) {
|
||||
D("LS(%d): enabling exit_on_close\n", s->id);
|
||||
|
|
|
@ -8,11 +8,11 @@ import hashlib
|
|||
import os
|
||||
import random
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
import sys
|
||||
import shlex
|
||||
|
||||
|
||||
def trace(cmd):
|
||||
|
@ -181,6 +181,12 @@ class AdbWrapper(object):
|
|||
def usb(self):
|
||||
return call_checked(self.adb_cmd + "usb")
|
||||
|
||||
def root(self):
|
||||
return call_checked(self.adb_cmd + "root")
|
||||
|
||||
def unroot(self):
|
||||
return call_checked(self.adb_cmd + "unroot")
|
||||
|
||||
def forward_remove(self, local):
|
||||
return call_checked(self.adb_cmd + "forward --remove {}".format(local))
|
||||
|
||||
|
@ -233,6 +239,17 @@ class AdbBasic(unittest.TestCase):
|
|||
version_num = True
|
||||
self.assertTrue(version_num)
|
||||
|
||||
def test_root_unroot(self):
|
||||
"""Make sure that adb root and adb unroot work, using id(1)."""
|
||||
for device in get_device_list():
|
||||
adb = AdbWrapper(device)
|
||||
adb.root()
|
||||
adb.wait()
|
||||
self.assertEqual("root", adb.shell("id -un").strip())
|
||||
adb.unroot()
|
||||
adb.wait()
|
||||
self.assertEqual("shell", adb.shell("id -un").strip())
|
||||
|
||||
|
||||
class AdbFile(unittest.TestCase):
|
||||
SCRATCH_DIR = "/data/local/tmp"
|
||||
|
|
Loading…
Reference in New Issue