summaryrefslogtreecommitdiffstats
path: root/adb
diff options
context:
space:
mode:
Diffstat (limited to 'adb')
-rw-r--r--adb/Android.mk1
-rw-r--r--adb/adb.c64
-rw-r--r--adb/adb.h1
-rw-r--r--adb/adb_auth.h4
-rw-r--r--adb/adb_auth_client.c55
-rw-r--r--adb/commandline.c5
-rw-r--r--adb/transport.c7
7 files changed, 117 insertions, 20 deletions
diff --git a/adb/Android.mk b/adb/Android.mk
index 6cd82ec..a803978 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -17,6 +17,7 @@ ifeq ($(HOST_OS),linux)
USB_SRCS := usb_linux.c
EXTRA_SRCS := get_my_path_linux.c
LOCAL_LDLIBS += -lrt -ldl -lpthread
+ LOCAL_CFLAGS += -DWORKAROUND_BUG6558362
endif
ifeq ($(HOST_OS),darwin)
diff --git a/adb/adb.c b/adb/adb.c
index cd7f16c..ec74b49 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -326,7 +326,7 @@ static void send_connect(atransport *t)
send_packet(cp, t);
}
-static void send_auth_request(atransport *t)
+void send_auth_request(atransport *t)
{
D("Calling send_auth_request\n");
apacket *p;
@@ -407,6 +407,8 @@ static char *connection_state_name(atransport *t)
return "sideload";
case CS_OFFLINE:
return "offline";
+ case CS_UNAUTHORIZED:
+ return "unauthorized";
default:
return "unknown";
}
@@ -536,6 +538,7 @@ void handle_packet(apacket *p, atransport *t)
case A_AUTH:
if (p->msg.arg0 == ADB_AUTH_TOKEN) {
+ t->connection_state = CS_UNAUTHORIZED;
t->key = adb_auth_nextkey(t->key);
if (t->key) {
send_auth_response(p->data, p->msg.data_length, t);
@@ -988,6 +991,33 @@ void start_device_log(void)
#endif
#if ADB_HOST
+
+#ifdef WORKAROUND_BUG6558362
+#include <sched.h>
+#define AFFINITY_ENVVAR "ADB_CPU_AFFINITY_BUG6558362"
+void adb_set_affinity(void)
+{
+ cpu_set_t cpu_set;
+ const char* cpunum_str = getenv(AFFINITY_ENVVAR);
+ char* strtol_res;
+ int cpu_num;
+
+ if (!cpunum_str || !*cpunum_str)
+ return;
+ cpu_num = strtol(cpunum_str, &strtol_res, 0);
+ if (*strtol_res != '\0')
+ fatal("bad number (%s) in env var %s. Expecting 0..n.\n", cpunum_str, AFFINITY_ENVVAR);
+
+ sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
+ D("orig cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
+ CPU_ZERO(&cpu_set);
+ CPU_SET(cpu_num, &cpu_set);
+ sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
+ sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
+ D("new cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
+}
+#endif
+
int launch_server(int server_port)
{
#ifdef HAVE_WIN32_PROC
@@ -1158,6 +1188,32 @@ void build_local_name(char* target_str, size_t target_size, int server_port)
}
#if !ADB_HOST
+
+static void drop_capabilities_bounding_set_if_needed() {
+#ifdef ALLOW_ADBD_ROOT
+ char value[PROPERTY_VALUE_MAX];
+ property_get("ro.debuggable", value, "");
+ if (strcmp(value, "1") == 0) {
+ return;
+ }
+#endif
+ int i;
+ for (i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
+ if ((i == CAP_SETUID) || (i == CAP_SETGID)) {
+ // CAP_SETUID CAP_SETGID needed by /system/bin/run-as
+ continue;
+ }
+ int err = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
+
+ // Some kernels don't have file capabilities compiled in, and
+ // prctl(PR_CAPBSET_DROP) returns EINVAL. Don't automatically
+ // die when we see such misconfigured kernels.
+ if ((err < 0) && (errno != EINVAL)) {
+ exit(1);
+ }
+ }
+}
+
static int should_drop_privileges() {
#ifndef ALLOW_ADBD_ROOT
return 1;
@@ -1212,6 +1268,10 @@ int adb_main(int is_daemon, int server_port)
#if ADB_HOST
HOST = 1;
+
+#ifdef WORKAROUND_BUG6558362
+ if(is_daemon) adb_set_affinity();
+#endif
usb_vendors_init();
usb_init();
local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
@@ -1248,6 +1308,8 @@ int adb_main(int is_daemon, int server_port)
exit(1);
}
+ drop_capabilities_bounding_set_if_needed();
+
/* add extra groups:
** AID_ADB to access the USB driver
** AID_LOG to read system logs (adb logcat)
diff --git a/adb/adb.h b/adb/adb.h
index 9da8af8..a01d460 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -468,6 +468,7 @@ int connection_state(atransport *t);
#define CS_RECOVERY 4
#define CS_NOPERM 5 /* Insufficient permissions to communicate with the device */
#define CS_SIDELOAD 6
+#define CS_UNAUTHORIZED 7
extern int HOST;
extern int SHELL_EXIT_NOTIFY_FD;
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index 1fffa49..b24c674 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -20,6 +20,8 @@
void adb_auth_init(void);
void adb_auth_verified(atransport *t);
+void send_auth_request(atransport *t);
+
/* AUTH packets first argument */
/* Request */
#define ADB_AUTH_TOKEN 1
@@ -36,7 +38,6 @@ int adb_auth_get_userkey(unsigned char *data, size_t len);
static inline int adb_auth_generate_token(void *token, size_t token_size) { return 0; }
static inline int adb_auth_verify(void *token, void *sig, int siglen) { return 0; }
static inline void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t) { }
-static inline void adb_auth_reload_keys(void) { }
#else // !ADB_HOST
@@ -47,7 +48,6 @@ static inline int adb_auth_get_userkey(unsigned char *data, size_t len) { return
int adb_auth_generate_token(void *token, size_t token_size);
int adb_auth_verify(void *token, void *sig, int siglen);
void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t);
-void adb_auth_reload_keys(void);
#endif // ADB_HOST
diff --git a/adb/adb_auth_client.c b/adb/adb_auth_client.c
index 0b4913e..763b448 100644
--- a/adb/adb_auth_client.c
+++ b/adb/adb_auth_client.c
@@ -34,8 +34,6 @@ struct adb_public_key {
RSAPublicKey key;
};
-static struct listnode key_list;
-
static char *key_paths[] = {
"/adb_keys",
"/data/misc/adb/adb_keys",
@@ -45,6 +43,10 @@ static char *key_paths[] = {
static fdevent listener_fde;
static int framework_fd = -1;
+static void usb_disconnected(void* unused, atransport* t);
+static struct adisconnect usb_disconnect = { usb_disconnected, 0, 0, 0 };
+static atransport* usb_transport;
+static bool needs_retry = false;
static void read_keys(const char *file, struct listnode *list)
{
@@ -102,18 +104,18 @@ static void free_keys(struct listnode *list)
}
}
-void adb_auth_reload_keys(void)
+static void load_keys(struct listnode *list)
{
char *path;
char **paths = key_paths;
struct stat buf;
- free_keys(&key_list);
+ list_init(list);
while ((path = *paths++)) {
if (!stat(path, &buf)) {
D("Loading keys from '%s'\n", path);
- read_keys(path, &key_list);
+ read_keys(path, list);
}
}
}
@@ -137,37 +139,50 @@ int adb_auth_verify(void *token, void *sig, int siglen)
{
struct listnode *item;
struct adb_public_key *key;
- int ret;
+ struct listnode key_list;
+ int ret = 0;
if (siglen != RSANUMBYTES)
return 0;
+ load_keys(&key_list);
+
list_for_each(item, &key_list) {
key = node_to_item(item, struct adb_public_key, node);
ret = RSA_verify(&key->key, sig, siglen, token);
if (ret)
- return 1;
+ break;
}
- return 0;
+ free_keys(&key_list);
+
+ return ret;
+}
+
+static void usb_disconnected(void* unused, atransport* t)
+{
+ D("USB disconnect\n");
+ remove_transport_disconnect(usb_transport, &usb_disconnect);
+ usb_transport = NULL;
+ needs_retry = false;
}
static void adb_auth_event(int fd, unsigned events, void *data)
{
- atransport *t = data;
char response[2];
int ret;
if (events & FDE_READ) {
ret = unix_read(fd, response, sizeof(response));
if (ret < 0) {
- D("Disconnect");
- fdevent_remove(&t->auth_fde);
+ D("Framework disconnect\n");
+ if (usb_transport)
+ fdevent_remove(&usb_transport->auth_fde);
framework_fd = -1;
}
else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
- adb_auth_reload_keys();
- adb_auth_verified(t);
+ if (usb_transport)
+ adb_auth_verified(usb_transport);
}
}
}
@@ -177,8 +192,14 @@ void adb_auth_confirm_key(unsigned char *key, size_t len, atransport *t)
char msg[MAX_PAYLOAD];
int ret;
+ if (!usb_transport) {
+ usb_transport = t;
+ add_transport_disconnect(t, &usb_disconnect);
+ }
+
if (framework_fd < 0) {
D("Client not connected\n");
+ needs_retry = true;
return;
}
@@ -219,15 +240,17 @@ static void adb_auth_listener(int fd, unsigned events, void *data)
}
framework_fd = s;
+
+ if (needs_retry) {
+ needs_retry = false;
+ send_auth_request(usb_transport);
+ }
}
void adb_auth_init(void)
{
int fd, ret;
- list_init(&key_list);
- adb_auth_reload_keys();
-
fd = android_get_control_socket("adbd");
if (fd < 0) {
D("Failed to get adbd socket\n");
diff --git a/adb/commandline.c b/adb/commandline.c
index a927423..27a1754 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -144,12 +144,15 @@ void help()
" adb bugreport - return all information from the device\n"
" that should be included in a bug report.\n"
"\n"
- " adb backup [-f <file>] [-apk|-noapk] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
+ " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
" - write an archive of the device's data to <file>.\n"
" If no -f option is supplied then the data is written\n"
" to \"backup.ab\" in the current directory.\n"
" (-apk|-noapk enable/disable backup of the .apks themselves\n"
" in the archive; the default is noapk.)\n"
+ " (-obb|-noobb enable/disable backup of any installed apk expansion\n"
+ " (aka .obb) files associated with each application; the default\n"
+ " is noobb.)\n"
" (-shared|-noshared enable/disable backup of the device's\n"
" shared storage / SD card contents; the default is noshared.)\n"
" (-all means to back up all installed applications)\n"
diff --git a/adb/transport.c b/adb/transport.c
index 9fd6cc2..b4abb66 100644
--- a/adb/transport.c
+++ b/adb/transport.c
@@ -851,6 +851,12 @@ retry:
adb_mutex_unlock(&transport_lock);
if (result) {
+ if (result->connection_state == CS_UNAUTHORIZED) {
+ if (error_out)
+ *error_out = "device unauthorized. Please check the confirmation dialog on your device.";
+ result = NULL;
+ }
+
/* offline devices are ignored -- they are either being born or dying */
if (result && result->connection_state == CS_OFFLINE) {
if (error_out)
@@ -888,6 +894,7 @@ static const char *statename(atransport *t)
case CS_RECOVERY: return "recovery";
case CS_SIDELOAD: return "sideload";
case CS_NOPERM: return "no permissions";
+ case CS_UNAUTHORIZED: return "unauthorized";
default: return "unknown";
}
}