adb: add "adb unroot" to restart adb in non-root mode

Change-Id: Ice6b94a71a62648ac073d129914a07372411fb25
This commit is contained in:
Dan Pasanen 2014-10-06 12:57:20 -05:00 committed by Elliott Hughes
parent 1ac334ec66
commit 9885881d06
5 changed files with 70 additions and 37 deletions

View File

@ -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 */

View File

@ -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];

View File

@ -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;

View File

@ -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);

21
adb/tests/test_adb.py Normal file → Executable file
View File

@ -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"