diff options
-rw-r--r-- | adb/SERVICES.TXT | 17 | ||||
-rw-r--r-- | adb/adb.c | 221 | ||||
-rw-r--r-- | adb/adb.h | 2 | ||||
-rw-r--r-- | adb/commandline.c | 38 | ||||
-rw-r--r-- | adb/services.c | 21 | ||||
-rwxr-xr-x | adb/usb_vendors.c | 3 | ||||
-rwxr-xr-x | debuggerd/tombstone.cpp | 1 | ||||
-rw-r--r-- | include/private/android_filesystem_config.h | 3 | ||||
-rw-r--r-- | logcat/logcat.cpp | 5 | ||||
-rw-r--r-- | logd/LogAudit.cpp | 107 | ||||
-rw-r--r-- | rootdir/init.rc | 1 | ||||
-rw-r--r-- | rootdir/init.zygote64_32.rc | 12 |
12 files changed, 298 insertions, 133 deletions
diff --git a/adb/SERVICES.TXT b/adb/SERVICES.TXT index 7f85dc3..63000f2 100644 --- a/adb/SERVICES.TXT +++ b/adb/SERVICES.TXT @@ -240,3 +240,20 @@ sync: This starts the file synchronisation service, used to implement "adb push" and "adb pull". Since this service is pretty complex, it will be detailed in a companion document named SYNC.TXT + +reverse:<forward-command> + This implements the 'adb reverse' feature, i.e. the ability to reverse + socket connections from a device to the host. <forward-command> is one + of the forwarding commands that are described above, as in: + + list-forward + forward:<local>;<remote> + forward:norebind:<local>;<remote> + killforward-all + killforward:<local> + + Note that in this case, <local> corresponds to the socket on the device + and <remote> corresponds to the socket on the host. + + The output of reverse:list-forward is the same as host:list-forward + except that <serial> will be just 'host'. @@ -318,7 +318,18 @@ static size_t fill_connect_data(char *buf, size_t bufsize) #endif } -static void send_msg_with_okay(int fd, char* msg, size_t msglen) { +#if !ADB_HOST +static void send_msg_with_header(int fd, const char* msg, size_t msglen) { + char header[5]; + if (msglen > 0xffff) + msglen = 0xffff; + snprintf(header, sizeof(header), "%04x", (unsigned)msglen); + writex(fd, header, 4); + writex(fd, msg, msglen); +} +#endif + +static void send_msg_with_okay(int fd, const char* msg, size_t msglen) { char header[9]; if (msglen > 0xffff) msglen = 0xffff; @@ -1428,6 +1439,120 @@ int adb_main(int is_daemon, int server_port) return 0; } +// Try to handle a network forwarding request. +// This returns 1 on success, 0 on failure, and -1 to indicate this is not +// a forwarding-related request. +int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd) +{ + if (!strcmp(service, "list-forward")) { + // Create the list of forward redirections. + int buffer_size = format_listeners(NULL, 0); + // Add one byte for the trailing zero. + char* buffer = malloc(buffer_size + 1); + if (buffer == NULL) { + sendfailmsg(reply_fd, "not enough memory"); + return 1; + } + (void) format_listeners(buffer, buffer_size + 1); +#if ADB_HOST + send_msg_with_okay(reply_fd, buffer, buffer_size); +#else + send_msg_with_header(reply_fd, buffer, buffer_size); +#endif + free(buffer); + return 1; + } + + if (!strcmp(service, "killforward-all")) { + remove_all_listeners(); +#if ADB_HOST + /* On the host: 1st OKAY is connect, 2nd OKAY is status */ + adb_write(reply_fd, "OKAY", 4); +#endif + adb_write(reply_fd, "OKAY", 4); + return 1; + } + + if (!strncmp(service, "forward:",8) || + !strncmp(service, "killforward:",12)) { + char *local, *remote, *err; + int r; + atransport *transport; + + int createForward = strncmp(service, "kill", 4); + int no_rebind = 0; + + local = strchr(service, ':') + 1; + + // Handle forward:norebind:<local>... here + if (createForward && !strncmp(local, "norebind:", 9)) { + no_rebind = 1; + local = strchr(local, ':') + 1; + } + + remote = strchr(local,';'); + + if (createForward) { + // Check forward: parameter format: '<local>;<remote>' + if(remote == 0) { + sendfailmsg(reply_fd, "malformed forward spec"); + return 1; + } + + *remote++ = 0; + if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')) { + sendfailmsg(reply_fd, "malformed forward spec"); + return 1; + } + } else { + // Check killforward: parameter format: '<local>' + if (local[0] == 0) { + sendfailmsg(reply_fd, "malformed forward spec"); + return 1; + } + } + + transport = acquire_one_transport(CS_ANY, ttype, serial, &err); + if (!transport) { + sendfailmsg(reply_fd, err); + return 1; + } + + if (createForward) { + r = install_listener(local, remote, transport, no_rebind); + } else { + r = remove_listener(local, transport); + } + if(r == 0) { +#if ADB_HOST + /* On the host: 1st OKAY is connect, 2nd OKAY is status */ + writex(reply_fd, "OKAY", 4); +#endif + writex(reply_fd, "OKAY", 4); + return 1; + } + + if (createForward) { + const char* message; + switch (r) { + case INSTALL_STATUS_CANNOT_BIND: + message = "cannot bind to socket"; + break; + case INSTALL_STATUS_CANNOT_REBIND: + message = "cannot rebind existing socket"; + break; + default: + message = "internal error"; + } + sendfailmsg(reply_fd, message); + } else { + sendfailmsg(reply_fd, "cannot remove listener"); + } + return 1; + } + return 0; +} + int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s) { atransport *transport = NULL; @@ -1548,97 +1673,9 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r } #endif // ADB_HOST - if(!strcmp(service,"list-forward")) { - // Create the list of forward redirections. - int buffer_size = format_listeners(NULL, 0); - // Add one byte for the trailing zero. - char* buffer = malloc(buffer_size+1); - (void) format_listeners(buffer, buffer_size+1); - send_msg_with_okay(reply_fd, buffer, buffer_size); - free(buffer); - return 0; - } - - if (!strcmp(service,"killforward-all")) { - remove_all_listeners(); - adb_write(reply_fd, "OKAYOKAY", 8); - return 0; - } - - if(!strncmp(service,"forward:",8) || - !strncmp(service,"killforward:",12)) { - char *local, *remote, *err; - int r; - atransport *transport; - - int createForward = strncmp(service,"kill",4); - int no_rebind = 0; - - local = strchr(service, ':') + 1; - - // Handle forward:norebind:<local>... here - if (createForward && !strncmp(local, "norebind:", 9)) { - no_rebind = 1; - local = strchr(local, ':') + 1; - } - - remote = strchr(local,';'); - - if (createForward) { - // Check forward: parameter format: '<local>;<remote>' - if(remote == 0) { - sendfailmsg(reply_fd, "malformed forward spec"); - return 0; - } - - *remote++ = 0; - if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){ - sendfailmsg(reply_fd, "malformed forward spec"); - return 0; - } - } else { - // Check killforward: parameter format: '<local>' - if (local[0] == 0) { - sendfailmsg(reply_fd, "malformed forward spec"); - return 0; - } - } - - transport = acquire_one_transport(CS_ANY, ttype, serial, &err); - if (!transport) { - sendfailmsg(reply_fd, err); - return 0; - } - - if (createForward) { - r = install_listener(local, remote, transport, no_rebind); - } else { - r = remove_listener(local, transport); - } - if(r == 0) { - /* 1st OKAY is connect, 2nd OKAY is status */ - writex(reply_fd, "OKAYOKAY", 8); - return 0; - } - - if (createForward) { - const char* message; - switch (r) { - case INSTALL_STATUS_CANNOT_BIND: - message = "cannot bind to socket"; - break; - case INSTALL_STATUS_CANNOT_REBIND: - message = "cannot rebind existing socket"; - break; - default: - message = "internal error"; - } - sendfailmsg(reply_fd, message); - } else { - sendfailmsg(reply_fd, "cannot remove listener"); - } - return 0; - } + int ret = handle_forward_request(service, ttype, serial, reply_fd); + if (ret >= 0) + return ret - 1; if(!strncmp(service,"get-state",strlen("get-state"))) { transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); @@ -323,6 +323,8 @@ asocket* create_jdwp_tracker_service_socket(); int create_jdwp_connection_fd(int jdwp_pid); #endif +int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd); + #if !ADB_HOST typedef enum { BACKUP, diff --git a/adb/commandline.c b/adb/commandline.c index 241cefc..3970ab1 100644 --- a/adb/commandline.c +++ b/adb/commandline.c @@ -136,6 +136,19 @@ void help() " if <local> is already forwarded\n" " adb forward --remove <local> - remove a specific forward socket connection\n" " adb forward --remove-all - remove all forward socket connections\n" + " adb reverse --list - list all reverse socket connections from device\n" + " adb reverse <remote> <local> - reverse socket connections\n" + " reverse specs are one of:\n" + " tcp:<port>\n" + " localabstract:<unix domain socket name>\n" + " localreserved:<unix domain socket name>\n" + " localfilesystem:<unix domain socket name>\n" + " adb reverse --norebind <remote> <local>\n" + " - same as 'adb reverse <remote> <local>' but fails\n" + " if <remote> is already reversed.\n" + " adb reverse --remove <remote>\n" + " - remove a specific reversed socket connection\n" + " adb reverse --remove-all - remove all reversed socket connections from device\n" " adb jdwp - list PIDs of processes hosting a JDWP transport\n" " adb install [-l] [-r] [-s] [--algo <algorithm name> --key <hex-encoded key> --iv <hex-encoded iv>] <file>\n" " - push this package file to the device and install it\n" @@ -1299,8 +1312,11 @@ top: return 0; } - if(!strcmp(argv[0], "forward")) { + if(!strcmp(argv[0], "forward") || + !strcmp(argv[0], "reverse")) + { char host_prefix[64]; + char reverse = (char) !strcmp(argv[0], "reverse"); char remove = 0; char remove_all = 0; char list = 0; @@ -1329,15 +1345,19 @@ top: } // Determine the <host-prefix> for this command. - if (serial) { - snprintf(host_prefix, sizeof host_prefix, "host-serial:%s", - serial); - } else if (ttype == kTransportUsb) { - snprintf(host_prefix, sizeof host_prefix, "host-usb"); - } else if (ttype == kTransportLocal) { - snprintf(host_prefix, sizeof host_prefix, "host-local"); + if (reverse) { + snprintf(host_prefix, sizeof host_prefix, "reverse"); } else { - snprintf(host_prefix, sizeof host_prefix, "host"); + if (serial) { + snprintf(host_prefix, sizeof host_prefix, "host-serial:%s", + serial); + } else if (ttype == kTransportUsb) { + snprintf(host_prefix, sizeof host_prefix, "host-usb"); + } else if (ttype == kTransportLocal) { + snprintf(host_prefix, sizeof host_prefix, "host-local"); + } else { + snprintf(host_prefix, sizeof host_prefix, "host"); + } } // Implement forward --list diff --git a/adb/services.c b/adb/services.c index 2d3423b..ebe84bb 100644 --- a/adb/services.c +++ b/adb/services.c @@ -154,6 +154,17 @@ cleanup: adb_close(fd); } +void reverse_service(int fd, void* arg) +{ + const char* command = arg; + + if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) { + sendfailmsg(fd, "not a reverse forwarding command"); + } + free(arg); + adb_close(fd); +} + #endif static int create_service_thread(void (*func)(int, void *), void *cookie) @@ -398,6 +409,16 @@ int service_to_fd(const char *name) ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port); } else if(!strncmp(name, "usb:", 4)) { ret = create_service_thread(restart_usb_service, NULL); + } else if (!strncmp(name, "reverse:", 8)) { + char* cookie = strdup(name + 8); + if (cookie == NULL) { + ret = -1; + } else { + ret = create_service_thread(reverse_service, cookie); + if (ret < 0) { + free(cookie); + } + } #endif } if (ret >= 0) { diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c index 0357ced..c7e0ad5 100755 --- a/adb/usb_vendors.c +++ b/adb/usb_vendors.c @@ -172,6 +172,8 @@ #define VENDOR_ID_TI 0x0451 // Toshiba's USB Vendor ID #define VENDOR_ID_TOSHIBA 0x0930 +// Unowhy's USB Vendor ID +#define VENDOR_ID_UNOWHY 0x2A49 // Vizio's USB Vendor ID #define VENDOR_ID_VIZIO 0xE040 // Wacom's USB Vendor ID @@ -257,6 +259,7 @@ int builtInVendorIds[] = { VENDOR_ID_TELEEPOCH, VENDOR_ID_TI, VENDOR_ID_TOSHIBA, + VENDOR_ID_UNOWHY, VENDOR_ID_VIZIO, VENDOR_ID_WACOM, VENDOR_ID_XIAOMI, diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp index 1a00146..cdaa09f 100755 --- a/debuggerd/tombstone.cpp +++ b/debuggerd/tombstone.cpp @@ -583,7 +583,6 @@ static void dump_log_file(log_t* log, pid_t pid, const char* filename, static void dump_logs(log_t* log, pid_t pid, unsigned tail) { dump_log_file(log, pid, "system", tail); dump_log_file(log, pid, "main", tail); - dump_log_file(log, pid, "events", tail); } static void dump_abort_message(Backtrace* backtrace, log_t* log, uintptr_t address) { diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h index d662107..f5289c1 100644 --- a/include/private/android_filesystem_config.h +++ b/include/private/android_filesystem_config.h @@ -77,6 +77,7 @@ #define AID_SDCARD_AV 1034 /* external storage audio/video access */ #define AID_SDCARD_ALL 1035 /* access all users external storage */ #define AID_LOGD 1036 /* log daemon */ +#define AID_SHARED_RELRO 1037 /* creator of shared GNU RELRO files */ #define AID_SHELL 2000 /* adb and debug shell user */ #define AID_CACHE 2001 /* cache access */ @@ -153,6 +154,7 @@ static const struct android_id_info android_ids[] = { { "sdcard_av", AID_SDCARD_AV, }, { "sdcard_all", AID_SDCARD_ALL, }, { "logd", AID_LOGD, }, + { "shared_relro", AID_SHARED_RELRO, }, { "shell", AID_SHELL, }, { "cache", AID_CACHE, }, @@ -198,6 +200,7 @@ static const struct fs_path_config android_dirs[] = { { 00771, AID_SHELL, AID_SHELL, 0, "data/local" }, { 01771, AID_SYSTEM, AID_MISC, 0, "data/misc" }, { 00770, AID_DHCP, AID_DHCP, 0, "data/misc/dhcp" }, + { 00771, AID_SHARED_RELRO, AID_SHARED_RELRO, 0, "data/misc/shared_relro" }, { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media" }, { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" }, { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" }, diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp index ed2c241..16fe7ee 100644 --- a/logcat/logcat.cpp +++ b/logcat/logcat.cpp @@ -633,11 +633,6 @@ int main(int argc, char **argv) dev = dev->next = new log_device_t("crash", false, 'c'); android::g_devCount++; } - if (android_name_to_log_id("events") == LOG_ID_EVENTS) { - dev = dev->next = new log_device_t("events", true, 'e'); - android::g_devCount++; - needBinary = true; - } } if (android::g_logRotateSizeKBytes != 0 diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp index 0651a92..f8d6162 100644 --- a/logd/LogAudit.cpp +++ b/logd/LogAudit.cpp @@ -70,6 +70,11 @@ int LogAudit::logPrint(const char *fmt, ...) { return rc; } + char *cp; + while ((cp = strstr(str, " "))) { + memmove(cp, cp + 1, strlen(cp + 1) + 1); + } + if (fdDmesg >= 0) { struct iovec iov[2]; @@ -88,12 +93,11 @@ int LogAudit::logPrint(const char *fmt, ...) { static const char audit_str[] = " audit("; char *timeptr = strstr(str, audit_str); - char *cp; if (timeptr && ((cp = now.strptime(timeptr + sizeof(audit_str) - 1, "%s.%q"))) && (*cp == ':')) { memcpy(timeptr + sizeof(audit_str) - 1, "0.0", 3); - strcpy(timeptr + sizeof(audit_str) - 1 + 3, cp); + memmove(timeptr + sizeof(audit_str) - 1 + 3, cp, strlen(cp) + 1); } else { now.strptime("", ""); // side effect of setting CLOCK_REALTIME } @@ -109,37 +113,88 @@ int LogAudit::logPrint(const char *fmt, ...) { } tid = pid; uid = logbuf->pidToUid(pid); - strcpy(pidptr, cp); + memmove(pidptr, cp, strlen(cp) + 1); } - size_t n = strlen(str); - n += sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t); + // log to events + + size_t l = strlen(str); + size_t n = l + sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t); + + bool notify = false; char *newstr = reinterpret_cast<char *>(malloc(n)); if (!newstr) { - free(str); - return -ENOMEM; - } - - char *msg = newstr; - *msg++ = AUDITD_LOG_TAG & 0xFF; - *msg++ = (AUDITD_LOG_TAG >> 8) & 0xFF; - *msg++ = (AUDITD_LOG_TAG >> 16) & 0xFF; - *msg++ = (AUDITD_LOG_TAG >> 24) & 0xFF; - *msg++ = EVENT_TYPE_STRING; - size_t l = n - sizeof(uint32_t) - sizeof(uint8_t) - sizeof(uint32_t); - *msg++ = l & 0xFF; - *msg++ = (l >> 8) & 0xFF; - *msg++ = (l >> 16) & 0xFF; - *msg++ = (l >> 24) & 0xFF; - memcpy(msg, str, l); - free(str); + rc = -ENOMEM; + } else { + cp = newstr; + *cp++ = AUDITD_LOG_TAG & 0xFF; + *cp++ = (AUDITD_LOG_TAG >> 8) & 0xFF; + *cp++ = (AUDITD_LOG_TAG >> 16) & 0xFF; + *cp++ = (AUDITD_LOG_TAG >> 24) & 0xFF; + *cp++ = EVENT_TYPE_STRING; + *cp++ = l & 0xFF; + *cp++ = (l >> 8) & 0xFF; + *cp++ = (l >> 16) & 0xFF; + *cp++ = (l >> 24) & 0xFF; + memcpy(cp, str, l); + + logbuf->log(LOG_ID_EVENTS, now, uid, pid, tid, newstr, + (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX); + free(newstr); + + notify = true; + } + + // log to main + + static const char comm_str[] = " comm=\""; + const char *comm = strstr(str, comm_str); + const char *estr = str + strlen(str); + if (comm) { + estr = comm; + comm += sizeof(comm_str) - 1; + } else if (pid == getpid()) { + pid = tid; + comm = "auditd"; + } else if (!(comm = logbuf->pidToName(pid))) { + comm = "unknown"; + } + + const char *ecomm = strchr(comm, '"'); + if (ecomm) { + ++ecomm; + l = ecomm - comm; + } else { + l = strlen(comm) + 1; + ecomm = ""; + } + n = (estr - str) + strlen(ecomm) + l + 2; + + newstr = reinterpret_cast<char *>(malloc(n)); + if (!newstr) { + rc = -ENOMEM; + } else { + *newstr = (strstr(str, " permissive=1") + || strstr(str, " policy loaded ")) + ? ANDROID_LOG_INFO + : ANDROID_LOG_WARN; + strlcpy(newstr + 1, comm, l); + strncpy(newstr + 1 + l, str, estr - str); + strcpy(newstr + 1 + l + (estr - str), ecomm); + + logbuf->log(LOG_ID_MAIN, now, uid, pid, tid, newstr, + (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX); + free(newstr); + + notify = true; + } - logbuf->log(LOG_ID_EVENTS, now, uid, pid, tid, newstr, - (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX); - reader->notifyNewLog(); + free(str); - free(newstr); + if (notify) { + reader->notifyNewLog(); + } return rc; } diff --git a/rootdir/init.rc b/rootdir/init.rc index 2585353..9f60081 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -226,6 +226,7 @@ on post-fs-data mkdir /data/misc/sms 0770 system radio mkdir /data/misc/zoneinfo 0775 system system mkdir /data/misc/vpn 0770 system vpn + mkdir /data/misc/shared_relro 0771 shared_relro shared_relro mkdir /data/misc/systemkeys 0700 system system mkdir /data/misc/wifi 0770 wifi wifi mkdir /data/misc/wifi/sockets 0770 wifi wifi diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc new file mode 100644 index 0000000..979ab3b --- /dev/null +++ b/rootdir/init.zygote64_32.rc @@ -0,0 +1,12 @@ +service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote + class main + socket zygote stream 660 root system + onrestart write /sys/android_power/request_state wake + onrestart write /sys/power/state on + onrestart restart media + onrestart restart netd + +service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary + class main + socket zygote_secondary stream 660 root system + onrestart restart zygote |