From f01b52895dfb44c3a7e98a870ab415672aee0960 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Tue, 23 May 2017 16:24:48 +0900 Subject: [PATCH 001/129] vndk: remove vendor/lib from the search path of the 'vndk' namespace 'vndk' namespace is the place for VNDK-SP libs. So /vendor/lib must be removed from its search paths. It was there just because libhardware (which is VNDK-SP) is loading HAL libs in vendor partition from there. However this problem has been solved by modifying the libhardware so that HAL libs are loaded from the 'sphal' namespace and not from the current (the 'vndk') namespace. Bug: 37731053 Test: sailfish builds and boots Change-Id: Ia88934a975aa8811e05b5ba408e42d132f20f4e9 --- rootdir/etc/ld.config.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index 773ca0684..328ac1e44 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt @@ -93,10 +93,10 @@ namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:androi # This namespace is exclusively for vndk-sp libs. ############################################################################### namespace.vndk.isolated = true -namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/vendor/${LIB} +namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl -namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/vendor/${LIB}:/vendor/${LIB} +namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl # When these NDK libs are required inside this namespace, then it is redirected From 62962dd5b7a37478da2bad786e084345d366f984 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 13 Jun 2017 10:15:05 -0700 Subject: [PATCH 002/129] Move chmod of /sys/kernel/debug/tracing to fix traceur. This is a temporary fix, since we're still not sure exactly what the bug is. Bug: 62547086 Test: Built, flashed, and booted Marlin. Verified that the file has the correct permission and that traceur does not popup an error. Change-Id: I43275e974a11754eca274f1b77d15cdd03a3b365 --- rootdir/init.rc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rootdir/init.rc b/rootdir/init.rc index c32d41bc1..2778bbc66 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -317,7 +317,6 @@ on post-fs # Make sure /sys/kernel/debug (if present) is labeled properly # Note that tracefs may be mounted under debug, so we need to cross filesystems restorecon --recursive --cross-filesystems /sys/kernel/debug - chmod 0755 /sys/kernel/debug/tracing # We chown/chmod /cache again so because mount is run as root + defaults chown system cache /cache @@ -355,6 +354,10 @@ on post-fs mkdir /cache/lost+found 0770 root root on late-fs + # Ensure that tracefs has the correct permissions. + # This does not work correctly if it is called in post-fs. + chmod 0755 /sys/kernel/debug/tracing + # HALs required before storage encryption can get unlocked (FBE/FDE) class_start early_hal From 59d9ee5d020c54d89cbb520b30fa19765a68646d Mon Sep 17 00:00:00 2001 From: Jesse Hall Date: Mon, 12 Jun 2017 10:51:34 -0700 Subject: [PATCH 003/129] Fix NDK libsync to match ndk/sync.h The header names were changed during review, but the library map file wasn't updated. Bug: 62229958 Test: CtsGraphicsTestCases:android.graphics.cts.SyncTest Change-Id: Ie5955865667b35067f1ee209933f159f170419cd --- libsync/libsync.map.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsync/libsync.map.txt b/libsync/libsync.map.txt index daa28ae92..f9057bd7f 100644 --- a/libsync/libsync.map.txt +++ b/libsync/libsync.map.txt @@ -17,8 +17,8 @@ LIBSYNC { global: sync_merge; # introduced=26 - sync_get_fence_info; # introduced=26 - sync_free_fence_info; # introduced=26 + sync_file_info; # introduced=26 + sync_file_info_free; # introduced=26 local: *; }; From 6fb86da61b19e340d3ad44706a16267e8cfe0e17 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Wed, 14 Jun 2017 11:15:00 -0700 Subject: [PATCH 004/129] Remove restorecon of file_contexts.bin file_contexts.bin is dead. Long live split file_contexts. Test: build and flash angler. Change-Id: I962743ce3e98aefee14d972e04bf4e68bec633a5 --- init/init.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/init/init.cpp b/init/init.cpp index ee87145c3..48cb1e85d 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -897,7 +897,6 @@ static void selinux_restore_context() { selinux_android_restorecon("/dev/urandom", 0); selinux_android_restorecon("/dev/__properties__", 0); - selinux_android_restorecon("/file_contexts.bin", 0); selinux_android_restorecon("/plat_file_contexts", 0); selinux_android_restorecon("/nonplat_file_contexts", 0); selinux_android_restorecon("/plat_property_contexts", 0); From 673e27677aad3de9d2c8ac22321650e5a642aa13 Mon Sep 17 00:00:00 2001 From: Robert Benea Date: Thu, 1 Jun 2017 16:32:31 -0700 Subject: [PATCH 005/129] Make lmkd use medium/critical mem pressure, and update soft limit based on adj score. Test: GO device (512MB/1GB), both show improvements under heavy load. Bug: 62626918 Change-Id: I98afc8b1171db5b57056bc05d1f1ae9c5eed8506 --- lmkd/lmkd.c | 124 +++++++++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index 8a6168cd3..c0953158d 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -40,7 +40,8 @@ #endif #define MEMCG_SYSFS_PATH "/dev/memcg/" -#define MEMPRESSURE_WATCH_LEVEL "low" +#define MEMPRESSURE_WATCH_MEDIUM_LEVEL "medium" +#define MEMPRESSURE_WATCH_CRITICAL_LEVEL "critical" #define ZONEINFO_PATH "/proc/zoneinfo" #define LINE_MAX 128 @@ -48,6 +49,7 @@ #define INKERNEL_ADJ_PATH "/sys/module/lowmemorykiller/parameters/adj" #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) +#define EIGHT_MEGA (1 << 23) enum lmk_cmd { LMK_TARGET, @@ -66,15 +68,17 @@ enum lmk_cmd { static int use_inkernel_interface = 1; /* memory pressure level medium event */ -static int mpevfd; +static int mpevfd[2]; +#define CRITICAL_INDEX 1 +#define MEDIUM_INDEX 0 /* control socket listen and data */ static int ctrl_lfd; static int ctrl_dfd = -1; static int ctrl_dfd_reopened; /* did we reopen ctrl conn on this loop? */ -/* 1 memory pressure level, 1 ctrl listen socket, 1 ctrl data socket */ -#define MAX_EPOLL_EVENTS 3 +/* 2 memory pressure levels, 1 ctrl listen socket, 1 ctrl data socket */ +#define MAX_EPOLL_EVENTS 4 static int epollfd; static int maxevents; @@ -113,14 +117,6 @@ static struct proc *pidhash[PIDHASH_SZ]; #define ADJTOSLOT(adj) ((adj) + -OOM_SCORE_ADJ_MIN) static struct adjslot_list procadjslot_list[ADJTOSLOT(OOM_SCORE_ADJ_MAX) + 1]; -/* - * Wait 1-2 seconds for the death report of a killed process prior to - * considering killing more processes. - */ -#define KILL_TIMEOUT 2 -/* Time of last process kill we initiated, stop me before I kill again */ -static time_t kill_lasttime; - /* PAGE_SIZE / 1024 */ static long page_k; @@ -241,6 +237,7 @@ static void cmd_procprio(int pid, int uid, int oomadj) { struct proc *procp; char path[80]; char val[20]; + int soft_limit_mult; if (oomadj < OOM_SCORE_ADJ_MIN || oomadj > OOM_SCORE_ADJ_MAX) { ALOGE("Invalid PROCPRIO oomadj argument %d", oomadj); @@ -254,6 +251,36 @@ static void cmd_procprio(int pid, int uid, int oomadj) { if (use_inkernel_interface) return; + if (oomadj >= 900) { + soft_limit_mult = 0; + } else if (oomadj >= 800) { + soft_limit_mult = 0; + } else if (oomadj >= 700) { + soft_limit_mult = 0; + } else if (oomadj >= 600) { + soft_limit_mult = 0; + } else if (oomadj >= 500) { + soft_limit_mult = 0; + } else if (oomadj >= 400) { + soft_limit_mult = 0; + } else if (oomadj >= 300) { + soft_limit_mult = 1; + } else if (oomadj >= 200) { + soft_limit_mult = 2; + } else if (oomadj >= 100) { + soft_limit_mult = 10; + } else if (oomadj >= 0) { + soft_limit_mult = 20; + } else { + // Persistent processes will have a large + // soft limit 512MB. + soft_limit_mult = 64; + } + + snprintf(path, sizeof(path), "/dev/memcg/apps/uid_%d/pid_%d/memory.soft_limit_in_bytes", uid, pid); + snprintf(val, sizeof(val), "%d", soft_limit_mult * EIGHT_MEGA); + writefilestring(path, val); + procp = pid_lookup(pid); if (!procp) { procp = malloc(sizeof(struct proc)); @@ -278,7 +305,6 @@ static void cmd_procremove(int pid) { return; pid_remove(pid); - kill_lasttime = 0; } static void cmd_target(int ntargets, int *params) { @@ -574,7 +600,6 @@ static int kill_one_process(struct proc *procp, int other_free, int other_file, first ? "" : "~", other_file * page_k, minfree * page_k, min_score_adj, first ? "" : "~", other_free * page_k, other_free >= 0 ? "above" : "below"); r = kill(pid, SIGKILL); - killProcessGroup(uid, pid, SIGKILL); pid_remove(pid); if (r) { @@ -589,24 +614,12 @@ static int kill_one_process(struct proc *procp, int other_free, int other_file, * Find a process to kill based on the current (possibly estimated) free memory * and cached memory sizes. Returns the size of the killed processes. */ -static int find_and_kill_process(int other_free, int other_file, bool first) +static int find_and_kill_process(int other_free, int other_file, bool first, int min_score_adj) { int i; - int min_score_adj = OOM_SCORE_ADJ_MAX + 1; int minfree = 0; int killed_size = 0; - for (i = 0; i < lowmem_targets_size; i++) { - minfree = lowmem_minfree[i]; - if (other_free < minfree && other_file < minfree) { - min_score_adj = lowmem_adj[i]; - break; - } - } - - if (min_score_adj == OOM_SCORE_ADJ_MAX + 1) - return 0; - for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) { struct proc *procp; @@ -626,42 +639,33 @@ retry: return 0; } -static void mp_event(uint32_t events __unused) { +static void mp_event_common(bool is_critical) { int ret; unsigned long long evcount; - struct sysmeminfo mi; - int other_free; - int other_file; - int killed_size; bool first = true; + int min_adj_score = is_critical ? 0 : 800; + int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX; - ret = read(mpevfd, &evcount, sizeof(evcount)); + ret = read(mpevfd[index], &evcount, sizeof(evcount)); if (ret < 0) ALOGE("Error reading memory pressure event fd; errno=%d", errno); - if (time(NULL) - kill_lasttime < KILL_TIMEOUT) - return; - - while (zoneinfo_parse(&mi) < 0) { - // Failed to read /proc/zoneinfo, assume ENOMEM and kill something - find_and_kill_process(0, 0, true); + if (find_and_kill_process(0, 0, first, min_adj_score) == 0) { + ALOGI("Nothing to kill"); } - - other_free = mi.nr_free_pages - mi.totalreserve_pages; - other_file = mi.nr_file_pages - mi.nr_shmem; - - do { - killed_size = find_and_kill_process(other_free, other_file, first); - if (killed_size > 0) { - first = false; - other_free += killed_size; - other_file += killed_size; - } - } while (killed_size > 0); } -static int init_mp(char *levelstr, void *event_handler) +static void mp_event(uint32_t events __unused) { + mp_event_common(false); +} + +static void mp_event_critical(uint32_t events __unused) { + ALOGI("Memory pressure critical"); + mp_event_common(true); +} + +static int init_mp_common(char *levelstr, void *event_handler, bool is_critical) { int mpfd; int evfd; @@ -669,6 +673,7 @@ static int init_mp(char *levelstr, void *event_handler) char buf[256]; struct epoll_event epev; int ret; + int mpevfd_index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX; mpfd = open(MEMCG_SYSFS_PATH "memory.pressure_level", O_RDONLY | O_CLOEXEC); if (mpfd < 0) { @@ -709,7 +714,7 @@ static int init_mp(char *levelstr, void *event_handler) goto err; } maxevents++; - mpevfd = evfd; + mpevfd[mpevfd_index] = evfd; return 0; err: @@ -722,6 +727,16 @@ err_open_mpfd: return -1; } +static int init_mp_medium() +{ + return init_mp_common(MEMPRESSURE_WATCH_MEDIUM_LEVEL, (void *)&mp_event, false); +} + +static int init_mp_critical() +{ + return init_mp_common(MEMPRESSURE_WATCH_CRITICAL_LEVEL, (void *)&mp_event_critical, true); +} + static int init(void) { struct epoll_event epev; int i; @@ -763,7 +778,8 @@ static int init(void) { if (use_inkernel_interface) { ALOGI("Using in-kernel low memory killer interface"); } else { - ret = init_mp(MEMPRESSURE_WATCH_LEVEL, (void *)&mp_event); + ret = init_mp_medium(); + ret |= init_mp_critical(); if (ret) ALOGE("Kernel does not support memory pressure events or in-kernel low memory killer"); } From a2421041bfae954ab30aa2f735dc77758ff531e4 Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Fri, 9 Jun 2017 13:25:46 -0700 Subject: [PATCH 006/129] init: rename mke2fs tools with _static suffix We build a static version for recovery mode. Give them different names to avoid conflicts with regular version in /system/bin/ Bug: 35219933 Change-Id: I738655ad9b9ad71c63ae604d9a4d659b0b671121 --- init/init.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init/init.cpp b/init/init.cpp index ee87145c3..871459b10 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -915,8 +915,8 @@ static void selinux_restore_context() { selinux_android_restorecon("/dev/block", SELINUX_ANDROID_RESTORECON_RECURSE); selinux_android_restorecon("/dev/device-mapper", 0); - selinux_android_restorecon("/sbin/mke2fs", 0); - selinux_android_restorecon("/sbin/e2fsdroid", 0); + selinux_android_restorecon("/sbin/mke2fs_static", 0); + selinux_android_restorecon("/sbin/e2fsdroid_static", 0); } // Set the UDC controller for the ConfigFS USB Gadgets. From afa345325647e66dc7add78f7100dc81bd066dbb Mon Sep 17 00:00:00 2001 From: Daichi Hirono Date: Thu, 15 Jun 2017 15:48:07 +0900 Subject: [PATCH 007/129] Skip FUSE request from /dev/fuse if unique=0 APCT log shows that we got FUSE request unique=0 and replying to such request causes a EINVAL. The possible reasons of getting unique=0 here are: * /dev/fuse actually submits such requests. In this case, not replying to such request probabbly safe as the kernel cannot wait corresponding response without a unique number. We can observing the kernel code to find out what unique=0 actually means. * Memory corruption happens and unique number are cleared with zero. In this case, if we skip unique=0 request, libappfuse does not reply to the kernel request and APCT result will become timeout . To see which case happens, the CL ScopedLogSeverity to output verbose logs and lets FuseBridgeLoop skip a request from /dev/fuse if unique=0. Bug: 62429763 Test: libappfuse_tests Change-Id: I8c4d532564b690d55573b92260170b0cd68150ab --- libappfuse/FuseBridgeLoop.cc | 9 ++++++++- libappfuse/tests/FuseBridgeLoopTest.cc | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc index 07923071b..5a897a472 100644 --- a/libappfuse/FuseBridgeLoop.cc +++ b/libappfuse/FuseBridgeLoop.cc @@ -173,13 +173,20 @@ class FuseBridgeEntry { } FuseBridgeState ReadFromDevice(FuseBridgeLoopCallback* callback) { + // To observe APCT failures. + base::ScopedLogSeverity log_severity(base::VERBOSE); + LOG(VERBOSE) << "ReadFromDevice"; if (!buffer_.request.Read(device_fd_)) { return FuseBridgeState::kClosing; } const uint32_t opcode = buffer_.request.header.opcode; - LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode; + const uint64_t unique = buffer_.request.header.unique; + LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode << " unique=" << unique; + if (unique == 0) { + return FuseBridgeState::kWaitToReadEither; + } switch (opcode) { case FUSE_FORGET: // Do not reply to FUSE_FORGET. diff --git a/libappfuse/tests/FuseBridgeLoopTest.cc b/libappfuse/tests/FuseBridgeLoopTest.cc index 51d605136..0a28451bf 100644 --- a/libappfuse/tests/FuseBridgeLoopTest.cc +++ b/libappfuse/tests/FuseBridgeLoopTest.cc @@ -67,6 +67,7 @@ class FuseBridgeLoopTest : public ::testing::Test { memset(&request_, 0, sizeof(FuseRequest)); request_.header.opcode = opcode; request_.header.len = sizeof(fuse_in_header); + request_.header.unique = 1; ASSERT_TRUE(request_.Write(dev_sockets_[0])); memset(&response_, 0, sizeof(FuseResponse)); From f71bc0c1524bdbad64bcd62c9deb86067d6e4ad9 Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Fri, 21 Apr 2017 16:56:34 -0700 Subject: [PATCH 008/129] fs_mgr: replace make_ext4 api with e2fsprogs Execute mke2fs to create empty ext4 filesystem. Execute e2fsdroid to initialize selinux context. Test: zero-out first 4k of data partition and reboot, fs_mgr successfully formats /data. Bug: 35219933 Change-Id: If6f72f62c618c64be703b83f0114a4dd0a2b079f --- fs_mgr/Android.bp | 4 +- fs_mgr/Android.mk | 1 + fs_mgr/fs_mgr_format.cpp | 105 ++++++++++++++------------------------- 3 files changed, 41 insertions(+), 69 deletions(-) diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp index 0af615905..4441ad0c1 100644 --- a/fs_mgr/Android.bp +++ b/fs_mgr/Android.bp @@ -22,7 +22,6 @@ cc_defaults { local_include_dirs: ["include/"], cppflags: ["-Werror"], static_libs: [ - "liblogwrap", "libfec", "libfec_rs", "libbase", @@ -33,6 +32,9 @@ cc_defaults { "libselinux", "libavb", ], + whole_static_libs: [ + "liblogwrap", + ], } cc_library_static { diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk index f3ca7246f..924934308 100644 --- a/fs_mgr/Android.mk +++ b/fs_mgr/Android.mk @@ -21,6 +21,7 @@ LOCAL_SRC_FILES:= fs_mgr_main.cpp LOCAL_C_INCLUDES := $(LOCAL_PATH)/include LOCAL_MODULE:= fs_mgr LOCAL_MODULE_TAGS := optional +LOCAL_REQUIRED_MODULES := mke2fs mke2fs.conf e2fsdroid LOCAL_FORCE_STATIC_EXECUTABLE := true LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/sbin LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp index a03d92c6b..75feee798 100644 --- a/fs_mgr/fs_mgr_format.cpp +++ b/fs_mgr/fs_mgr_format.cpp @@ -24,25 +24,21 @@ #include #include -#include #include -#include -#include -#include +#include +#include #include +#include +#include #include "fs_mgr_priv.h" #include "cryptfs.h" -extern "C" { -extern struct fs_info info; /* magic global from ext4_utils */ -extern void reset_ext4fs_info(); -} - static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer) { uint64_t dev_sz; int fd, rc = 0; + int status; if ((fd = open(fs_blkdev, O_WRONLY)) < 0) { PERROR << "Cannot open block device"; @@ -55,30 +51,36 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer) return -1; } - struct selabel_handle *sehandle = selinux_android_file_context_handle(); - if (!sehandle) { - /* libselinux logs specific error */ - LERROR << "Cannot initialize android file_contexts"; - close(fd); - return -1; - } - - /* Format the partition using the calculated length */ - reset_ext4fs_info(); - info.len = (off64_t)dev_sz; - if (crypt_footer) { - info.len -= CRYPT_FOOTER_OFFSET; - } - - /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */ - rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, sehandle, 0, 0, NULL, NULL, NULL); - if (rc) { - LERROR << "make_ext4fs returned " << rc; - } close(fd); - if (sehandle) { - selabel_close(sehandle); + /* Format the partition using the calculated length */ + if (crypt_footer) { + dev_sz -= CRYPT_FOOTER_OFFSET; + } + + std::string size_str = std::to_string(dev_sz / 4096); + const char* const mke2fs_args[] = { + "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr}; + + rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast(mke2fs_args), &status, + true, LOG_KLOG, true, nullptr, nullptr, 0); + if (rc) { + LERROR << "mke2fs returned " << rc; + return rc; + } + + const char* const e2fsdroid_args[] = { + "/system/bin/e2fsdroid", + "-e", + "-a", + fs_mnt_point, + fs_blkdev, + nullptr}; + + rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast(e2fsdroid_args), + &status, true, LOG_KLOG, true, nullptr, nullptr, 0); + if (rc) { + LERROR << "e2fsdroid returned " << rc; } return rc; @@ -86,44 +88,11 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer) static int format_f2fs(char *fs_blkdev) { - char * args[5]; - int pid; - int rc = 0; + int status; + const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr}; - args[0] = (char *)"/system/bin/make_f2fs"; - args[1] = (char *)"-f"; - args[2] = (char *)"-O encrypt"; - args[3] = fs_blkdev; - args[4] = (char *)0; - - pid = fork(); - if (pid < 0) { - return pid; - } - if (!pid) { - /* This doesn't return */ - execv(args[0], args); - exit(1); - } - for(;;) { - pid_t p = waitpid(pid, &rc, 0); - if (p != pid) { - LERROR << "Error waiting for child process - " << p; - rc = -1; - break; - } - if (WIFEXITED(rc)) { - rc = WEXITSTATUS(rc); - LINFO << args[0] << " done, status " << rc; - if (rc) { - rc = -1; - } - break; - } - LERROR << "Still waiting for " << args[0] << "..."; - } - - return rc; + return android_fork_execvp_ext(arraysize(args), const_cast(args), &status, true, + LOG_KLOG, true, nullptr, nullptr, 0); } int fs_mgr_do_format(struct fstab_rec *fstab, bool crypt_footer) From 6ac5322a33f46db7b1319eac706dbc04ff3e1e0f Mon Sep 17 00:00:00 2001 From: Ben Fennema Date: Thu, 22 Jun 2017 15:00:55 -0700 Subject: [PATCH 009/129] fs_mgr: properly propagate exec child errors Child status was being requested, but ignored, so if the exec failed with something like file not found or permissions denied the return value with be 0 (success). Passing in NULL instead of &status causes the failure to be properly returned from execvp instead of in status. Test: erase f2fs userdata on device without /system/bin/make_f2fs and verify device boots into recovery to format the partition instead of believing the format succeeded and going into infinite f2fs.fsck loop. Bug: 62901965 Signed-off-by: Ben Fennema Change-Id: Ia5bbf09d5a666402cba8437abcc56775583ba6d2 --- fs_mgr/fs_mgr_format.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp index 75feee798..fc88217ce 100644 --- a/fs_mgr/fs_mgr_format.cpp +++ b/fs_mgr/fs_mgr_format.cpp @@ -38,7 +38,6 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer) { uint64_t dev_sz; int fd, rc = 0; - int status; if ((fd = open(fs_blkdev, O_WRONLY)) < 0) { PERROR << "Cannot open block device"; @@ -62,7 +61,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer) const char* const mke2fs_args[] = { "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr}; - rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast(mke2fs_args), &status, + rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast(mke2fs_args), NULL, true, LOG_KLOG, true, nullptr, nullptr, 0); if (rc) { LERROR << "mke2fs returned " << rc; @@ -78,7 +77,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer) nullptr}; rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast(e2fsdroid_args), - &status, true, LOG_KLOG, true, nullptr, nullptr, 0); + NULL, true, LOG_KLOG, true, nullptr, nullptr, 0); if (rc) { LERROR << "e2fsdroid returned " << rc; } @@ -88,10 +87,9 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer) static int format_f2fs(char *fs_blkdev) { - int status; const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr}; - return android_fork_execvp_ext(arraysize(args), const_cast(args), &status, true, + return android_fork_execvp_ext(arraysize(args), const_cast(args), NULL, true, LOG_KLOG, true, nullptr, nullptr, 0); } From a6dee5e279de56751238f750d12f8a6237992043 Mon Sep 17 00:00:00 2001 From: Daichi Hirono Date: Tue, 20 Jun 2017 16:18:32 +0900 Subject: [PATCH 010/129] Add volatile to temporary variable. FuseBuffer::HandleNotImpl save the value of |request.header.unique| to the temporary variable, clear the buffer which is a union of |request| and |response|, then write back the unique value to response.header.unique. Before the CL, the temporary variable was wrongly removed by the compiler optimization, and response.header.unique was always 0. The CL adds volatile modifier as workaround to prevent the compiler optimization from removing the temporary value. Bug: 62429763 Test: libappfuse_tests Change-Id: Ia853f805633f646f316f585a35c7b018000b6eb3 --- libappfuse/FuseBuffer.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libappfuse/FuseBuffer.cc b/libappfuse/FuseBuffer.cc index 1b47e0a35..1eab46cb4 100644 --- a/libappfuse/FuseBuffer.cc +++ b/libappfuse/FuseBuffer.cc @@ -251,7 +251,9 @@ void FuseBuffer::HandleInit() { void FuseBuffer::HandleNotImpl() { LOG(VERBOSE) << "NOTIMPL op=" << request.header.opcode << " uniq=" << request.header.unique << " nid=" << request.header.nodeid; - const uint64_t unique = request.header.unique; + // Add volatile as a workaround for compiler issue which removes the temporary + // variable. + const volatile uint64_t unique = request.header.unique; response.Reset(0, -ENOSYS, unique); } From 43e20cac7b0f0fac603999cdb9516929b3f758dd Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Mon, 26 Jun 2017 13:52:06 -0700 Subject: [PATCH 011/129] libutils: liblog export headers - make liblog dependency for all library builds (this is required for files like String8.cpp) - export liblog headers (because they are used in many header files). Test: less libraries fail with BOARD_VNDK_VERSION := current Change-Id: Iecb9cd00deb3a9056ea63c4a087afdb80a51a2b8 --- libutils/Android.bp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libutils/Android.bp b/libutils/Android.bp index 508f5536c..ef16d56aa 100644 --- a/libutils/Android.bp +++ b/libutils/Android.bp @@ -79,6 +79,13 @@ cc_library { "libutils_headers", ], + shared_libs: [ + "liblog", + ], + export_shared_lib_headers: [ + "liblog", + ], + arch: { mips: { cflags: ["-DALIGN_DOUBLE"], @@ -99,7 +106,6 @@ cc_library { "libbacktrace", "libcutils", "libdl", - "liblog", "libvndksupport", ], From 5eeb934689e8bc0d60f8d055cf3fd756b1d30fe3 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 26 Jun 2017 17:01:42 +0900 Subject: [PATCH 012/129] fs_mgr: add libfstab for vendor libfstab is a subset of libfs_mgr, intended for vendors to use. It exposes APIs for reading fstab. Note this 'visible to vendor' does not mean that the API should be stable forever. The API can be changed in later releases of Android, ,but the newer Android must not cause run-time error when there is an older version of this static library being used somewhere. Bug: 62990533 Test: BOARD_VNDK_VERSION=current m -j libfstab.vendor Change-Id: If8fc73e4ae4c2f8281c41a12f1c18079aab8baa2 --- fs_mgr/Android.bp | 49 +++++++++----- fs_mgr/include/fs_mgr.h | 73 +-------------------- fs_mgr/include_fstab/fstab/fstab.h | 101 +++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 89 deletions(-) create mode 100644 fs_mgr/include_fstab/fstab/fstab.h diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp index 4441ad0c1..7fd67c293 100644 --- a/fs_mgr/Android.bp +++ b/fs_mgr/Android.bp @@ -21,20 +21,6 @@ cc_defaults { }, local_include_dirs: ["include/"], cppflags: ["-Werror"], - static_libs: [ - "libfec", - "libfec_rs", - "libbase", - "libcrypto_utils", - "libcrypto", - "libext4_utils", - "libsquashfs_utils", - "libselinux", - "libavb", - ], - whole_static_libs: [ - "liblogwrap", - ], } cc_library_static { @@ -46,12 +32,28 @@ cc_library_static { "fs_mgr.cpp", "fs_mgr_dm_ioctl.cpp", "fs_mgr_format.cpp", - "fs_mgr_fstab.cpp", - "fs_mgr_slotselect.cpp", "fs_mgr_verity.cpp", "fs_mgr_avb.cpp", "fs_mgr_avb_ops.cpp", - "fs_mgr_boot_config.cpp", + ], + static_libs: [ + "libfec", + "libfec_rs", + "libbase", + "libcrypto_utils", + "libcrypto", + "libext4_utils", + "libsquashfs_utils", + "libselinux", + "libavb", + "libfstab", + ], + export_static_lib_headers: [ + "libfstab", + ], + whole_static_libs: [ + "liblogwrap", + "libfstab", ], product_variables: { debuggable: { @@ -62,3 +64,16 @@ cc_library_static { }, }, } + +cc_library_static { + name: "libfstab", + vendor_available: true, + defaults: ["fs_mgr_defaults"], + srcs: [ + "fs_mgr_fstab.cpp", + "fs_mgr_boot_config.cpp", + "fs_mgr_slotselect.cpp", + ], + export_include_dirs: ["include_fstab"], + header_libs: ["libbase_headers"], +} diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h index e033d4749..c74f6c85c 100644 --- a/fs_mgr/include/fs_mgr.h +++ b/fs_mgr/include/fs_mgr.h @@ -22,11 +22,7 @@ #include #include -// C++ only headers -// TODO: move this into separate header files under include/fs_mgr/*.h -#ifdef __cplusplus -#include -#endif +#include // Magic number at start of verity metadata #define VERITY_METADATA_MAGIC_NUMBER 0xb001b001 @@ -53,49 +49,10 @@ enum mount_mode { MOUNT_MODE_LATE = 2 }; -/* - * The entries must be kept in the same order as they were seen in the fstab. - * Unless explicitly requested, a lookup on mount point should always - * return the 1st one. - */ -struct fstab { - int num_entries; - struct fstab_rec *recs; - char *fstab_filename; -}; - -struct fstab_rec { - char *blk_device; - char *mount_point; - char *fs_type; - unsigned long flags; - char *fs_options; - int fs_mgr_flags; - char *key_loc; - char* key_dir; - char *verity_loc; - long long length; - char *label; - int partnum; - int swap_prio; - int max_comp_streams; - unsigned int zram_size; - uint64_t reserved_size; - unsigned int file_contents_mode; - unsigned int file_names_mode; - unsigned int erase_blk_size; - unsigned int logical_blk_size; -}; - // Callback function for verity status typedef void (*fs_mgr_verity_state_callback)(struct fstab_rec *fstab, const char *mount_point, int mode, int status); -struct fstab *fs_mgr_read_fstab_default(); -struct fstab *fs_mgr_read_fstab_dt(); -struct fstab *fs_mgr_read_fstab(const char *fstab_path); -void fs_mgr_free_fstab(struct fstab *fstab); - #define FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED 7 #define FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION 6 #define FS_MGR_MNTALL_DEV_FILE_ENCRYPTED 5 @@ -120,28 +77,6 @@ struct fstab_rec const* fs_mgr_get_crypt_entry(struct fstab const* fstab); void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_device, size_t size); bool fs_mgr_load_verity_state(int* mode); bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback); -int fs_mgr_add_entry(struct fstab *fstab, - const char *mount_point, const char *fs_type, - const char *blk_device); -struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path); -int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab); -int fs_mgr_is_nonremovable(const struct fstab_rec *fstab); -int fs_mgr_is_verified(const struct fstab_rec *fstab); -int fs_mgr_is_verifyatboot(const struct fstab_rec *fstab); -int fs_mgr_is_avb(const struct fstab_rec *fstab); -int fs_mgr_is_encryptable(const struct fstab_rec *fstab); -int fs_mgr_is_file_encrypted(const struct fstab_rec *fstab); -void fs_mgr_get_file_encryption_modes(const struct fstab_rec *fstab, - const char **contents_mode_ret, - const char **filenames_mode_ret); -int fs_mgr_is_convertible_to_fbe(const struct fstab_rec *fstab); -int fs_mgr_is_noemulatedsd(const struct fstab_rec *fstab); -int fs_mgr_is_notrim(struct fstab_rec *fstab); -int fs_mgr_is_formattable(struct fstab_rec *fstab); -int fs_mgr_is_slotselect(struct fstab_rec *fstab); -int fs_mgr_is_nofail(struct fstab_rec *fstab); -int fs_mgr_is_latemount(struct fstab_rec *fstab); -int fs_mgr_is_quota(struct fstab_rec *fstab); int fs_mgr_swapon_all(struct fstab *fstab); int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer); @@ -154,10 +89,4 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev); __END_DECLS -// C++ only functions -// TODO: move this into separate header files under include/fs_mgr/*.h -#ifdef __cplusplus -std::string fs_mgr_get_slot_suffix(); -#endif - #endif /* __CORE_FS_MGR_H */ diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h new file mode 100644 index 000000000..d7cbfe1b1 --- /dev/null +++ b/fs_mgr/include_fstab/fstab/fstab.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CORE_FS_TAB_H +#define __CORE_FS_TAB_H + +#include +#include +#include +#include + +// C++ only headers +// TODO: move this into separate header files under include/fs_mgr/*.h +#ifdef __cplusplus +#include +#endif + +__BEGIN_DECLS + +/* + * The entries must be kept in the same order as they were seen in the fstab. + * Unless explicitly requested, a lookup on mount point should always + * return the 1st one. + */ +struct fstab { + int num_entries; + struct fstab_rec* recs; + char* fstab_filename; +}; + +struct fstab_rec { + char* blk_device; + char* mount_point; + char* fs_type; + unsigned long flags; + char* fs_options; + int fs_mgr_flags; + char* key_loc; + char* key_dir; + char* verity_loc; + long long length; + char* label; + int partnum; + int swap_prio; + int max_comp_streams; + unsigned int zram_size; + uint64_t reserved_size; + unsigned int file_contents_mode; + unsigned int file_names_mode; + unsigned int erase_blk_size; + unsigned int logical_blk_size; +}; + +struct fstab* fs_mgr_read_fstab_default(); +struct fstab* fs_mgr_read_fstab_dt(); +struct fstab* fs_mgr_read_fstab(const char* fstab_path); +void fs_mgr_free_fstab(struct fstab* fstab); + +int fs_mgr_add_entry(struct fstab* fstab, const char* mount_point, const char* fs_type, + const char* blk_device); +struct fstab_rec* fs_mgr_get_entry_for_mount_point(struct fstab* fstab, const char* path); +int fs_mgr_is_voldmanaged(const struct fstab_rec* fstab); +int fs_mgr_is_nonremovable(const struct fstab_rec* fstab); +int fs_mgr_is_verified(const struct fstab_rec* fstab); +int fs_mgr_is_verifyatboot(const struct fstab_rec* fstab); +int fs_mgr_is_avb(const struct fstab_rec* fstab); +int fs_mgr_is_encryptable(const struct fstab_rec* fstab); +int fs_mgr_is_file_encrypted(const struct fstab_rec* fstab); +void fs_mgr_get_file_encryption_modes(const struct fstab_rec* fstab, const char** contents_mode_ret, + const char** filenames_mode_ret); +int fs_mgr_is_convertible_to_fbe(const struct fstab_rec* fstab); +int fs_mgr_is_noemulatedsd(const struct fstab_rec* fstab); +int fs_mgr_is_notrim(struct fstab_rec* fstab); +int fs_mgr_is_formattable(struct fstab_rec* fstab); +int fs_mgr_is_slotselect(struct fstab_rec* fstab); +int fs_mgr_is_nofail(struct fstab_rec* fstab); +int fs_mgr_is_latemount(struct fstab_rec* fstab); +int fs_mgr_is_quota(struct fstab_rec* fstab); + +__END_DECLS + +// C++ only functions +// TODO: move this into separate header files under include/fs_mgr/*.h +#ifdef __cplusplus +std::string fs_mgr_get_slot_suffix(); +#endif + +#endif /* __CORE_FS_TAB_H */ From 9890f89ca2ec281709da9a002ac4dca163d27aa5 Mon Sep 17 00:00:00 2001 From: Pavel Grafov Date: Wed, 28 Jun 2017 19:03:58 +0100 Subject: [PATCH 013/129] Don't look up parent user SID. This is a revert of http://ag/741442 Every user now has their own SID, so there is no need to look up profile parent anymore. Bug: 38259874 Test: manual, using ConfirmCredential sample app in work profile. Test: manual, making sure keys survive N->O-MR1 upgrade. Change-Id: Ib2f52baeb7c5bfeec95431fccfd6ddd537019954 --- gatekeeperd/Android.mk | 3 +- gatekeeperd/IUserManager.cpp | 57 ------------------------------------ gatekeeperd/IUserManager.h | 46 ----------------------------- gatekeeperd/gatekeeperd.cpp | 19 +----------- 4 files changed, 2 insertions(+), 123 deletions(-) delete mode 100644 gatekeeperd/IUserManager.cpp delete mode 100644 gatekeeperd/IUserManager.h diff --git a/gatekeeperd/Android.mk b/gatekeeperd/Android.mk index 0dfd9d8a9..28f0b07ab 100644 --- a/gatekeeperd/Android.mk +++ b/gatekeeperd/Android.mk @@ -21,8 +21,7 @@ LOCAL_CFLAGS := -Wall -Wextra -Werror -Wunused LOCAL_SRC_FILES := \ SoftGateKeeperDevice.cpp \ IGateKeeperService.cpp \ - gatekeeperd.cpp \ - IUserManager.cpp + gatekeeperd.cpp LOCAL_MODULE := gatekeeperd LOCAL_SHARED_LIBRARIES := \ diff --git a/gatekeeperd/IUserManager.cpp b/gatekeeperd/IUserManager.cpp deleted file mode 100644 index 8167d1919..000000000 --- a/gatekeeperd/IUserManager.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "IUserManager" -#include -#include -#include -#include - -#include "IUserManager.h" - -namespace android { - -class BpUserManager : public BpInterface -{ -public: - explicit BpUserManager(const sp& impl) : - BpInterface(impl) { - } - virtual int32_t getCredentialOwnerProfile(int32_t user_id) { - Parcel data, reply; - data.writeInterfaceToken(IUserManager::getInterfaceDescriptor()); - data.writeInt32(user_id); - status_t rc = remote()->transact(GET_CREDENTIAL_OWNER_PROFILE, data, &reply, 0); - if (rc != NO_ERROR) { - ALOGE("%s: failed (%d)\n", __func__, rc); - return -1; - } - - int32_t exception = reply.readExceptionCode(); - if (exception != 0) { - ALOGE("%s: got exception (%d)\n", __func__, exception); - return -1; - } - - return reply.readInt32(); - } - -}; - -IMPLEMENT_META_INTERFACE(UserManager, "android.os.IUserManager"); - -}; // namespace android - diff --git a/gatekeeperd/IUserManager.h b/gatekeeperd/IUserManager.h deleted file mode 100644 index 640e9b511..000000000 --- a/gatekeeperd/IUserManager.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef IUSERMANAGER_H_ -#define IUSERMANAGER_H_ - -#include -#include -#include -#include -#include - -namespace android { - -/* -* Communication channel to UserManager -*/ -class IUserManager : public IInterface { - public: - // must be kept in sync with IUserManager.aidl - enum { - GET_CREDENTIAL_OWNER_PROFILE = IBinder::FIRST_CALL_TRANSACTION + 0, - }; - - virtual int32_t getCredentialOwnerProfile(int32_t user_id) = 0; - - DECLARE_META_INTERFACE(UserManager); -}; - -}; // namespace android - -#endif // IUSERMANAGER_H_ - diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp index c6369f9ed..184c6d222 100644 --- a/gatekeeperd/gatekeeperd.cpp +++ b/gatekeeperd/gatekeeperd.cpp @@ -37,7 +37,6 @@ #include #include "SoftGateKeeperDevice.h" -#include "IUserManager.h" #include #include @@ -334,23 +333,7 @@ public: return ret; } - virtual uint64_t getSecureUserId(uint32_t uid) { - uint64_t sid = read_sid(uid); - if (sid == 0) { - // might be a work profile, look up the parent - sp sm = defaultServiceManager(); - sp binder = sm->getService(String16("user")); - sp um = interface_cast(binder); - int32_t parent = um->getCredentialOwnerProfile(uid); - if (parent < 0) { - return 0; - } else if (parent != (int32_t) uid) { - return read_sid(parent); - } - } - return sid; - - } + virtual uint64_t getSecureUserId(uint32_t uid) { return read_sid(uid); } virtual void clearSecureUserId(uint32_t uid) { IPCThreadState* ipc = IPCThreadState::self(); From 653d49a2451b9d7ec5746c88a54a5e54fa42742c Mon Sep 17 00:00:00 2001 From: nickrose Date: Mon, 10 Jul 2017 11:10:19 -0700 Subject: [PATCH 014/129] Add logd CTS tests to VTS Follow-up to Change-Id: Id52ac1639447276171006c33bdfa7b4e6c874745 Test: make vts Change-Id: Ibeb5082439ada49a6eccd6fb699e466ca71730c9 --- liblog/tests/Android.mk | 2 +- logd/tests/Android.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk index ab964295c..91044ab75 100644 --- a/liblog/tests/Android.mk +++ b/liblog/tests/Android.mk @@ -89,7 +89,7 @@ LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64 LOCAL_SHARED_LIBRARIES := liblog libcutils libbase LOCAL_STATIC_LIBRARIES := libgtest libgtest_main -LOCAL_COMPATIBILITY_SUITE := cts +LOCAL_COMPATIBILITY_SUITE := cts vts LOCAL_CTS_TEST_PACKAGE := android.core.liblog include $(BUILD_CTS_EXECUTABLE) diff --git a/logd/tests/Android.mk b/logd/tests/Android.mk index 191567721..a0875ea99 100644 --- a/logd/tests/Android.mk +++ b/logd/tests/Android.mk @@ -63,7 +63,7 @@ LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64 LOCAL_SHARED_LIBRARIES := libbase libcutils liblog libselinux LOCAL_STATIC_LIBRARIES := libgtest libgtest_main -LOCAL_COMPATIBILITY_SUITE := cts +LOCAL_COMPATIBILITY_SUITE := cts vts LOCAL_CTS_TEST_PACKAGE := android.core.logd include $(BUILD_CTS_EXECUTABLE) From 1b13eea81f95a1d5aed1ef3c9b1f9ed52b9c0f8a Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Mon, 10 Jul 2017 16:05:51 -0700 Subject: [PATCH 015/129] Added libhealthd-headers. Test: use with BOARD_VNDK_VERSION=current Change-Id: Icece8e543307498f349d7f4914ec5be6d97e98fc --- healthd/Android.bp | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 healthd/Android.bp diff --git a/healthd/Android.bp b/healthd/Android.bp new file mode 100644 index 000000000..56f5148ca --- /dev/null +++ b/healthd/Android.bp @@ -0,0 +1,7 @@ +cc_library_headers { + name: "libhealthd_headers", + vendor_available: true, + export_include_dirs: ["include"], + header_libs: ["libbatteryservice_headers"], + export_header_lib_headers: ["libbatteryservice_headers"], +} From 42b485cc538217fa127996a340229f76b7c4031b Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Mon, 10 Jul 2017 16:40:36 -0700 Subject: [PATCH 016/129] Add vendor_available to liblog_headers. Renamed NDK headers to "liblog_ndk_headers" (these names aren't used anywhere). libutils_headers now properly export liblog_headers. Test: with BOARD_VNDK_VERSION=current Change-Id: I3a85385f588b84393c57fd6d1bcac620f708f0f1 --- liblog/Android.bp | 23 +++++++++++++++++++++-- libutils/Android.bp | 5 ++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/liblog/Android.bp b/liblog/Android.bp index e74aa8283..b98d18ff6 100644 --- a/liblog/Android.bp +++ b/liblog/Android.bp @@ -42,6 +42,24 @@ liblog_target_sources = [ "logd_writer.c", ] +cc_library_headers { + name: "liblog_headers", + host_supported: true, + vendor_available: true, + export_include_dirs: ["include"], + target: { + windows: { + enabled: true, + }, + linux_bionic: { + enabled: true, + }, + vendor: { + export_include_dirs: ["include_vndk"], + }, + }, +} + // Shared and static library for host and device // ======================================================== cc_library { @@ -81,7 +99,8 @@ cc_library { }, }, - export_include_dirs: ["include"], + header_libs: ["liblog_headers"], + export_header_lib_headers: ["liblog_headers"], cflags: [ "-Werror", @@ -100,7 +119,7 @@ cc_library { } ndk_headers { - name: "liblog_headers", + name: "liblog_ndk_headers", from: "include/android", to: "android", srcs: ["include/android/log.h"], diff --git a/libutils/Android.bp b/libutils/Android.bp index ef16d56aa..cf28f6efa 100644 --- a/libutils/Android.bp +++ b/libutils/Android.bp @@ -18,10 +18,12 @@ cc_library_headers { host_supported: true, header_libs: [ + "liblog_headers", "libsystem_headers", "libcutils_headers" ], export_header_lib_headers: [ + "liblog_headers", "libsystem_headers", "libcutils_headers" ], @@ -82,9 +84,6 @@ cc_library { shared_libs: [ "liblog", ], - export_shared_lib_headers: [ - "liblog", - ], arch: { mips: { From fff6f75fc1de2963254271d7d254e53ae187cada Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Tue, 11 Jul 2017 14:06:16 +0900 Subject: [PATCH 017/129] Use the legacy linker namespace configs when target is sanitized The new linker namespace config causes problem when the target is sanitized: vendor libs which are loaded in the sphal namespace can't link against to libclang_rt* libs which are in /system/lib directory because the directory is not allowed for sphal namsapce. Long-term solution would be installing libclang_rt* to both /system/lib and /vendor/lib so that vendor libs can link against to the one in /vendor/lib. Until the work is done, let's just disable the new linker namespace config when the target is to be sanitized. Bug: 63535130 Test: make SANITIZE_TARGET=integer_overflow SANITIZE_TARGET_DIAG=integer_overflow builds and boots to the UI Change-Id: I6afb69885aaa3d25e554b9ca699a572248bfc50a --- rootdir/Android.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootdir/Android.mk b/rootdir/Android.mk index 2e5575fd0..046557eb2 100644 --- a/rootdir/Android.mk +++ b/rootdir/Android.mk @@ -194,7 +194,7 @@ bcp_dep := include $(CLEAR_VARS) LOCAL_MODULE := ld.config.txt -ifeq ($(PRODUCT_FULL_TREBLE),true) +ifeq ($(PRODUCT_FULL_TREBLE)|$(SANITIZE_TARGET),true|) LOCAL_SRC_FILES := etc/ld.config.txt else LOCAL_SRC_FILES := etc/ld.config.legacy.txt From 926acb637fe8dccbff33e9d2063e039e62a3ba3a Mon Sep 17 00:00:00 2001 From: Daichi Hirono Date: Fri, 14 Jul 2017 16:41:45 +0900 Subject: [PATCH 018/129] Remove ScopedLogSeverity for debugging The ScopedLogSeverity was added to observe APCT failures, which turned out to be a compiler optimization error. Bug: 62429763 Test: None Change-Id: Ibb45d018d8eaf4b29cb417da80ae5f0b000dda8e --- libappfuse/FuseBridgeLoop.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc index 5a897a472..8b0c53eb2 100644 --- a/libappfuse/FuseBridgeLoop.cc +++ b/libappfuse/FuseBridgeLoop.cc @@ -173,9 +173,6 @@ class FuseBridgeEntry { } FuseBridgeState ReadFromDevice(FuseBridgeLoopCallback* callback) { - // To observe APCT failures. - base::ScopedLogSeverity log_severity(base::VERBOSE); - LOG(VERBOSE) << "ReadFromDevice"; if (!buffer_.request.Read(device_fd_)) { return FuseBridgeState::kClosing; From 8847c62579282cd67a80d7354ccf26064aaed4e5 Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Mon, 17 Jul 2017 15:06:11 -0700 Subject: [PATCH 019/129] storaged: record userdata space utilization Update disk space utilization together with diskstats since we will use free space size to co-relate disk performance. Bug: 63629306 Change-Id: I4e5694aaff3b71aa56db451f1bc92ccfb07e5086 --- storaged/include/storaged.h | 3 ++ storaged/include/storaged_info.h | 37 +++++++++++--------- storaged/main.cpp | 2 +- storaged/storaged.cpp | 7 ++++ storaged/storaged_info.cpp | 58 +++++++++++++++++++++++--------- 5 files changed, 76 insertions(+), 31 deletions(-) diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h index 514798bff..fa6840638 100644 --- a/storaged/include/storaged.h +++ b/storaged/include/storaged.h @@ -256,6 +256,7 @@ private: uid_monitor mUidm; time_t mStarttime; sp battery_properties; + std::unique_ptr storage_info; public: storaged_t(void); ~storaged_t() {} @@ -285,6 +286,8 @@ public: void init_battery_service(); virtual void batteryPropertiesChanged(struct BatteryProperties props); void binderDied(const wp& who); + + void report_storage_info(); }; // Eventlog tag diff --git a/storaged/include/storaged_info.h b/storaged/include/storaged_info.h index 913c814ac..7d04c7a0d 100644 --- a/storaged/include/storaged_info.h +++ b/storaged/include/storaged_info.h @@ -27,39 +27,46 @@ using namespace std; class storage_info_t { protected: FRIEND_TEST(storaged_test, storage_info_t); + // emmc lifetime uint16_t eol; // pre-eol (end of life) information uint16_t lifetime_a; // device life time estimation (type A) uint16_t lifetime_b; // device life time estimation (type B) string version; // version string + // free space + const string userdata_path = "/data"; + uint64_t userdata_total_kb; + uint64_t userdata_free_kb; + + storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0), + userdata_total_kb(0), userdata_free_kb(0) {} void publish(); + storage_info_t* s_info; public: - storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0) {} + static storage_info_t* get_storage_info(); virtual ~storage_info_t() {} - virtual bool report() = 0; + virtual void report() {}; + void refresh(); }; class emmc_info_t : public storage_info_t { private: - const string emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/"; - const string emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd"; - const char* emmc_ver_str[9] = { - "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0", "5.1" - }; -public: - virtual ~emmc_info_t() {} - bool report(); bool report_sysfs(); bool report_debugfs(); +public: + static const string emmc_sysfs; + static const string emmc_debugfs; + static const char* emmc_ver_str[]; + + virtual ~emmc_info_t() {} + virtual void report(); }; class ufs_info_t : public storage_info_t { -private: - const string health_file = "/sys/devices/soc/624000.ufshc/health"; public: + static const string health_file; + virtual ~ufs_info_t() {} - bool report(); + virtual void report(); }; -void report_storage_health(); - #endif /* _STORAGED_INFO_H_ */ diff --git a/storaged/main.cpp b/storaged/main.cpp index 4d1e43014..6b82904d2 100644 --- a/storaged/main.cpp +++ b/storaged/main.cpp @@ -49,6 +49,7 @@ void* storaged_main(void* /* unused */) { storaged = new storaged_t(); storaged->init_battery_service(); + storaged->report_storage_info(); LOG_TO(SYSTEM, INFO) << "storaged: Start"; @@ -113,7 +114,6 @@ int main(int argc, char** argv) { } if (flag_main_service) { // start main thread - report_storage_health(); // Start the main thread of storaged pthread_t storaged_main_thread; errno = pthread_create(&storaged_main_thread, NULL, storaged_main, NULL); diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp index 54d429cd8..06afea693 100644 --- a/storaged/storaged.cpp +++ b/storaged/storaged.cpp @@ -200,6 +200,10 @@ void storaged_t::binderDied(const wp& who) { } } +void storaged_t::report_storage_info() { + storage_info->report(); +} + /* storaged_t */ storaged_t::storaged_t(void) { if (access(MMC_DISK_STATS_PATH, R_OK) < 0 && access(SDA_DISK_STATS_PATH, R_OK) < 0) { @@ -222,6 +226,8 @@ storaged_t::storaged_t(void) { mConfig.periodic_chores_interval_uid_io = property_get_int32("ro.storaged.uid_io.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO); + storage_info.reset(storage_info_t::get_storage_info()); + mStarttime = time(NULL); } @@ -229,6 +235,7 @@ void storaged_t::event(void) { if (mConfig.diskstats_available) { mDiskStats.update(); mDsm.update(); + storage_info->refresh(); if (mTimer && (mTimer % mConfig.periodic_chores_interval_disk_stats_publish) == 0) { mDiskStats.publish(); } diff --git a/storaged/storaged_info.cpp b/storaged/storaged_info.cpp index 434bd74ae..b5fb13e0c 100644 --- a/storaged/storaged_info.cpp +++ b/storaged/storaged_info.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -30,13 +31,42 @@ using namespace std; using namespace android::base; -void report_storage_health() -{ - emmc_info_t mmc; - ufs_info_t ufs; +const string emmc_info_t::emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/"; +const string emmc_info_t::emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd"; +const char* emmc_info_t::emmc_ver_str[9] = { + "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0", "5.1" +}; - mmc.report(); - ufs.report(); +const string ufs_info_t::health_file = "/sys/devices/soc/624000.ufshc/health"; + +static bool FileExists(const std::string& filename) +{ + struct stat buffer; + return stat(filename.c_str(), &buffer) == 0; +} + +storage_info_t* storage_info_t::get_storage_info() +{ + if (FileExists(emmc_info_t::emmc_sysfs) || + FileExists(emmc_info_t::emmc_debugfs)) { + return new emmc_info_t; + } + if (FileExists(ufs_info_t::health_file)) { + return new ufs_info_t; + } + return new storage_info_t; +} + +void storage_info_t::refresh() +{ + struct statvfs buf; + if (statvfs(userdata_path.c_str(), &buf) != 0) { + PLOG_TO(SYSTEM, WARNING) << "Failed to get userdata info"; + return; + } + + userdata_total_kb = buf.f_bsize * buf.f_blocks >> 10; + userdata_free_kb = buf.f_bfree * buf.f_blocks >> 10; } void storage_info_t::publish() @@ -46,13 +76,12 @@ void storage_info_t::publish() << LOG_ID_EVENTS; } -bool emmc_info_t::report() +void emmc_info_t::report() { if (!report_sysfs() && !report_debugfs()) - return false; + return; publish(); - return true; } bool emmc_info_t::report_sysfs() @@ -136,21 +165,21 @@ bool emmc_info_t::report_debugfs() return true; } -bool ufs_info_t::report() +void ufs_info_t::report() { string buffer; if (!ReadFileToString(health_file, &buffer)) { - return false; + return; } vector lines = Split(buffer, "\n"); if (lines.empty()) { - return false; + return; } char rev[8]; if (sscanf(lines[0].c_str(), "ufs version: 0x%7s\n", rev) < 1) { - return false; + return; } version = "ufs " + string(rev); @@ -175,10 +204,9 @@ bool ufs_info_t::report() } if (eol == 0 || (lifetime_a == 0 && lifetime_b == 0)) { - return false; + return; } publish(); - return true; } From 79b1a3027b4c1b5f86a68c7a5bf1f1d2e22494d8 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Mon, 17 Jul 2017 16:25:59 -0700 Subject: [PATCH 020/129] Add sys/cdefs.h to log/log_main.h. for liblog.vendor. __ANDROID_API__ is __ANDROID_API_FUTURE__ with BOARD_VNDK_VERSION=current, so we need it defined. Bug: 33241851 Test: BOARD_VNDK_VERSION=current m libgui.vendor (that uses liblog.vendor) Change-Id: I340ec048094c027828f516d891250651e0c88eea --- liblog/include/log/log_main.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/liblog/include/log/log_main.h b/liblog/include/log/log_main.h index da1615828..68c2e9af6 100644 --- a/liblog/include/log/log_main.h +++ b/liblog/include/log/log_main.h @@ -18,10 +18,9 @@ #define _LIBS_LOG_LOG_MAIN_H #include +#include -#ifdef __cplusplus -extern "C" { -#endif +__BEGIN_DECLS /* * Normally we strip the effects of ALOGV (VERBOSE messages), @@ -385,8 +384,6 @@ int __android_log_is_loggable_len(int prio, const char* tag, size_t len, #pragma clang diagnostic pop #endif -#ifdef __cplusplus -} -#endif +__END_DECLS #endif /* _LIBS_LOG_LOG_MAIN_H */ From d14d7c14cbe297614bf99dae9bf50b1fc342c44e Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Tue, 18 Apr 2017 18:19:12 -0700 Subject: [PATCH 021/129] fastboot: call mke2fs tools to generate ext4 image Set MKE2FS_CONFIG to empty to use mke2fs default configs Test: fastboot --wipe-and-use-fbe Bug: 35219933 Change-Id: Ibc97bb125899e1f1fe820d53709fdb2ab291c171 --- fastboot/Android.mk | 1 + fastboot/fs.cpp | 86 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/fastboot/Android.mk b/fastboot/Android.mk index 80def732c..0b656aaa7 100644 --- a/fastboot/Android.mk +++ b/fastboot/Android.mk @@ -40,6 +40,7 @@ LOCAL_MODULE := fastboot LOCAL_MODULE_TAGS := debug LOCAL_MODULE_HOST_OS := darwin linux windows LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code +LOCAL_REQUIRED_MODULES := mke2fs e2fsdroid LOCAL_SRC_FILES_linux := usb_linux.cpp LOCAL_STATIC_LIBRARIES_linux := libselinux diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp index 99ca7dd81..f3c000eb7 100644 --- a/fastboot/fs.cpp +++ b/fastboot/fs.cpp @@ -10,14 +10,22 @@ #include #include #include +#ifndef WIN32 +#include +#endif #include +#include +#include +#include #include #include #include +using android::base::StringPrintf; using android::base::unique_fd; +#ifdef WIN32 static int generate_ext4_image(const char* fileName, long long partSize, const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize) { @@ -34,6 +42,84 @@ static int generate_ext4_image(const char* fileName, long long partSize, const s } return 0; } +#else +static int exec_e2fs_cmd(const char* path, char* const argv[]) { + int status; + pid_t child; + if ((child = fork()) == 0) { + setenv("MKE2FS_CONFIG", "", 1); + execvp(path, argv); + _exit(EXIT_FAILURE); + } + if (child < 0) { + fprintf(stderr, "%s failed with fork %s\n", path, strerror(errno)); + return -1; + } + if (TEMP_FAILURE_RETRY(waitpid(child, &status, 0)) == -1) { + fprintf(stderr, "%s failed with waitpid %s\n", path, strerror(errno)); + return -1; + } + int ret = -1; + if (WIFEXITED(status)) { + ret = WEXITSTATUS(status); + if (ret != 0) { + fprintf(stderr, "%s failed with status %d\n", path, ret); + } + } + return ret; +} + +static int generate_ext4_image(const char* fileName, long long partSize, + const std::string& initial_dir, unsigned eraseBlkSize, + unsigned logicalBlkSize) { + static constexpr int block_size = 4096; + const std::string exec_dir = android::base::GetExecutableDirectory(); + + const std::string mke2fs_path = exec_dir + "/mke2fs"; + std::vector mke2fs_args = {mke2fs_path.c_str(), "-t", "ext4", "-b"}; + + std::string block_size_str = std::to_string(block_size); + mke2fs_args.push_back(block_size_str.c_str()); + + std::string ext_attr = "android_sparse"; + if (eraseBlkSize != 0 && logicalBlkSize != 0) { + int raid_stride = logicalBlkSize / block_size; + int raid_stripe_width = eraseBlkSize / block_size; + // stride should be the max of 8kb and logical block size + if (logicalBlkSize != 0 && logicalBlkSize < 8192) raid_stride = 8192 / block_size; + ext_attr += StringPrintf(",stride=%d,stripe-width=%d", raid_stride, raid_stripe_width); + } + mke2fs_args.push_back("-E"); + mke2fs_args.push_back(ext_attr.c_str()); + mke2fs_args.push_back(fileName); + + std::string size_str = std::to_string(partSize / block_size); + mke2fs_args.push_back(size_str.c_str()); + mke2fs_args.push_back(nullptr); + + int ret = exec_e2fs_cmd(mke2fs_args[0], const_cast(mke2fs_args.data())); + if (ret != 0) { + fprintf(stderr, "mke2fs failed: %d\n", ret); + return -1; + } + + if (initial_dir.empty()) { + return 0; + } + + const std::string e2fsdroid_path = exec_dir + "/e2fsdroid"; + std::vector e2fsdroid_args = {e2fsdroid_path.c_str(), "-f", initial_dir.c_str(), + fileName, nullptr}; + + ret = exec_e2fs_cmd(e2fsdroid_args[0], const_cast(e2fsdroid_args.data())); + if (ret != 0) { + fprintf(stderr, "e2fsdroid failed: %d\n", ret); + return -1; + } + + return 0; +} +#endif #ifdef USE_F2FS static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir, From 6ce78321a229083a4b7e06958232b2788886d193 Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Wed, 19 Jul 2017 15:19:16 -0700 Subject: [PATCH 022/129] fastboot: add mke2fs and e2fsdroid to build package Bug: 23686092 Bug: 63849632 Change-Id: Iff0d92b7174597d43ee646847888aedc2080052a --- fastboot/Android.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fastboot/Android.mk b/fastboot/Android.mk index 0b656aaa7..dd8bad9aa 100644 --- a/fastboot/Android.mk +++ b/fastboot/Android.mk @@ -86,6 +86,8 @@ LOCAL_SHARED_LIBRARIES := include $(BUILD_HOST_EXECUTABLE) my_dist_files := $(LOCAL_BUILT_MODULE) +my_dist_files += $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX) +my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid$(HOST_EXECUTABLE_SUFFIX) ifeq ($(HOST_OS),linux) my_dist_files += $(HOST_LIBRARY_PATH)/libf2fs_fmt_host_dyn$(HOST_SHLIB_SUFFIX) endif From 1d540dd0f44c1c7d40878f6a7bb447e85e6207ad Mon Sep 17 00:00:00 2001 From: Luke Song Date: Thu, 13 Jul 2017 15:10:35 -0700 Subject: [PATCH 023/129] healthd: restructure healthd_mode_charger Refactor drawing code into separate class, and allow for split screen drawing with offset. Cherry picked from commit 7f386dcab98b4a2827b5ffe29d7d3de7637841c0 Bug: 63541890 Test: Verify charging mode animation Change-Id: I6c089460f55b8c2f75f4aa3153a5736f6f434b51 --- healthd/Android.mk | 26 ++ healthd/healthd_draw.cpp | 195 +++++++++++++ healthd/healthd_draw.h | 75 +++++ healthd/healthd_mode_charger.cpp | 484 ++++++++----------------------- 4 files changed, 425 insertions(+), 355 deletions(-) create mode 100644 healthd/healthd_draw.cpp create mode 100644 healthd/healthd_draw.h diff --git a/healthd/Android.mk b/healthd/Android.mk index 8b5996442..6b14289e8 100644 --- a/healthd/Android.mk +++ b/healthd/Android.mk @@ -33,6 +33,30 @@ include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) +LOCAL_MODULE := libhealthd_draw + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) +LOCAL_STATIC_LIBRARIES := \ + libminui \ + libbase +LOCAL_SRC_FILES := healthd_draw.cpp + +ifneq ($(TARGET_HEALTHD_DRAW_SPLIT_SCREEN),) +LOCAL_CFLAGS += -DHEALTHD_DRAW_SPLIT_SCREEN=$(TARGET_HEALTHD_DRAW_SPLIT_SCREEN) +else +LOCAL_CFLAGS += -DHEALTHD_DRAW_SPLIT_SCREEN=0 +endif + +ifneq ($(TARGET_HEALTHD_DRAW_SPLIT_OFFSET),) +LOCAL_CFLAGS += -DHEALTHD_DRAW_SPLIT_OFFSET=$(TARGET_HEALTHD_DRAW_SPLIT_OFFSET) +else +LOCAL_CFLAGS += -DHEALTHD_DRAW_SPLIT_OFFSET=0 +endif + +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) + LOCAL_CFLAGS := -Werror ifeq ($(strip $(BOARD_CHARGER_DISABLE_INIT_BLANK)),true) LOCAL_CFLAGS += -DCHARGER_DISABLE_INIT_BLANK @@ -58,6 +82,7 @@ LOCAL_STATIC_LIBRARIES := \ libutils \ libbase \ libcutils \ + libhealthd_draw \ liblog \ libm \ libc \ @@ -101,6 +126,7 @@ endif LOCAL_STATIC_LIBRARIES := \ libhealthd_charger \ + libhealthd_draw \ libbatterymonitor \ libbase \ libutils \ diff --git a/healthd/healthd_draw.cpp b/healthd/healthd_draw.cpp new file mode 100644 index 000000000..ea3d991c0 --- /dev/null +++ b/healthd/healthd_draw.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "healthd_draw.h" + +#define LOGE(x...) KLOG_ERROR("charger", x); +#define LOGV(x...) KLOG_DEBUG("charger", x); + +HealthdDraw::HealthdDraw(animation* anim) + : kSplitScreen(HEALTHD_DRAW_SPLIT_SCREEN), + kSplitOffset(HEALTHD_DRAW_SPLIT_OFFSET) { + gr_init(); + gr_font_size(gr_sys_font(), &char_width_, &char_height_); + + screen_width_ = gr_fb_width() / (kSplitScreen ? 2 : 1); + screen_height_ = gr_fb_height(); + + int res; + if (!anim->text_clock.font_file.empty() && + (res = gr_init_font(anim->text_clock.font_file.c_str(), + &anim->text_clock.font)) < 0) { + LOGE("Could not load time font (%d)\n", res); + } + if (!anim->text_percent.font_file.empty() && + (res = gr_init_font(anim->text_percent.font_file.c_str(), + &anim->text_percent.font)) < 0) { + LOGE("Could not load percent font (%d)\n", res); + } +} + +HealthdDraw::~HealthdDraw() {} + +void HealthdDraw::redraw_screen(const animation* batt_anim, GRSurface* surf_unknown) { + clear_screen(); + + /* try to display *something* */ + if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0) + draw_unknown(surf_unknown); + else + draw_battery(batt_anim); + gr_flip(); +} + +void HealthdDraw::blank_screen(bool blank) { gr_fb_blank(blank); } + +void HealthdDraw::clear_screen(void) { + gr_color(0, 0, 0, 255); + gr_clear(); +} + +int HealthdDraw::draw_surface_centered(GRSurface* surface) { + int w = gr_get_width(surface); + int h = gr_get_height(surface); + int x = (screen_width_ - w) / 2 + kSplitOffset; + int y = (screen_height_ - h) / 2; + + LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); + gr_blit(surface, 0, 0, w, h, x, y); + if (kSplitScreen) { + x += screen_width_ - 2 * kSplitOffset; + LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); + gr_blit(surface, 0, 0, w, h, x, y); + } + + return y + h; +} + +int HealthdDraw::draw_text(const GRFont* font, int x, int y, const char* str) { + int str_len_px = gr_measure(font, str); + + if (x < 0) x = (screen_width_ - str_len_px) / 2; + if (y < 0) y = (screen_height_ - char_height_) / 2; + gr_text(font, x + kSplitOffset, y, str, false /* bold */); + if (kSplitScreen) + gr_text(font, x - kSplitOffset + screen_width_, y, str, false /* bold */); + + return y + char_height_; +} + +void HealthdDraw::determine_xy(const animation::text_field& field, + const int length, int* x, int* y) { + *x = field.pos_x; + + int str_len_px = length * field.font->char_width; + if (field.pos_x == CENTER_VAL) { + *x = (screen_width_ - str_len_px) / 2; + } else if (field.pos_x >= 0) { + *x = field.pos_x; + } else { // position from max edge + *x = screen_width_ + field.pos_x - str_len_px - kSplitOffset; + } + + *y = field.pos_y; + + if (field.pos_y == CENTER_VAL) { + *y = (screen_height_ - field.font->char_height) / 2; + } else if (field.pos_y >= 0) { + *y = field.pos_y; + } else { // position from max edge + *y = screen_height_ + field.pos_y - field.font->char_height; + } +} + +void HealthdDraw::draw_clock(const animation* anim) { + static constexpr char CLOCK_FORMAT[] = "%H:%M"; + static constexpr int CLOCK_LENGTH = 6; + + const animation::text_field& field = anim->text_clock; + + if (field.font == nullptr || field.font->char_width == 0 || + field.font->char_height == 0) + return; + + time_t rawtime; + time(&rawtime); + tm* time_info = localtime(&rawtime); + + char clock_str[CLOCK_LENGTH]; + size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info); + if (length != CLOCK_LENGTH - 1) { + LOGE("Could not format time\n"); + return; + } + + int x, y; + determine_xy(field, length, &x, &y); + + LOGV("drawing clock %s %d %d\n", clock_str, x, y); + gr_color(field.color_r, field.color_g, field.color_b, field.color_a); + draw_text(field.font, x, y, clock_str); +} + +void HealthdDraw::draw_percent(const animation* anim) { + int cur_level = anim->cur_level; + if (anim->cur_status == BATTERY_STATUS_FULL) { + cur_level = 100; + } + + if (cur_level <= 0) return; + + const animation::text_field& field = anim->text_percent; + if (field.font == nullptr || field.font->char_width == 0 || + field.font->char_height == 0) { + return; + } + + std::string str = base::StringPrintf("%d%%", cur_level); + + int x, y; + determine_xy(field, str.size(), &x, &y); + + LOGV("drawing percent %s %d %d\n", str.c_str(), x, y); + gr_color(field.color_r, field.color_g, field.color_b, field.color_a); + draw_text(field.font, x, y, str.c_str()); +} + +void HealthdDraw::draw_battery(const animation* anim) { + const animation::frame& frame = anim->frames[anim->cur_frame]; + + if (anim->num_frames != 0) { + draw_surface_centered(frame.surface); + LOGV("drawing frame #%d min_cap=%d time=%d\n", anim->cur_frame, + frame.min_level, frame.disp_time); + } + draw_clock(anim); + draw_percent(anim); +} + +void HealthdDraw::draw_unknown(GRSurface* surf_unknown) { + int y; + if (surf_unknown) { + draw_surface_centered(surf_unknown); + } else { + gr_color(0xa4, 0xc6, 0x39, 255); + y = draw_text(gr_sys_font(), -1, -1, "Charging!"); + draw_text(gr_sys_font(), -1, y + 25, "?\?/100"); + } +} diff --git a/healthd/healthd_draw.h b/healthd/healthd_draw.h new file mode 100644 index 000000000..6a6ba7655 --- /dev/null +++ b/healthd/healthd_draw.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HEALTHD_DRAW_H +#define HEALTHD_DRAW_H + +#include +#include + +#include "animation.h" + +using namespace android; + +class HealthdDraw { + public: + // Configures font using given animation. + HealthdDraw(animation* anim); + virtual ~HealthdDraw(); + + // Redraws screen. + void redraw_screen(const animation* batt_anim, GRSurface* surf_unknown); + + // Blanks screen if true, unblanks if false. + virtual void blank_screen(bool blank); + + protected: + virtual void clear_screen(); + + // returns the last y-offset of where the surface ends. + virtual int draw_surface_centered(GRSurface* surface); + // Negative x or y coordinates center text. + virtual int draw_text(const GRFont* font, int x, int y, const char* str); + + // Negative x or y coordinates position the text away from the opposite edge + // that positive ones do. + virtual void determine_xy(const animation::text_field& field, + const int length, int* x, int* y); + + // Draws battery animation, if it exists. + virtual void draw_battery(const animation* anim); + // Draws clock text, if animation contains text_field data. + virtual void draw_clock(const animation* anim); + // Draws battery percentage text if animation contains text_field data. + virtual void draw_percent(const animation* anim); + // Draws charger->surf_unknown or basic text. + virtual void draw_unknown(GRSurface* surf_unknown); + + // Pixel sizes of characters for default font. + int char_width_; + int char_height_; + + // Width and height of screen in pixels. + int screen_width_; + int screen_height_; + + // Device screen is split vertically. + const bool kSplitScreen; + // Pixels to offset graphics towards center split. + const int kSplitOffset; +}; + +#endif // HEALTHD_DRAW_H diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp index c76762d37..6c6d73880 100644 --- a/healthd/healthd_mode_charger.cpp +++ b/healthd/healthd_mode_charger.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2013 The Android Open Source Project + * Copyright (C) 2011-2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -34,56 +33,54 @@ #include #include -#include -#include #include +#include -#include #include #include -#include #include -#include +#include #include #ifdef CHARGER_ENABLE_SUSPEND #include #endif -#include "animation.h" #include "AnimationParser.h" +#include "healthd_draw.h" #include using namespace android; -char *locale; +char* locale; #ifndef max -#define max(a,b) ((a) > (b) ? (a) : (b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef min -#define min(a,b) ((a) < (b) ? (a) : (b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) #endif -#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#define MSEC_PER_SEC (1000LL) -#define NSEC_PER_MSEC (1000000LL) +#define MSEC_PER_SEC (1000LL) +#define NSEC_PER_MSEC (1000000LL) -#define BATTERY_UNKNOWN_TIME (2 * MSEC_PER_SEC) -#define POWER_ON_KEY_TIME (2 * MSEC_PER_SEC) +#define BATTERY_UNKNOWN_TIME (2 * MSEC_PER_SEC) +#define POWER_ON_KEY_TIME (2 * MSEC_PER_SEC) #define UNPLUGGED_SHUTDOWN_TIME (10 * MSEC_PER_SEC) -#define LAST_KMSG_MAX_SZ (32 * 1024) +#define LAST_KMSG_MAX_SZ (32 * 1024) -#define LOGE(x...) do { KLOG_ERROR("charger", x); } while (0) -#define LOGW(x...) do { KLOG_WARNING("charger", x); } while (0) -#define LOGV(x...) do { KLOG_DEBUG("charger", x); } while (0) +#define LOGE(x...) KLOG_ERROR("charger", x); +#define LOGW(x...) KLOG_WARNING("charger", x); +#define LOGV(x...) KLOG_DEBUG("charger", x); -static constexpr const char* animation_desc_path = "/res/values/charger/animation.txt"; +static constexpr const char* animation_desc_path = + "/res/values/charger/animation.txt"; struct key_state { bool pending; @@ -98,34 +95,36 @@ struct charger { int64_t next_key_check; int64_t next_pwr_check; - struct key_state keys[KEY_MAX + 1]; + key_state keys[KEY_MAX + 1]; - struct animation *batt_anim; + animation* batt_anim; GRSurface* surf_unknown; int boot_min_cap; }; -static const struct animation BASE_ANIMATION = { - .text_clock = { - .pos_x = 0, - .pos_y = 0, +static const animation BASE_ANIMATION = { + .text_clock = + { + .pos_x = 0, + .pos_y = 0, - .color_r = 255, - .color_g = 255, - .color_b = 255, - .color_a = 255, + .color_r = 255, + .color_g = 255, + .color_b = 255, + .color_a = 255, - .font = nullptr, - }, - .text_percent = { - .pos_x = 0, - .pos_y = 0, + .font = nullptr, + }, + .text_percent = + { + .pos_x = 0, + .pos_y = 0, - .color_r = 255, - .color_g = 255, - .color_b = 255, - .color_a = 255, - }, + .color_r = 255, + .color_g = 255, + .color_b = 255, + .color_a = 255, + }, .run = false, @@ -141,8 +140,7 @@ static const struct animation BASE_ANIMATION = { .cur_status = BATTERY_STATUS_UNKNOWN, }; - -static struct animation::frame default_animation_frames[] = { +static animation::frame default_animation_frames[] = { { .disp_time = 750, .min_level = 0, @@ -181,35 +179,25 @@ static struct animation::frame default_animation_frames[] = { }, }; -static struct animation battery_animation = BASE_ANIMATION; +static animation battery_animation = BASE_ANIMATION; -static struct charger charger_state; -static struct healthd_config *healthd_config; -static struct android::BatteryProperties *batt_prop; -static int char_width; -static int char_height; -static bool minui_inited; +static charger charger_state; +static healthd_config* healthd_config; +static android::BatteryProperties* batt_prop; +static std::unique_ptr healthd_draw; /* current time in milliseconds */ -static int64_t curr_time_ms(void) -{ - struct timespec tm; +static int64_t curr_time_ms() { + timespec tm; clock_gettime(CLOCK_MONOTONIC, &tm); return tm.tv_sec * MSEC_PER_SEC + (tm.tv_nsec / NSEC_PER_MSEC); } -static void clear_screen(void) -{ - gr_color(0, 0, 0, 255); - gr_clear(); -} - #define MAX_KLOG_WRITE_BUF_SZ 256 -static void dump_last_kmsg(void) -{ - char *buf; - char *ptr; +static void dump_last_kmsg(void) { + char* buf; + char* ptr; unsigned sz = 0; int len; @@ -239,11 +227,10 @@ static void dump_last_kmsg(void) while (len > 0) { int cnt = min(len, MAX_KLOG_WRITE_BUF_SZ); char yoink; - char *nl; + char* nl; - nl = (char *)memrchr(ptr, '\n', cnt - 1); - if (nl) - cnt = nl - ptr + 1; + nl = (char*)memrchr(ptr, '\n', cnt - 1); + if (nl) cnt = nl - ptr + 1; yoink = ptr[cnt]; ptr[cnt] = '\0'; @@ -263,241 +250,59 @@ out: } #ifdef CHARGER_ENABLE_SUSPEND -static int request_suspend(bool enable) -{ +static int request_suspend(bool enable) { if (enable) return autosuspend_enable(); else return autosuspend_disable(); } #else -static int request_suspend(bool /*enable*/) -{ +static int request_suspend(bool /*enable*/) { return 0; } #endif -static int draw_text(const char *str, int x, int y) -{ - int str_len_px = gr_measure(gr_sys_font(), str); - - if (x < 0) - x = (gr_fb_width() - str_len_px) / 2; - if (y < 0) - y = (gr_fb_height() - char_height) / 2; - gr_text(gr_sys_font(), x, y, str, 0); - - return y + char_height; -} - -static void android_green(void) -{ - gr_color(0xa4, 0xc6, 0x39, 255); -} - -// Negative x or y coordinates position the text away from the opposite edge that positive ones do. -void determine_xy(const animation::text_field& field, const int length, int* x, int* y) -{ - *x = field.pos_x; - *y = field.pos_y; - - int str_len_px = length * field.font->char_width; - if (field.pos_x == CENTER_VAL) { - *x = (gr_fb_width() - str_len_px) / 2; - } else if (field.pos_x >= 0) { - *x = field.pos_x; - } else { // position from max edge - *x = gr_fb_width() + field.pos_x - str_len_px; - } - - if (field.pos_y == CENTER_VAL) { - *y = (gr_fb_height() - field.font->char_height) / 2; - } else if (field.pos_y >= 0) { - *y = field.pos_y; - } else { // position from max edge - *y = gr_fb_height() + field.pos_y - field.font->char_height; - } -} - -static void draw_clock(const animation& anim) -{ - static constexpr char CLOCK_FORMAT[] = "%H:%M"; - static constexpr int CLOCK_LENGTH = 6; - - const animation::text_field& field = anim.text_clock; - - if (field.font == nullptr || field.font->char_width == 0 || field.font->char_height == 0) return; - - time_t rawtime; - time(&rawtime); - struct tm* time_info = localtime(&rawtime); - - char clock_str[CLOCK_LENGTH]; - size_t length = strftime(clock_str, CLOCK_LENGTH, CLOCK_FORMAT, time_info); - if (length != CLOCK_LENGTH - 1) { - LOGE("Could not format time\n"); - return; - } - - int x, y; - determine_xy(field, length, &x, &y); - - LOGV("drawing clock %s %d %d\n", clock_str, x, y); - gr_color(field.color_r, field.color_g, field.color_b, field.color_a); - gr_text(field.font, x, y, clock_str, false); -} - -static void draw_percent(const animation& anim) -{ - int cur_level = anim.cur_level; - if (anim.cur_status == BATTERY_STATUS_FULL) { - cur_level = 100; - } - - if (cur_level <= 0) return; - - const animation::text_field& field = anim.text_percent; - if (field.font == nullptr || field.font->char_width == 0 || field.font->char_height == 0) { - return; - } - - std::string str = base::StringPrintf("%d%%", cur_level); - - int x, y; - determine_xy(field, str.size(), &x, &y); - - LOGV("drawing percent %s %d %d\n", str.c_str(), x, y); - gr_color(field.color_r, field.color_g, field.color_b, field.color_a); - gr_text(field.font, x, y, str.c_str(), false); -} - -/* returns the last y-offset of where the surface ends */ -static int draw_surface_centered(GRSurface* surface) -{ - int w; - int h; - int x; - int y; - - w = gr_get_width(surface); - h = gr_get_height(surface); - x = (gr_fb_width() - w) / 2 ; - y = (gr_fb_height() - h) / 2 ; - - LOGV("drawing surface %dx%d+%d+%d\n", w, h, x, y); - gr_blit(surface, 0, 0, w, h, x, y); - return y + h; -} - -static void draw_unknown(struct charger *charger) -{ - int y; - if (charger->surf_unknown) { - draw_surface_centered(charger->surf_unknown); - } else { - android_green(); - y = draw_text("Charging!", -1, -1); - draw_text("?\?/100", -1, y + 25); - } -} - -static void draw_battery(const struct charger* charger) -{ - const struct animation& anim = *charger->batt_anim; - const struct animation::frame& frame = anim.frames[anim.cur_frame]; - - if (anim.num_frames != 0) { - draw_surface_centered(frame.surface); - LOGV("drawing frame #%d min_cap=%d time=%d\n", - anim.cur_frame, frame.min_level, - frame.disp_time); - } - draw_clock(anim); - draw_percent(anim); -} - -static void redraw_screen(struct charger *charger) -{ - struct animation *batt_anim = charger->batt_anim; - - clear_screen(); - - /* try to display *something* */ - if (batt_anim->cur_level < 0 || batt_anim->num_frames == 0) - draw_unknown(charger); - else - draw_battery(charger); - gr_flip(); -} - -static void kick_animation(struct animation *anim) -{ +static void kick_animation(animation* anim) { anim->run = true; } -static void reset_animation(struct animation *anim) -{ +static void reset_animation(animation* anim) { anim->cur_cycle = 0; anim->cur_frame = 0; anim->run = false; } -static void init_status_display(struct animation* anim) -{ - int res; - - if (!anim->text_clock.font_file.empty()) { - if ((res = - gr_init_font(anim->text_clock.font_file.c_str(), &anim->text_clock.font)) < 0) { - LOGE("Could not load time font (%d)\n", res); - } - } - - if (!anim->text_percent.font_file.empty()) { - if ((res = - gr_init_font(anim->text_percent.font_file.c_str(), &anim->text_percent.font)) < 0) { - LOGE("Could not load percent font (%d)\n", res); - } - } -} - -static void update_screen_state(struct charger *charger, int64_t now) -{ - struct animation *batt_anim = charger->batt_anim; +static void update_screen_state(charger* charger, int64_t now) { + animation* batt_anim = charger->batt_anim; int disp_time; if (!batt_anim->run || now < charger->next_screen_transition) return; - if (!minui_inited) { + if (healthd_draw == nullptr) { if (healthd_config && healthd_config->screen_on) { if (!healthd_config->screen_on(batt_prop)) { LOGV("[%" PRId64 "] leave screen off\n", now); batt_anim->run = false; charger->next_screen_transition = -1; - if (charger->charger_connected) - request_suspend(true); + if (charger->charger_connected) request_suspend(true); return; } } - gr_init(); - gr_font_size(gr_sys_font(), &char_width, &char_height); - init_status_display(batt_anim); + healthd_draw.reset(new HealthdDraw(batt_anim)); #ifndef CHARGER_DISABLE_INIT_BLANK - gr_fb_blank(true); + healthd_draw->blank_screen(true); #endif - minui_inited = true; } /* animation is over, blank screen and leave */ if (batt_anim->num_cycles > 0 && batt_anim->cur_cycle == batt_anim->num_cycles) { reset_animation(batt_anim); charger->next_screen_transition = -1; - gr_fb_blank(true); + healthd_draw->blank_screen(true); LOGV("[%" PRId64 "] animation done\n", now); - if (charger->charger_connected) - request_suspend(true); + if (charger->charger_connected) request_suspend(true); return; } @@ -505,7 +310,6 @@ static void update_screen_state(struct charger *charger, int64_t now) /* animation starting, set up the animation */ if (batt_anim->cur_frame == 0) { - LOGV("[%" PRId64 "] animation starting\n", now); if (batt_prop) { batt_anim->cur_level = batt_prop->batteryLevel; @@ -522,17 +326,16 @@ static void update_screen_state(struct charger *charger, int64_t now) // repeat the first frame first_frame_repeats times disp_time = batt_anim->frames[batt_anim->cur_frame].disp_time * - batt_anim->first_frame_repeats; + batt_anim->first_frame_repeats; } } } /* unblank the screen on first cycle */ - if (batt_anim->cur_cycle == 0) - gr_fb_blank(false); + if (batt_anim->cur_cycle == 0) healthd_draw->blank_screen(false); /* draw the new frame (@ cur_frame) */ - redraw_screen(charger); + healthd_draw->redraw_screen(charger->batt_anim, charger->surf_unknown); /* if we don't have anim frames, we only have one image, so just bump * the cycle counter and exit @@ -576,22 +379,18 @@ static void update_screen_state(struct charger *charger, int64_t now) } } -static int set_key_callback(struct charger *charger, int code, int value) -{ +static int set_key_callback(charger* charger, int code, int value) { int64_t now = curr_time_ms(); int down = !!value; - if (code > KEY_MAX) - return -1; + if (code > KEY_MAX) return -1; /* ignore events that don't modify our state */ - if (charger->keys[code].down == down) - return 0; + if (charger->keys[code].down == down) return 0; /* only record the down even timestamp, as the amount * of time the key spent not being pressed is not useful */ - if (down) - charger->keys[code].timestamp = now; + if (down) charger->keys[code].timestamp = now; charger->keys[code].down = down; charger->keys[code].pending = true; if (down) { @@ -600,34 +399,27 @@ static int set_key_callback(struct charger *charger, int code, int value) int64_t duration = now - charger->keys[code].timestamp; int64_t secs = duration / 1000; int64_t msecs = duration - secs * 1000; - LOGV("[%" PRId64 "] key[%d] up (was down for %" PRId64 ".%" PRId64 "sec)\n", - now, code, secs, msecs); + LOGV("[%" PRId64 "] key[%d] up (was down for %" PRId64 ".%" PRId64 "sec)\n", now, code, + secs, msecs); } return 0; } -static void update_input_state(struct charger *charger, - struct input_event *ev) -{ - if (ev->type != EV_KEY) - return; +static void update_input_state(charger* charger, input_event* ev) { + if (ev->type != EV_KEY) return; set_key_callback(charger, ev->code, ev->value); } -static void set_next_key_check(struct charger *charger, - struct key_state *key, - int64_t timeout) -{ +static void set_next_key_check(charger* charger, key_state* key, int64_t timeout) { int64_t then = key->timestamp + timeout; if (charger->next_key_check == -1 || then < charger->next_key_check) charger->next_key_check = then; } -static void process_key(struct charger *charger, int code, int64_t now) -{ - struct key_state *key = &charger->keys[code]; +static void process_key(charger* charger, int code, int64_t now) { + key_state* key = &charger->keys[code]; if (code == KEY_POWER) { if (key->down) { @@ -644,8 +436,10 @@ static void process_key(struct charger *charger, int code, int64_t now) LOGW("[%" PRId64 "] rebooting\n", now); reboot(RB_AUTOBOOT); } else { - LOGV("[%" PRId64 "] ignore power-button press, battery level " - "less than minimum\n", now); + LOGV("[%" PRId64 + "] ignore power-button press, battery level " + "less than minimum\n", + now); } } } else { @@ -654,9 +448,9 @@ static void process_key(struct charger *charger, int code, int64_t now) */ set_next_key_check(charger, key, POWER_ON_KEY_TIME); - /* Turn on the display and kick animation on power-key press - * rather than on key release - */ + /* Turn on the display and kick animation on power-key press + * rather than on key release + */ kick_animation(charger->batt_anim); request_suspend(false); } @@ -671,21 +465,17 @@ static void process_key(struct charger *charger, int code, int64_t now) key->pending = false; } -static void handle_input_state(struct charger *charger, int64_t now) -{ +static void handle_input_state(charger* charger, int64_t now) { process_key(charger, KEY_POWER, now); if (charger->next_key_check != -1 && now > charger->next_key_check) charger->next_key_check = -1; } -static void handle_power_supply_state(struct charger *charger, int64_t now) -{ - if (!charger->have_battery_state) - return; +static void handle_power_supply_state(charger* charger, int64_t now) { + if (!charger->have_battery_state) return; if (!charger->charger_connected) { - /* Last cycle would have stopped at the extreme top of battery-icon * Need to show the correct level corresponding to capacity. */ @@ -711,9 +501,8 @@ static void handle_power_supply_state(struct charger *charger, int64_t now) } } -void healthd_mode_charger_heartbeat() -{ - struct charger *charger = &charger_state; +void healthd_mode_charger_heartbeat() { + charger* charger = &charger_state; int64_t now = curr_time_ms(); handle_input_state(charger, now); @@ -725,14 +514,11 @@ void healthd_mode_charger_heartbeat() update_screen_state(charger, now); } -void healthd_mode_charger_battery_update( - struct android::BatteryProperties *props) -{ - struct charger *charger = &charger_state; +void healthd_mode_charger_battery_update(android::BatteryProperties* props) { + charger* charger = &charger_state; charger->charger_connected = - props->chargerAcOnline || props->chargerUsbOnline || - props->chargerWirelessOnline; + props->chargerAcOnline || props->chargerUsbOnline || props->chargerWirelessOnline; if (!charger->have_battery_state) { charger->have_battery_state = true; @@ -743,19 +529,16 @@ void healthd_mode_charger_battery_update( batt_prop = props; } -int healthd_mode_charger_preparetowait(void) -{ - struct charger *charger = &charger_state; +int healthd_mode_charger_preparetowait(void) { + charger* charger = &charger_state; int64_t now = curr_time_ms(); int64_t next_event = INT64_MAX; int64_t timeout; - LOGV("[%" PRId64 "] next screen: %" PRId64 " next key: %" PRId64 " next pwr: %" PRId64 "\n", now, - charger->next_screen_transition, charger->next_key_check, - charger->next_pwr_check); + LOGV("[%" PRId64 "] next screen: %" PRId64 " next key: %" PRId64 " next pwr: %" PRId64 "\n", + now, charger->next_screen_transition, charger->next_key_check, charger->next_pwr_check); - if (charger->next_screen_transition != -1) - next_event = charger->next_screen_transition; + if (charger->next_screen_transition != -1) next_event = charger->next_screen_transition; if (charger->next_key_check != -1 && charger->next_key_check < next_event) next_event = charger->next_key_check; if (charger->next_pwr_check != -1 && charger->next_pwr_check < next_event) @@ -766,32 +549,27 @@ int healthd_mode_charger_preparetowait(void) else timeout = -1; - return (int)timeout; + return (int)timeout; } -static int input_callback(struct charger *charger, int fd, unsigned int epevents) -{ - struct input_event ev; +static int input_callback(charger* charger, int fd, unsigned int epevents) { + input_event ev; int ret; ret = ev_get_input(fd, epevents, &ev); - if (ret) - return -1; + if (ret) return -1; update_input_state(charger, &ev); return 0; } -static void charger_event_handler(uint32_t /*epevents*/) -{ +static void charger_event_handler(uint32_t /*epevents*/) { int ret; ret = ev_wait(-1); - if (!ret) - ev_dispatch(); + if (!ret) ev_dispatch(); } -animation* init_animation() -{ +animation* init_animation() { bool parse_success; std::string content; @@ -814,32 +592,29 @@ animation* init_animation() } LOGV("Animation Description:\n"); - LOGV(" animation: %d %d '%s' (%d)\n", - battery_animation.num_cycles, battery_animation.first_frame_repeats, - battery_animation.animation_file.c_str(), battery_animation.num_frames); + LOGV(" animation: %d %d '%s' (%d)\n", battery_animation.num_cycles, + battery_animation.first_frame_repeats, battery_animation.animation_file.c_str(), + battery_animation.num_frames); LOGV(" fail_file: '%s'\n", battery_animation.fail_file.c_str()); - LOGV(" clock: %d %d %d %d %d %d '%s'\n", - battery_animation.text_clock.pos_x, battery_animation.text_clock.pos_y, - battery_animation.text_clock.color_r, battery_animation.text_clock.color_g, - battery_animation.text_clock.color_b, battery_animation.text_clock.color_a, - battery_animation.text_clock.font_file.c_str()); - LOGV(" percent: %d %d %d %d %d %d '%s'\n", - battery_animation.text_percent.pos_x, battery_animation.text_percent.pos_y, - battery_animation.text_percent.color_r, battery_animation.text_percent.color_g, - battery_animation.text_percent.color_b, battery_animation.text_percent.color_a, - battery_animation.text_percent.font_file.c_str()); + LOGV(" clock: %d %d %d %d %d %d '%s'\n", battery_animation.text_clock.pos_x, + battery_animation.text_clock.pos_y, battery_animation.text_clock.color_r, + battery_animation.text_clock.color_g, battery_animation.text_clock.color_b, + battery_animation.text_clock.color_a, battery_animation.text_clock.font_file.c_str()); + LOGV(" percent: %d %d %d %d %d %d '%s'\n", battery_animation.text_percent.pos_x, + battery_animation.text_percent.pos_y, battery_animation.text_percent.color_r, + battery_animation.text_percent.color_g, battery_animation.text_percent.color_b, + battery_animation.text_percent.color_a, battery_animation.text_percent.font_file.c_str()); for (int i = 0; i < battery_animation.num_frames; i++) { LOGV(" frame %.2d: %d %d %d\n", i, battery_animation.frames[i].disp_time, - battery_animation.frames[i].min_level, battery_animation.frames[i].max_level); + battery_animation.frames[i].min_level, battery_animation.frames[i].max_level); } return &battery_animation; } -void healthd_mode_charger_init(struct healthd_config* config) -{ +void healthd_mode_charger_init(struct healthd_config* config) { int ret; - struct charger *charger = &charger_state; + charger* charger = &charger_state; int i; int epollfd; @@ -847,14 +622,13 @@ void healthd_mode_charger_init(struct healthd_config* config) LOGW("--------------- STARTING CHARGER MODE ---------------\n"); - ret = ev_init(std::bind(&input_callback, charger, std::placeholders::_1, - std::placeholders::_2)); + ret = ev_init(std::bind(&input_callback, charger, std::placeholders::_1, std::placeholders::_2)); if (!ret) { epollfd = ev_get_epollfd(); healthd_register_event(epollfd, charger_event_handler, EVENT_WAKEUP_FD); } - struct animation* anim = init_animation(); + animation* anim = init_animation(); charger->batt_anim = anim; ret = res_create_display_surface(anim->fail_file.c_str(), &charger->surf_unknown); @@ -871,15 +645,15 @@ void healthd_mode_charger_init(struct healthd_config* config) int scale_count; int scale_fps; // Not in use (charger/battery_scale doesn't have FPS text // chunk). We are using hard-coded frame.disp_time instead. - ret = res_create_multi_display_surface(anim->animation_file.c_str(), - &scale_count, &scale_fps, &scale_frames); + ret = res_create_multi_display_surface(anim->animation_file.c_str(), &scale_count, &scale_fps, + &scale_frames); if (ret < 0) { LOGE("Cannot load battery_scale image\n"); anim->num_frames = 0; anim->num_cycles = 1; } else if (scale_count != anim->num_frames) { - LOGE("battery_scale image has unexpected frame count (%d, expected %d)\n", - scale_count, anim->num_frames); + LOGE("battery_scale image has unexpected frame count (%d, expected %d)\n", scale_count, + anim->num_frames); anim->num_frames = 0; anim->num_cycles = 1; } else { @@ -887,8 +661,8 @@ void healthd_mode_charger_init(struct healthd_config* config) anim->frames[i].surface = scale_frames[i]; } } - ev_sync_key_state(std::bind(&set_key_callback, charger, std::placeholders::_1, - std::placeholders::_2)); + ev_sync_key_state( + std::bind(&set_key_callback, charger, std::placeholders::_1, std::placeholders::_2)); charger->next_screen_transition = -1; charger->next_key_check = -1; From 12f81dfdffb63d71c138d44c245c8a649264b308 Mon Sep 17 00:00:00 2001 From: Jean-Luc Brouillet Date: Fri, 21 Jul 2017 20:16:35 -0700 Subject: [PATCH 024/129] Make the Neural Networks library loadable by apps. Add to the whitelist the NN API lib. Bug: 63905942 Test: Ran an app that uses the NN API. Change-Id: I83c1acdff58b8fe99fbd7a8fbfb5444fe77b7902 --- rootdir/etc/public.libraries.android.txt | 1 + rootdir/etc/public.libraries.wear.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/rootdir/etc/public.libraries.android.txt b/rootdir/etc/public.libraries.android.txt index bcdecf26e..54820853f 100644 --- a/rootdir/etc/public.libraries.android.txt +++ b/rootdir/etc/public.libraries.android.txt @@ -14,6 +14,7 @@ liblog.so libmediandk.so libm.so libnativewindow.so +libneuralnetworks.so libOpenMAXAL.so libOpenSLES.so libRS.so diff --git a/rootdir/etc/public.libraries.wear.txt b/rootdir/etc/public.libraries.wear.txt index f4da09d8a..45b4bc216 100644 --- a/rootdir/etc/public.libraries.wear.txt +++ b/rootdir/etc/public.libraries.wear.txt @@ -14,6 +14,7 @@ liblog.so libmediandk.so libm.so libnativewindow.so +libneuralnetworks.so libOpenMAXAL.so libOpenSLES.so libRS.so From 90a2487776d464e867c7bad1dc8d993ed50df09e Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Tue, 25 Jul 2017 14:13:51 +0900 Subject: [PATCH 025/129] Add system/${LIB}/vndk to default namespace for vendor. With BOARD_VNDK_VERSION=current, vndk libs will be installed in system/${LIB}/vndk. To make them available for vendor, it must be added to default namespace. Bug: 63866913 Test: build and boot with BOARD_VNDK_VERSION=current Change-Id: I9e467a6125fc89513754b56a2420975559144f98 --- rootdir/etc/ld.config.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index 3cb5c1dde..d0418883d 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt @@ -117,9 +117,9 @@ namespace.vndk.link.default.shared_libs = android.hidl.memory@1.0-impl.so:libc.s ############################################################################### [vendor] namespace.default.isolated = false -namespace.default.search.paths = /vendor/${LIB}:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/system/${LIB} +namespace.default.search.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl:/vendor/${LIB}:/system/${LIB}/vndk:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/system/${LIB} -namespace.default.asan.search.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB} +namespace.default.asan.search.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl:/data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB} ############################################################################### # Namespace config for tests. No VNDK restriction is enforced for these tests. From 48647f6db1e7fd513ad86fa61c86f326ee7d4a0f Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Wed, 26 Jul 2017 13:25:27 +0900 Subject: [PATCH 026/129] Mark an SP-NDK, libsync.so as VNDK libs. libsync.so is categorized as SP-NDK and vendor_available. However, it is marked as VNDK because it is needed by some VNDK libs. Bug: 63866913 Test: build and boot with BOARD_VNDK_VERSION=current Change-Id: I116a442ce284a6e5ba1c76f99d44329a9f00fed7 --- libsync/Android.bp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libsync/Android.bp b/libsync/Android.bp index 257d42deb..1cd52304a 100644 --- a/libsync/Android.bp +++ b/libsync/Android.bp @@ -23,6 +23,9 @@ cc_defaults { cc_library_shared { name: "libsync", vendor_available: true, + vndk: { + enabled: true, + }, defaults: ["libsync_defaults"], } From 684f4883b33856d8d0cd97e33f07b2939957bf96 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Wed, 26 Jul 2017 14:17:09 -0700 Subject: [PATCH 027/129] init: only use signed-integer-overflow sanitizer We've blown up twice in init due to the unsigned integer overflow sanitizer despite the overflows in question being both defined and intentional. Bug: 63680332 Test: boot Change-Id: I08effe3202ac1367d858982ff5478b3a088bab37 (cherry picked from commit 2ffd65e1d12940b5e13ea743bb88e94a57e7ca97) --- init/Android.bp | 2 +- init/Android.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/init/Android.bp b/init/Android.bp index 82945981e..aaef7e933 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -18,7 +18,7 @@ cc_defaults { name: "init_defaults", cpp_std: "experimental", sanitize: { - misc_undefined: ["integer"], + misc_undefined: ["signed-integer-overflow"], }, cppflags: [ "-DLOG_UEVENTS=0", diff --git a/init/Android.mk b/init/Android.mk index c0c490559..161256e9a 100644 --- a/init/Android.mk +++ b/init/Android.mk @@ -96,6 +96,6 @@ LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \ ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \ ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd -LOCAL_SANITIZE := integer +LOCAL_SANITIZE := signed-integer-overflow LOCAL_CLANG := true include $(BUILD_EXECUTABLE) From 7d7e7cdf3498d0484f85fa69688a79fe3cd7091e Mon Sep 17 00:00:00 2001 From: Ben Fennema Date: Tue, 25 Jul 2017 14:37:21 -0700 Subject: [PATCH 028/129] init: fix type of 2nd argument passed to prctl prctl(PR_SET_SECUREBITS, ...) expects an unsigned long as its 2nd argument. Passing in a int64_t happens to work with a 64-bit kernel, but does not work with a 32-bit kernel. Bug: 63680332 Test: boot 32-bit kernel; verify services with capabilities can successfully set those capabilties Change-Id: I60250d107a77b54b2e9fe3419b4480b921c7e2f8 Signed-off-by: Ben Fennema (cherry picked from commit a72436067d5f88885e4b32fa7c5d22f1ea8c0756) --- init/service.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/init/service.cpp b/init/service.cpp index 82dd9b137..fe38ee205 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -245,8 +245,8 @@ void Service::SetProcessAttributes() { if (capabilities_.any() && uid_) { // If Android is running in a container, some securebits might already // be locked, so don't change those. - int64_t securebits = prctl(PR_GET_SECUREBITS); - if (securebits == -1) { + unsigned long securebits = prctl(PR_GET_SECUREBITS); + if (securebits == -1UL) { PLOG(FATAL) << "prctl(PR_GET_SECUREBITS) failed for " << name_; } securebits |= SECBIT_KEEP_CAPS | SECBIT_KEEP_CAPS_LOCKED; From f415d1253c62916d5728ceaedbe5ba62195c7dc2 Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Tue, 25 Jul 2017 12:55:12 -0700 Subject: [PATCH 029/129] bootstat: Log even more boot reasons. Bug: 27555866 Test: None Change-Id: I8ab6597a323f5973d8b1c22c2c7422ef0c2efcc3 (cherry picked from commit 8d7f63da26f342ea4587962e57a0d457673a3a10) --- bootstat/bootstat.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp index 344fa9aae..bd611f0b9 100644 --- a/bootstat/bootstat.cpp +++ b/bootstat/bootstat.cpp @@ -169,6 +169,13 @@ const std::map kBootReasonMap = { {"wdog_bark", 42}, {"wdog_bite", 43}, {"wdog_reset", 44}, + {"shutdown,", 45}, // Trailing comma is intentional. + {"shutdown,userrequested", 46}, + {"reboot,bootloader", 47}, + {"reboot,cold", 48}, + {"reboot,recovery", 49}, + {"thermal_shutdown", 50}, + {"s3_wakeup", 51} }; // Converts a string value representing the reason the system booted to an From 6a38aa83b6b318613884b90506ff0a20369d15d2 Mon Sep 17 00:00:00 2001 From: Yu Ning Date: Wed, 26 Jul 2017 17:54:08 +0800 Subject: [PATCH 030/129] Allow the use of a custom Android DT directory On platforms that use ACPI instead of Device Tree (DT), such as Ranchu x86/x86_64, /proc/device-tree/firmware/android/ does not exist. As a result, Android O is unable to mount /system, etc. at the first stage of init: init: First stage mount skipped (missing/incompatible fstab in device tree) Those platforms may create another directory that mimics the layout of the standard DT directory in procfs, and store early mount configuration there. E.g., Ranchu x86/x86_64 creates one in sysfs using information encoded in the ACPI tables: https://android-review.googlesource.com/442472 https://android-review.googlesource.com/443432 https://android-review.googlesource.com/442393 https://android-review.googlesource.com/442395 Therefore, instead of hardcoding the Android DT path, load it from the kernel command line using a new Android-specific property key ("androidboot.android_dt_dir"). If no such property exists, fall back to the standard procfs path (so no change is needed for DT- aware platforms). Note that init/ and fs_mgr/ each have their own copy of the Android DT path, because they do not share any global state. A future CL should remove the duplication by refactoring. With this CL as well as the above ones, the said warning is gone, but early mount fails. That is a separate bug, though, and will be addressed by another CL. Test: Boot patched sdk_phone_x86-userdebug system image with patched Goldfish 3.18 x86 kernel in patched Android Emulator, verify the "init: First stage mount skipped" warning no longer shows in dmesg. Signed-off-by: Yu Ning (cherry picked from commit c08d2cb0fb7ce470e128c7571553aa12ae9b57a4) Change-Id: Ia8d5f68e044fde0ecf5c7b14e40f040ff42bc35d --- fs_mgr/fs_mgr_boot_config.cpp | 36 +++++++++++++++++++++----------- fs_mgr/fs_mgr_fstab.cpp | 25 +++++++++++++++++++--- fs_mgr/fs_mgr_priv.h | 1 + fs_mgr/fs_mgr_priv_boot_config.h | 3 +-- init/init.cpp | 4 ++-- init/util.cpp | 27 ++++++++++++++++++++++-- init/util.h | 7 ++++--- 7 files changed, 79 insertions(+), 24 deletions(-) diff --git a/fs_mgr/fs_mgr_boot_config.cpp b/fs_mgr/fs_mgr_boot_config.cpp index 911766752..9c5d3f3bb 100644 --- a/fs_mgr/fs_mgr_boot_config.cpp +++ b/fs_mgr/fs_mgr_boot_config.cpp @@ -23,19 +23,11 @@ #include "fs_mgr_priv.h" -// Tries to get the boot config value in properties, kernel cmdline and -// device tree (in that order). returns 'true' if successfully found, 'false' -// otherwise -bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) { +// Tries to get the given boot config value from kernel cmdline. +// Returns true if successfully found, false otherwise. +bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val) { FS_MGR_CHECK(out_val != nullptr); - // first check if we have "ro.boot" property already - *out_val = android::base::GetProperty("ro.boot." + key, ""); - if (!out_val->empty()) { - return true; - } - - // fallback to kernel cmdline, properties may not be ready yet std::string cmdline; std::string cmdline_key("androidboot." + key); if (android::base::ReadFileToString("/proc/cmdline", &cmdline)) { @@ -50,9 +42,29 @@ bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) { } } + return false; +} + +// Tries to get the boot config value in properties, kernel cmdline and +// device tree (in that order). returns 'true' if successfully found, 'false' +// otherwise +bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) { + FS_MGR_CHECK(out_val != nullptr); + + // first check if we have "ro.boot" property already + *out_val = android::base::GetProperty("ro.boot." + key, ""); + if (!out_val->empty()) { + return true; + } + + // fallback to kernel cmdline, properties may not be ready yet + if (fs_mgr_get_boot_config_from_kernel_cmdline(key, out_val)) { + return true; + } + // lastly, check the device tree if (is_dt_compatible()) { - std::string file_name = kAndroidDtDir + "/" + key; + std::string file_name = get_android_dt_dir() + "/" + key; if (android::base::ReadFileToString(file_name, out_val)) { if (!out_val->empty()) { out_val->pop_back(); // Trims the trailing '\0' out. diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp index 6dcbded49..eeac6979a 100644 --- a/fs_mgr/fs_mgr_fstab.cpp +++ b/fs_mgr/fs_mgr_fstab.cpp @@ -29,6 +29,8 @@ #include "fs_mgr_priv.h" +const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android"); + struct fs_mgr_flag_values { char *key_loc; char* key_dir; @@ -365,9 +367,26 @@ static int parse_flags(char *flags, struct flag_list *fl, return f; } +static std::string init_android_dt_dir() { + std::string android_dt_dir; + // The platform may specify a custom Android DT path in kernel cmdline + if (!fs_mgr_get_boot_config_from_kernel_cmdline("android_dt_dir", &android_dt_dir)) { + // Fall back to the standard procfs-based path + android_dt_dir = kDefaultAndroidDtDir; + } + return android_dt_dir; +} + +// FIXME: The same logic is duplicated in system/core/init/ +const std::string& get_android_dt_dir() { + // Set once and saves time for subsequent calls to this function + static const std::string kAndroidDtDir = init_android_dt_dir(); + return kAndroidDtDir; +} + static bool is_dt_fstab_compatible() { std::string dt_value; - std::string file_name = kAndroidDtDir + "/fstab/compatible"; + std::string file_name = get_android_dt_dir() + "/fstab/compatible"; if (read_dt_file(file_name, &dt_value)) { if (dt_value == "android,fstab") { return true; @@ -383,7 +402,7 @@ static std::string read_fstab_from_dt() { return fstab; } - std::string fstabdir_name = kAndroidDtDir + "/fstab"; + std::string fstabdir_name = get_android_dt_dir() + "/fstab"; std::unique_ptr fstabdir(opendir(fstabdir_name.c_str()), closedir); if (!fstabdir) return fstab; @@ -446,7 +465,7 @@ static std::string read_fstab_from_dt() { } bool is_dt_compatible() { - std::string file_name = kAndroidDtDir + "/compatible"; + std::string file_name = get_android_dt_dir() + "/compatible"; std::string dt_value; if (read_dt_file(file_name, &dt_value)) { if (dt_value == "android,firmware") { diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index a5d172b03..0f62e18fd 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -120,6 +120,7 @@ bool fs_mgr_wait_for_file(const std::string& filename, const std::chrono::milliseconds relative_timeout); bool fs_mgr_update_for_slotselect(struct fstab *fstab); bool fs_mgr_is_device_unlocked(); +const std::string& get_android_dt_dir(); bool is_dt_compatible(); bool is_device_secure(); int load_verity_state(struct fstab_rec* fstab, int* mode); diff --git a/fs_mgr/fs_mgr_priv_boot_config.h b/fs_mgr/fs_mgr_priv_boot_config.h index 8773d33b0..d98dc02c1 100644 --- a/fs_mgr/fs_mgr_priv_boot_config.h +++ b/fs_mgr/fs_mgr_priv_boot_config.h @@ -20,8 +20,7 @@ #include #include -const std::string kAndroidDtDir("/proc/device-tree/firmware/android"); - +bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val); bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val); #endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */ diff --git a/init/init.cpp b/init/init.cpp index 55d5fa826..715dd72a2 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -513,7 +513,7 @@ static void process_kernel_dt() { return; } - std::unique_ptr dir(opendir(kAndroidDtDir.c_str()), closedir); + std::unique_ptr dir(opendir(get_android_dt_dir().c_str()), closedir); if (!dir) return; std::string dt_file; @@ -523,7 +523,7 @@ static void process_kernel_dt() { continue; } - std::string file_name = kAndroidDtDir + dp->d_name; + std::string file_name = get_android_dt_dir() + dp->d_name; android::base::ReadFileToString(file_name, &dt_file); std::replace(dt_file.begin(), dt_file.end(), ',', '.'); diff --git a/init/util.cpp b/init/util.cpp index 2792794c5..fdcb22d1c 100644 --- a/init/util.cpp +++ b/init/util.cpp @@ -53,6 +53,8 @@ using namespace std::literals::string_literals; namespace android { namespace init { +const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android/"); + // DecodeUid() - decodes and returns the given string, which can be either the // numeric or name representation, into the integer uid or gid. Returns // UINT_MAX on error. @@ -374,10 +376,31 @@ void panic() { DoReboot(ANDROID_RB_RESTART2, "reboot", "bootloader", false); } -// Reads the content of device tree file under kAndroidDtDir directory. +static std::string init_android_dt_dir() { + // Use the standard procfs-based path by default + std::string android_dt_dir = kDefaultAndroidDtDir; + // The platform may specify a custom Android DT path in kernel cmdline + import_kernel_cmdline(false, + [&](const std::string& key, const std::string& value, bool in_qemu) { + if (key == "androidboot.android_dt_dir") { + android_dt_dir = value; + } + }); + LOG(INFO) << "Using Android DT directory " << android_dt_dir; + return android_dt_dir; +} + +// FIXME: The same logic is duplicated in system/core/fs_mgr/ +const std::string& get_android_dt_dir() { + // Set once and saves time for subsequent calls to this function + static const std::string kAndroidDtDir = init_android_dt_dir(); + return kAndroidDtDir; +} + +// Reads the content of device tree file under the platform's Android DT directory. // Returns true if the read is success, false otherwise. bool read_android_dt_file(const std::string& sub_path, std::string* dt_content) { - const std::string file_name = kAndroidDtDir + sub_path; + const std::string file_name = get_android_dt_dir() + sub_path; if (android::base::ReadFileToString(file_name, dt_content)) { if (!dt_content->empty()) { dt_content->pop_back(); // Trims the trailing '\0' out. diff --git a/init/util.h b/init/util.h index 452df2d00..29c10cba2 100644 --- a/init/util.h +++ b/init/util.h @@ -30,8 +30,6 @@ #define COLDBOOT_DONE "/dev/.coldboot_done" -const std::string kAndroidDtDir("/proc/device-tree/firmware/android/"); - using android::base::boot_clock; using namespace std::chrono_literals; @@ -57,7 +55,10 @@ bool expand_props(const std::string& src, std::string* dst); void panic() __attribute__((__noreturn__)); -// Reads or compares the content of device tree file under kAndroidDtDir directory. +// Returns the platform's Android DT directory as specified in the kernel cmdline. +// If the platform does not configure a custom DT path, returns the standard one (based in procfs). +const std::string& get_android_dt_dir(); +// Reads or compares the content of device tree file under the platform's Android DT directory. bool read_android_dt_file(const std::string& sub_path, std::string* dt_content); bool is_android_dt_value_expected(const std::string& sub_path, const std::string& expected_content); From aeb68e86e4e335d4b201c46099cc2ce1256beec2 Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Mon, 31 Jul 2017 15:41:10 +0900 Subject: [PATCH 031/129] Mark the modules as VNDK-SP in Android.bp As a VNDK-SP module, Android.bp must have 'vndk' tag as well as 'vendor_available: true'. The 'vndk' tag for VNDK-SP formated as follows: vndk: { enabled: true, support_system_process: true, }, VNDK-SP modules will be installed both in system/lib(64) as normal and in system/lib(64)/vndk-sp as a vendor variant. Bug: 63866913 Test: build and boot with BOARD_VNDK_VERSION=current Change-Id: I51fe0859f63ad58b7b91909e7d7d4206443228cd --- base/Android.bp | 4 ++++ libbacktrace/Android.bp | 4 ++++ libcutils/Android.bp | 4 ++++ libion/Android.bp | 6 +++++- libutils/Android.bp | 4 ++++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/base/Android.bp b/base/Android.bp index b636dc31c..6c3a593a7 100644 --- a/base/Android.bp +++ b/base/Android.bp @@ -41,6 +41,10 @@ cc_library { vendor_available: true, clang: true, host_supported: true, + vndk: { + enabled: true, + support_system_process: true, + }, srcs: [ "file.cpp", "logging.cpp", diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp index e02aaf216..7eefc95af 100644 --- a/libbacktrace/Android.bp +++ b/libbacktrace/Android.bp @@ -64,6 +64,10 @@ cc_library_headers { cc_library { name: "libbacktrace", vendor_available: true, + vndk: { + enabled: true, + support_system_process: true, + }, defaults: ["libbacktrace_common"], host_supported: true, diff --git a/libcutils/Android.bp b/libcutils/Android.bp index 245deb113..56a0cca6d 100644 --- a/libcutils/Android.bp +++ b/libcutils/Android.bp @@ -50,6 +50,10 @@ cc_library_headers { cc_library { name: "libcutils", vendor_available: true, + vndk: { + enabled: true, + support_system_process: true, + }, host_supported: true, srcs: [ "config_utils.c", diff --git a/libion/Android.bp b/libion/Android.bp index 6f267e4c7..6d9fae076 100644 --- a/libion/Android.bp +++ b/libion/Android.bp @@ -1,7 +1,11 @@ cc_library { name: "libion", - vendor_available: true, + vendor_available: true, + vndk: { + enabled: true, + support_system_process: true, + }, srcs: ["ion.c"], shared_libs: ["liblog"], local_include_dirs: [ diff --git a/libutils/Android.bp b/libutils/Android.bp index 9e7cc138c..a779a8ccf 100644 --- a/libutils/Android.bp +++ b/libutils/Android.bp @@ -46,6 +46,10 @@ cc_library_headers { cc_library { name: "libutils", vendor_available: true, + vndk: { + enabled: true, + support_system_process: true, + }, host_supported: true, srcs: [ From cad5925fc93803b3775896a7523648d18216ea3b Mon Sep 17 00:00:00 2001 From: Saurabh Shah Date: Tue, 1 Aug 2017 13:54:21 -0700 Subject: [PATCH 032/129] sync: store the num_fences from first SYNC_IOC_FILE_INFO Fixes a bug with the signal time of devices using the modern sync file interface. The bug only affects kernels running an Android kernel 4.9 and later. b/63395253 Test: tests/sync_test.cpp Change-Id: I6fb00bcb8e16a3268c357153edd8e35a44546caa --- libsync/sync.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libsync/sync.c b/libsync/sync.c index baeccda47..095008254 100644 --- a/libsync/sync.c +++ b/libsync/sync.c @@ -217,6 +217,8 @@ static struct sync_file_info *modern_sync_file_info(int fd) local_info.num_fences * sizeof(struct sync_fence_info)); if (!info) return NULL; + + info->num_fences = local_info.num_fences; info->sync_fence_info = (__u64)(uintptr_t)(info + 1); err = ioctl(fd, SYNC_IOC_FILE_INFO, info); From a86141aa813ad5f12e48c941435286c1ad14ec54 Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Thu, 27 Jul 2017 16:17:17 -0700 Subject: [PATCH 033/129] fastboot: enable uninit_bg for ext4 This speeds up mke2fs as well as e2fsck. Bug: 23686092 Bug: 64032335 Change-Id: I9f2d4c15e431647bb845d50a2361b2a9a091fba6 (cherry picked from commit 99e3964e0deb2f6ded9624262bcbd8b077963f7d) --- fastboot/fs.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp index f3c000eb7..6058b882d 100644 --- a/fastboot/fs.cpp +++ b/fastboot/fs.cpp @@ -91,6 +91,8 @@ static int generate_ext4_image(const char* fileName, long long partSize, } mke2fs_args.push_back("-E"); mke2fs_args.push_back(ext_attr.c_str()); + mke2fs_args.push_back("-O"); + mke2fs_args.push_back("uninit_bg"); mke2fs_args.push_back(fileName); std::string size_str = std::to_string(partSize / block_size); From 216ed8f61a47c29c0b04574d108bc06bf08339f0 Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Mon, 10 Jul 2017 16:04:41 -0700 Subject: [PATCH 034/129] fastboot: call mke2fs to format ext4 filesystem on windows Bug: 35219933 Change-Id: I0cc8c165176e8dc9cbe4b6a52679937bc872e2d0 (cherry picked from commit 29fc859a6de4f5566652c4f5750e91c965d4b97f) --- fastboot/fs.cpp | 60 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp index 6058b882d..709f061bd 100644 --- a/fastboot/fs.cpp +++ b/fastboot/fs.cpp @@ -12,10 +12,14 @@ #include #ifndef WIN32 #include +#else +#include +#include #endif #include #include +#include #include #include #include @@ -26,21 +30,49 @@ using android::base::StringPrintf; using android::base::unique_fd; #ifdef WIN32 -static int generate_ext4_image(const char* fileName, long long partSize, const std::string& initial_dir, - unsigned eraseBlkSize, unsigned logicalBlkSize) -{ - unique_fd fd(open(fileName, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)); - if (fd == -1) { - fprintf(stderr, "Unable to open output file for EXT4 filesystem: %s\n", strerror(errno)); +static int exec_e2fs_cmd(const char* path, char* const argv[]) { + std::string cmd; + int i = 0; + while (argv[i] != nullptr) { + cmd += argv[i++]; + cmd += " "; + } + cmd = cmd.substr(0, cmd.size() - 1); + + STARTUPINFO si; + PROCESS_INFORMATION pi; + DWORD exit_code = 0; + + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + + SetEnvironmentVariableA("MKE2FS_CONFIG", ""); + + if (!CreateProcessA(nullptr, // No module name (use command line) + const_cast(cmd.c_str()), // Command line + nullptr, // Process handle not inheritable + nullptr, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + 0, // No creation flags + nullptr, // Use parent's environment block + nullptr, // Use parent's starting directory + &si, // Pointer to STARTUPINFO structure + &pi) // Pointer to PROCESS_INFORMATION structure + ) { + fprintf(stderr, "CreateProcess failed: %s\n", + android::base::SystemErrorCodeToString(GetLastError()).c_str()); return -1; } - if (initial_dir.empty()) { - make_ext4fs_sparse_fd_align(fd, partSize, NULL, NULL, eraseBlkSize, logicalBlkSize); - } else { - make_ext4fs_sparse_fd_directory_align(fd, partSize, NULL, NULL, initial_dir.c_str(), - eraseBlkSize, logicalBlkSize); - } - return 0; + + WaitForSingleObject(pi.hProcess, INFINITE); + + GetExitCodeProcess(pi.hProcess, &exit_code); + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + + return exit_code != 0; } #else static int exec_e2fs_cmd(const char* path, char* const argv[]) { @@ -68,6 +100,7 @@ static int exec_e2fs_cmd(const char* path, char* const argv[]) { } return ret; } +#endif static int generate_ext4_image(const char* fileName, long long partSize, const std::string& initial_dir, unsigned eraseBlkSize, @@ -121,7 +154,6 @@ static int generate_ext4_image(const char* fileName, long long partSize, return 0; } -#endif #ifdef USE_F2FS static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir, From 9560088743679416776e30f00d2278de534eaae8 Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Mon, 31 Jul 2017 15:18:32 +0900 Subject: [PATCH 035/129] libvndksupport: Change log level and message. If no 'sphal' namespace exist, the sphal library may be found in current namespace. Change the log level and message to note this. Bug: 64162324 Test: Check log message for vndksupport tag. Change-Id: I5ed6ba1e48f99e7d11d80a465177ac9f3a7fbd97 --- libvndksupport/linker.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libvndksupport/linker.c b/libvndksupport/linker.c index 696e97817..703b593fa 100644 --- a/libvndksupport/linker.c +++ b/libvndksupport/linker.c @@ -32,14 +32,13 @@ void* android_load_sphal_library(const char* name, int flag) { void* handle = android_dlopen_ext(name, flag, &dlextinfo); if (!handle) { ALOGE( - "Could not load %s from sphal namespace: %s. ", + "Could not load %s from sphal namespace: %s.", name, dlerror()); } return handle; } else { - ALOGI( - "sphal namespace is not configured for this process. " - "Loading %s from the current namespace instead.", + ALOGD( + "Loading %s from current namespace instead of sphal namespace.", name); return dlopen(name, flag); } From 58891d59b79640d9f32c13e556674a73b70110d8 Mon Sep 17 00:00:00 2001 From: Robert Benea Date: Mon, 31 Jul 2017 17:15:20 -0700 Subject: [PATCH 036/129] Make lmkd memory pressure levels configurable. By doing so different platforms can customize them accordingly. For instance a low mem, 512MB device can do ro.lmk.medium=400, while a device with more memory can keep the default(800). Test: tested on gobo. Bug: 64316084 Change-Id: Ifc4f3853bc06f30488adb25883ccd9aaf683ba9b --- lmkd/lmkd.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index c0953158d..27cc91b75 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -72,6 +73,9 @@ static int mpevfd[2]; #define CRITICAL_INDEX 1 #define MEDIUM_INDEX 0 +static int medium_oomadj; +static int critical_oomadj; + /* control socket listen and data */ static int ctrl_lfd; static int ctrl_dfd = -1; @@ -643,7 +647,7 @@ static void mp_event_common(bool is_critical) { int ret; unsigned long long evcount; bool first = true; - int min_adj_score = is_critical ? 0 : 800; + int min_adj_score = is_critical ? critical_oomadj : medium_oomadj; int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX; ret = read(mpevfd[index], &evcount, sizeof(evcount)); @@ -822,6 +826,9 @@ int main(int argc __unused, char **argv __unused) { .sched_priority = 1, }; + medium_oomadj = property_get_int32("ro.lmk.medium", 800); + critical_oomadj = property_get_int32("ro.lmk.critical", 0); + mlockall(MCL_FUTURE); sched_setscheduler(0, SCHED_FIFO, ¶m); if (!init()) From 6c21096251e6dbb821729d6fee935049a69354fd Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Tue, 25 Jul 2017 15:24:04 -0700 Subject: [PATCH 037/129] Remove private headers from libcutils.vendor Bug: 63135587 Test: m -j Test: BOARD_VNDK_VERSION=current m -j Test: mma -j Test: BOARD_VNDK_VERSION=current mma -j Change-Id: I9eecf23c4c311bd8336a5bfaaeb2afb3b51c6513 Merged-In: I9eecf23c4c311bd8336a5bfaaeb2afb3b51c6513 --- libcutils/Android.bp | 1 + libcutils/include_vndk/private | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 120000 libcutils/include_vndk/private diff --git a/libcutils/Android.bp b/libcutils/Android.bp index 245deb113..159c1ddf8 100644 --- a/libcutils/Android.bp +++ b/libcutils/Android.bp @@ -150,6 +150,7 @@ cc_library { "libutils_headers", ], export_header_lib_headers: ["libcutils_headers"], + local_include_dirs: ["include"], cflags: [ "-Werror", diff --git a/libcutils/include_vndk/private b/libcutils/include_vndk/private deleted file mode 120000 index 2245a855e..000000000 --- a/libcutils/include_vndk/private +++ /dev/null @@ -1 +0,0 @@ -../include/private \ No newline at end of file From 9b0ed7294273d5f10020388e5a5b7e545a2fd1de Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Mon, 24 Jul 2017 15:19:45 +0900 Subject: [PATCH 038/129] Mark the modules as VNDK in Android.bp As a VNDK module, Android.bp must have 'vndk' tag as well as 'vendor_available: true'. The 'vndk' tag for VNDK module is formated as below: vndk: { enabled: true, }, VNDK modules will be installed both in system/lib(64) as normal and in system/lib(64)/vndk as a vendor variant. Bug: 63866913 Test: build and boot with BOARD_VNDK_VERSION=current Change-Id: Icecb22ed2ed0f58c3168605d4cf64815e2dda750 --- libcrypto_utils/Android.bp | 3 +++ libdiskconfig/Android.bp | 3 +++ libnetutils/Android.bp | 3 +++ libprocinfo/Android.bp | 3 +++ libsuspend/Android.bp | 3 +++ libsysutils/Android.bp | 3 +++ libusbhost/Android.bp | 4 ++++ 7 files changed, 22 insertions(+) diff --git a/libcrypto_utils/Android.bp b/libcrypto_utils/Android.bp index 4a5f2a7ac..47de12ab0 100644 --- a/libcrypto_utils/Android.bp +++ b/libcrypto_utils/Android.bp @@ -17,6 +17,9 @@ cc_library { name: "libcrypto_utils", vendor_available: true, + vndk: { + enabled: true, + }, host_supported: true, srcs: [ "android_pubkey.c", diff --git a/libdiskconfig/Android.bp b/libdiskconfig/Android.bp index 088981a7c..23a5c79d0 100644 --- a/libdiskconfig/Android.bp +++ b/libdiskconfig/Android.bp @@ -1,6 +1,9 @@ cc_library { name: "libdiskconfig", vendor_available: true, + vndk: { + enabled: true, + }, srcs: [ "diskconfig.c", "diskutils.c", diff --git a/libnetutils/Android.bp b/libnetutils/Android.bp index 9967ef886..1d43775d6 100644 --- a/libnetutils/Android.bp +++ b/libnetutils/Android.bp @@ -1,6 +1,9 @@ cc_library_shared { name: "libnetutils", vendor_available: true, + vndk: { + enabled: true, + }, srcs: [ "dhcpclient.c", diff --git a/libprocinfo/Android.bp b/libprocinfo/Android.bp index aedaa3867..b568ee5da 100644 --- a/libprocinfo/Android.bp +++ b/libprocinfo/Android.bp @@ -23,6 +23,9 @@ libprocinfo_cppflags = [ cc_library { name: "libprocinfo", vendor_available: true, + vndk: { + enabled: true, + }, host_supported: true, srcs: [ "process.cpp", diff --git a/libsuspend/Android.bp b/libsuspend/Android.bp index 130800ed8..32f1e1ff8 100644 --- a/libsuspend/Android.bp +++ b/libsuspend/Android.bp @@ -3,6 +3,9 @@ cc_library { name: "libsuspend", vendor_available: true, + vndk: { + enabled: true, + }, srcs: [ "autosuspend.c", diff --git a/libsysutils/Android.bp b/libsysutils/Android.bp index 550ef4233..d076a1ae3 100644 --- a/libsysutils/Android.bp +++ b/libsysutils/Android.bp @@ -1,6 +1,9 @@ cc_library_shared { name: "libsysutils", vendor_available: true, + vndk: { + enabled: true, + }, srcs: [ "src/SocketListener.cpp", diff --git a/libusbhost/Android.bp b/libusbhost/Android.bp index a0d6b9b85..fc6f305c0 100644 --- a/libusbhost/Android.bp +++ b/libusbhost/Android.bp @@ -16,6 +16,10 @@ cc_library { name: "libusbhost", + vendor_available: true, + vndk: { + enabled: true, + }, host_supported: true, srcs: ["usbhost.c"], cflags: ["-Werror"], From 7aeb5bb86cae4d13f3459cb7fc344d1a1aaf779f Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Thu, 3 Aug 2017 15:49:19 +0900 Subject: [PATCH 039/129] Mark libmemtrack as VNDK in Android.bp As a VNDK module, Android.bp must have 'vndk' tag as well as 'vendor_available: true'. The 'vndk' tag for VNDK module is formated as below: vndk: { enabled: true, }, VNDK modules will be installed both in system/lib(64) as normal and in system/lib(64)/vndk as a vendor variant. Bug: 63866913 Test: build and boot with BOARD_VNDK_VERSION=current Change-Id: I4b9e560ca6d4751889a7b14f205e678b68c20008 --- libmemtrack/Android.bp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libmemtrack/Android.bp b/libmemtrack/Android.bp index 68c580a45..095563384 100644 --- a/libmemtrack/Android.bp +++ b/libmemtrack/Android.bp @@ -2,6 +2,10 @@ cc_library_shared { name: "libmemtrack", + vendor_available: true, + vndk: { + enabled: true, + }, srcs: ["memtrack.cpp"], export_include_dirs: ["include"], local_include_dirs: ["include"], From aadcb26adbcad2f365919c3e24cd6d7f4c59f44d Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Tue, 1 Aug 2017 16:33:11 -0700 Subject: [PATCH 040/129] Move android_filesystem_config.h => fs_config.h The non AID_ things in android_filesystem_config.h are moved to fs_config.h. For libcutils.vendor and libcutils_headers.vendor, fs_config.h is not exported. An empty system/core/include/private/fs_config.h is placed to appease the dependency from certain modules (logd, etc.) that includes system/core/include/private/android_filesystem_config.h directly. Test: m -j Test: BOARD_VNDK_VERSION=current m -j Bug: 63135587 Change-Id: I95dfb874a426941022b100c0ca26a0576b0f4aa3 Merged-In: I95dfb874a426941022b100c0ca26a0576b0f4aa3 --- include/private/fs_config.h | 4 ++ libcutils/canned_fs_config.c | 1 + .../cutils/android_filesystem_config.h | 1 + .../private/android_filesystem_config.h | 47 +------------------ libcutils/include/private/fs_config.h | 43 +++++++++++++++++ .../cutils/android_filesystem_config.h | 1 + 6 files changed, 52 insertions(+), 45 deletions(-) create mode 100644 include/private/fs_config.h create mode 120000 libcutils/include/cutils/android_filesystem_config.h create mode 120000 libcutils/include_vndk/cutils/android_filesystem_config.h diff --git a/include/private/fs_config.h b/include/private/fs_config.h new file mode 100644 index 000000000..e9868a41f --- /dev/null +++ b/include/private/fs_config.h @@ -0,0 +1,4 @@ +// TODO(b/63135587) remove this file after the transitive dependency +// from private/android_filesystem_config.h is resolved. All files that use +// libcutils/include/private/fs_config.h should include the file directly, not +// indirectly via private/android_filesystem_config.h. diff --git a/libcutils/canned_fs_config.c b/libcutils/canned_fs_config.c index 96ca566cd..819a846a6 100644 --- a/libcutils/canned_fs_config.c +++ b/libcutils/canned_fs_config.c @@ -23,6 +23,7 @@ #include #include +#include #include typedef struct { diff --git a/libcutils/include/cutils/android_filesystem_config.h b/libcutils/include/cutils/android_filesystem_config.h new file mode 120000 index 000000000..d2a92fefa --- /dev/null +++ b/libcutils/include/cutils/android_filesystem_config.h @@ -0,0 +1 @@ +../private/android_filesystem_config.h \ No newline at end of file diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h index 02141d687..d4ba01963 100644 --- a/libcutils/include/private/android_filesystem_config.h +++ b/libcutils/include/private/android_filesystem_config.h @@ -14,11 +14,6 @@ * limitations under the License. */ -/* This file is used to define the properties of the filesystem -** images generated by build tools (mkbootfs and mkyaffs2image) and -** by the device side of adb. -*/ - /* * This file is consumed by build/tools/fs_config and is used * for generating various files. Anything #define AID_ @@ -49,18 +44,12 @@ #ifndef _ANDROID_FILESYSTEM_CONFIG_H_ #define _ANDROID_FILESYSTEM_CONFIG_H_ -#include -#include #include -#if defined(__BIONIC__) -#include -#else -#include "android_filesystem_capability.h" +#if !defined(__ANDROID_VNDK__) && !defined(EXCLUDE_FS_CONFIG_STRUCTURES) +#include #endif -#define CAP_MASK_LONG(cap_name) (1ULL << (cap_name)) - /* This is the master Users and Groups config for the platform. * DO NOT EVER RENUMBER */ @@ -193,36 +182,4 @@ * Also see build/tools/fs_config for more details. */ -#if !defined(EXCLUDE_FS_CONFIG_STRUCTURES) - -struct fs_path_config { - unsigned mode; - unsigned uid; - unsigned gid; - uint64_t capabilities; - const char* prefix; -}; - -/* Rules for directories and files has moved to system/code/libcutils/fs_config.c */ - -__BEGIN_DECLS - -/* - * Used in: - * build/tools/fs_config/fs_config.c - * build/tools/fs_get_stats/fs_get_stats.c - * system/extras/ext4_utils/make_ext4fs_main.c - * external/squashfs-tools/squashfs-tools/android.c - * system/core/cpio/mkbootfs.c - * system/core/adb/file_sync_service.cpp - * system/extras/ext4_utils/canned_fs_config.c - */ -void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid, - unsigned* mode, uint64_t* capabilities); - -ssize_t fs_config_generate(char* buffer, size_t length, const struct fs_path_config* pc); - -__END_DECLS - -#endif #endif diff --git a/libcutils/include/private/fs_config.h b/libcutils/include/private/fs_config.h index 7dad668aa..aab504281 100644 --- a/libcutils/include/private/fs_config.h +++ b/libcutils/include/private/fs_config.h @@ -14,10 +14,24 @@ * limitations under the License. */ +/* This file is used to define the properties of the filesystem +** images generated by build tools (mkbootfs and mkyaffs2image) and +** by the device side of adb. +*/ + #ifndef _LIBS_CUTILS_PRIVATE_FS_CONFIG_H #define _LIBS_CUTILS_PRIVATE_FS_CONFIG_H #include +#include + +#if defined(__BIONIC__) +#include +#else // defined(__BIONIC__) +#include "android_filesystem_capability.h" +#endif // defined(__BIONIC__) + +#define CAP_MASK_LONG(cap_name) (1ULL << (cap_name)) /* * binary format for the runtime /etc/fs_config_(dirs|files) @@ -34,4 +48,33 @@ struct fs_path_config_from_file { char prefix[]; } __attribute__((__aligned__(sizeof(uint64_t)))); +struct fs_path_config { + unsigned mode; + unsigned uid; + unsigned gid; + uint64_t capabilities; + const char* prefix; +}; + +/* Rules for directories and files has moved to system/code/libcutils/fs_config.c */ + +__BEGIN_DECLS + +/* + * Used in: + * build/tools/fs_config/fs_config.c + * build/tools/fs_get_stats/fs_get_stats.c + * system/extras/ext4_utils/make_ext4fs_main.c + * external/squashfs-tools/squashfs-tools/android.c + * system/core/cpio/mkbootfs.c + * system/core/adb/file_sync_service.cpp + * system/extras/ext4_utils/canned_fs_config.c + */ +void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid, + unsigned* mode, uint64_t* capabilities); + +ssize_t fs_config_generate(char* buffer, size_t length, const struct fs_path_config* pc); + +__END_DECLS + #endif /* _LIBS_CUTILS_PRIVATE_FS_CONFIG_H */ diff --git a/libcutils/include_vndk/cutils/android_filesystem_config.h b/libcutils/include_vndk/cutils/android_filesystem_config.h new file mode 120000 index 000000000..13a5a08ef --- /dev/null +++ b/libcutils/include_vndk/cutils/android_filesystem_config.h @@ -0,0 +1 @@ +../../include/private/android_filesystem_config.h \ No newline at end of file From ccae2b5779e01e885bd7c85e314a2f8f523c4b94 Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Wed, 2 Aug 2017 17:37:40 -0700 Subject: [PATCH 041/129] storaged: fix excessive accounting when io usage has negative delta When current io bytes are smaller than previous bytes, add 0 to delta instead of adding current io bytes. Bug: 64317562 Merged-In: If0c9814892ad61b790baa6395649af10b11d5b7c Change-Id: I1ffd7ac33649ab3b8405c83b1328fa9bf49702c0 --- storaged/storaged_uid_monitor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/storaged/storaged_uid_monitor.cpp b/storaged/storaged_uid_monitor.cpp index 5bb98e1e8..dd398b5ca 100644 --- a/storaged/storaged_uid_monitor.cpp +++ b/storaged/storaged_uid_monitor.cpp @@ -228,13 +228,13 @@ void uid_monitor::update_curr_io_stats_locked() last_uid_io_stats[uid.uid].io[BACKGROUND].write_bytes; usage.bytes[READ][FOREGROUND][charger_stat] += - (fg_rd_delta < 0) ? uid.io[FOREGROUND].read_bytes : fg_rd_delta; + (fg_rd_delta < 0) ? 0 : fg_rd_delta; usage.bytes[READ][BACKGROUND][charger_stat] += - (bg_rd_delta < 0) ? uid.io[BACKGROUND].read_bytes : bg_rd_delta; + (bg_rd_delta < 0) ? 0 : bg_rd_delta; usage.bytes[WRITE][FOREGROUND][charger_stat] += - (fg_wr_delta < 0) ? uid.io[FOREGROUND].write_bytes : fg_wr_delta; + (fg_wr_delta < 0) ? 0 : fg_wr_delta; usage.bytes[WRITE][BACKGROUND][charger_stat] += - (bg_wr_delta < 0) ? uid.io[BACKGROUND].write_bytes : bg_wr_delta; + (bg_wr_delta < 0) ? 0 : bg_wr_delta; } last_uid_io_stats = uid_io_stats; From 7d4cf3fd3364a86c895371337a849ab40c99b232 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Fri, 4 Aug 2017 16:18:03 +0900 Subject: [PATCH 042/129] Permit /system/lib/vndk-sp/hw/ for 'sphal' namespace android.hidl.memory@1.0-impl.so is a SP-HAL located in /system/lib/vndk-sp/hw. This can't be moved to /vendor/lib since it is a framework HAL. Bug: 62930720 Test: 2017 pixel builds and boots with BOARD_VNDK_VERSION on Change-Id: I9c456983ef68120c5e8c629efc6dd66a26220ecb --- rootdir/etc/ld.config.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index d0418883d..5dcb8065d 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt @@ -54,7 +54,7 @@ namespace.default.asan.permitted.paths = /data/asan/system/${LIB}:/system/${LIB} namespace.sphal.isolated = true namespace.sphal.visible = true namespace.sphal.search.paths = /vendor/${LIB}/egl:/vendor/${LIB}/hw:/vendor/${LIB} -namespace.sphal.permitted.paths = /vendor/${LIB} +namespace.sphal.permitted.paths = /vendor/${LIB}:/system/${LIB}/vndk-sp/hw namespace.sphal.asan.search.paths = /data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl:/data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}:/vendor/${LIB} namespace.sphal.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB} From 9c54268dce4c82f066e24dfc40803192f537e35f Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Fri, 28 Jul 2017 18:45:59 -0700 Subject: [PATCH 043/129] storaged: call getNamesForUids to get uid names Calls getNamesForUids when one of the two conditions are true. 1. entries for new uids are reported from io stats 2. previous getNamesForUids failed Bug: 62805090 Merged-In: I120b81e1857b2aa0a90d0fb85c8d749e985df78e Change-Id: I120b81e1857b2aa0a90d0fb85c8d749e985df78e --- storaged/Android.mk | 1 - storaged/storaged_uid_monitor.cpp | 70 +++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/storaged/Android.mk b/storaged/Android.mk index 5e6a3c0a1..a1abe0fd1 100644 --- a/storaged/Android.mk +++ b/storaged/Android.mk @@ -9,7 +9,6 @@ LIBSTORAGED_SHARED_LIBRARIES := \ libcutils \ liblog \ libsysutils \ - libpackagelistparser \ libbatteryservice \ include $(CLEAR_VARS) diff --git a/storaged/storaged_uid_monitor.cpp b/storaged/storaged_uid_monitor.cpp index dd398b5ca..dd8bdd6e8 100644 --- a/storaged/storaged_uid_monitor.cpp +++ b/storaged/storaged_uid_monitor.cpp @@ -22,33 +22,24 @@ #include #include +#include #include #include #include #include #include #include +#include #include -#include #include "storaged.h" #include "storaged_uid_monitor.h" using namespace android; using namespace android::base; +using namespace android::content::pm; -static bool packagelist_parse_cb(pkg_info* info, void* userdata) -{ - std::unordered_map* uids = - reinterpret_cast*>(userdata); - - if (uids->find(info->uid) != uids->end()) { - (*uids)[info->uid].name = info->name; - } - - packagelist_free(info); - return true; -} +static bool refresh_uid_names; std::unordered_map uid_monitor::get_uid_io_stats() { @@ -56,6 +47,38 @@ std::unordered_map uid_monitor::get_uid_io_stats() return get_uid_io_stats_locked(); }; +static void get_uid_names(const vector& uids, const vector& uid_names) +{ + sp sm = defaultServiceManager(); + if (sm == NULL) { + LOG_TO(SYSTEM, ERROR) << "defaultServiceManager failed"; + return; + } + + sp binder = sm->getService(String16("package_native")); + if (binder == NULL) { + LOG_TO(SYSTEM, ERROR) << "getService package_native failed"; + return; + } + + sp package_mgr = interface_cast(binder); + std::vector names; + binder::Status status = package_mgr->getNamesForUids(uids, &names); + if (!status.isOk()) { + LOG_TO(SYSTEM, ERROR) << "package_native::getNamesForUids failed: " + << status.exceptionMessage(); + return; + } + + for (uint32_t i = 0; i < uid_names.size(); i++) { + if (!names[i].empty()) { + *uid_names[i] = names[i]; + } + } + + refresh_uid_names = false; +} + std::unordered_map uid_monitor::get_uid_io_stats_locked() { std::unordered_map uid_io_stats; @@ -67,7 +90,8 @@ std::unordered_map uid_monitor::get_uid_io_stats_lock std::vector io_stats = Split(buffer, "\n"); struct uid_info u; - bool refresh_uid = false; + vector uids; + vector uid_names; for (uint32_t i = 0; i < io_stats.size(); i++) { if (io_stats[i].empty()) { @@ -91,17 +115,19 @@ std::unordered_map uid_monitor::get_uid_io_stats_lock continue; } - if (last_uid_io_stats.find(u.uid) == last_uid_io_stats.end()) { - refresh_uid = true; - u.name = std::to_string(u.uid); - } else { - u.name = last_uid_io_stats[u.uid].name; - } uid_io_stats[u.uid] = u; + uid_io_stats[u.uid].name = std::to_string(u.uid); + uids.push_back(u.uid); + uid_names.push_back(&uid_io_stats[u.uid].name); + if (last_uid_io_stats.find(u.uid) == last_uid_io_stats.end()) { + refresh_uid_names = true; + } else { + uid_io_stats[u.uid].name = last_uid_io_stats[u.uid].name; + } } - if (refresh_uid) { - packagelist_parse(packagelist_parse_cb, &uid_io_stats); + if (!uids.empty() && refresh_uid_names) { + get_uid_names(uids, uid_names); } return uid_io_stats; From 7d81b4e08172037674f378ffb6f45ad694c01077 Mon Sep 17 00:00:00 2001 From: Hung-ying Tyan Date: Fri, 28 Jul 2017 19:09:33 +0800 Subject: [PATCH 044/129] Move trusty reference implementations to /vendor Trusty implementations are provided by vendors. This patch moves the AOSP reference implementations to the vendor partition. Bug: 63085384 Test: build gordon_peak which adopts trusty as the TEE and confirm that libtrusty and gateway.trusty are moved to /vendor. Test: build marlin which does not adopt trusty as the TEE and confirm that this patch has no effect on the build result. Change-Id: I9a5440071386b929058207fdef560ed2d7223ba3 --- CleanSpec.mk | 8 ++++++++ trusty/gatekeeper/Android.bp | 1 + trusty/keymaster/Android.bp | 2 ++ trusty/libtrusty/Android.bp | 1 + trusty/storage/proxy/Android.bp | 1 + 5 files changed, 13 insertions(+) diff --git a/CleanSpec.mk b/CleanSpec.mk index 5b5eff406..9fe59086c 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -60,3 +60,11 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.$(TARGET_D $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.$(TARGET_DEVICE).so) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/vendor) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/init.rc) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libtrusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/libtrusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/keystore.trusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/keystore.trusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.trusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.trusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/storageproxyd.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/trusty_keymaster_tipc.so) diff --git a/trusty/gatekeeper/Android.bp b/trusty/gatekeeper/Android.bp index a9566a17e..011f4a1c6 100644 --- a/trusty/gatekeeper/Android.bp +++ b/trusty/gatekeeper/Android.bp @@ -22,6 +22,7 @@ cc_library_shared { name: "gatekeeper.trusty", + vendor: true, relative_install_path: "hw", diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp index 6b9d72359..6dcfb208b 100644 --- a/trusty/keymaster/Android.bp +++ b/trusty/keymaster/Android.bp @@ -25,6 +25,7 @@ // and ECDSA keys. cc_binary { name: "trusty_keymaster_tipc", + vendor: true, srcs: [ "trusty_keymaster_device.cpp", "trusty_keymaster_ipc.cpp", @@ -45,6 +46,7 @@ cc_binary { // keystore.trusty is the HAL used by keystore on Trusty devices. cc_library_shared { name: "keystore.trusty", + vendor: true, relative_install_path: "hw", srcs: [ "module.cpp", diff --git a/trusty/libtrusty/Android.bp b/trusty/libtrusty/Android.bp index f316da229..88d624048 100644 --- a/trusty/libtrusty/Android.bp +++ b/trusty/libtrusty/Android.bp @@ -18,6 +18,7 @@ subdirs = [ cc_library { name: "libtrusty", + vendor: true, srcs: ["trusty.c"], export_include_dirs: ["include"], diff --git a/trusty/storage/proxy/Android.bp b/trusty/storage/proxy/Android.bp index eb34df014..4088696ce 100644 --- a/trusty/storage/proxy/Android.bp +++ b/trusty/storage/proxy/Android.bp @@ -16,6 +16,7 @@ cc_binary { name: "storageproxyd", + vendor: true, srcs: [ "ipc.c", From dadd3a846fae03b1d4416fcb8f2499b8296d9e83 Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Thu, 10 Aug 2017 17:39:30 +0900 Subject: [PATCH 045/129] Move libz vndk-sp from ll-ndk The ABI of libz is not as stable as it is for ll-ndk. Bug: 37617391 Test: build and boot Change-Id: I883bc6fda268e98cc7cdd5888264170c58688794 --- rootdir/etc/ld.config.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index 5dcb8065d..79a27a0d2 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt @@ -64,10 +64,10 @@ namespace.sphal.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB} namespace.sphal.links = default,vndk,rs # WARNING: only NDK libs can be listed here. -namespace.sphal.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libvndksupport.so +namespace.sphal.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libvndksupport.so # WARNING: only VNDK-SP libs can be listed here. DO NOT EDIT this line. -namespace.sphal.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so +namespace.sphal.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so:libz.so # Renderscript gets separate namespace namespace.sphal.link.rs.shared_libs = libRS_internal.so @@ -88,8 +88,8 @@ namespace.rs.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB} namespace.rs.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data namespace.rs.links = default,vndk -namespace.rs.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libvndksupport.so -namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so +namespace.rs.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libvndksupport.so +namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so:libz.so ############################################################################### # "vndk" namespace @@ -107,7 +107,7 @@ namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB} # to the default namespace. This is possible since their ABI is stable across # Android releases. namespace.vndk.links = default -namespace.vndk.link.default.shared_libs = android.hidl.memory@1.0-impl.so:libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libvndksupport.so +namespace.vndk.link.default.shared_libs = android.hidl.memory@1.0-impl.so:libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libvndksupport.so ############################################################################### # Namespace config for vendor processes. In O, no restriction is enforced for From 5505eb783b0fdf12fda9b3e0613a12af52bd80b2 Mon Sep 17 00:00:00 2001 From: Hung-ying Tyan Date: Fri, 11 Aug 2017 08:02:21 +0000 Subject: [PATCH 046/129] Revert "Move trusty reference implementations to /vendor" The CL is not complete and will cause build break when BOARD_VNDK_VERSION is set. This reverts commit 7d81b4e08172037674f378ffb6f45ad694c01077. Change-Id: If9632fb7ee8147c39f1ad0860ddc3bed62ba89db --- CleanSpec.mk | 8 -------- trusty/gatekeeper/Android.bp | 1 - trusty/keymaster/Android.bp | 2 -- trusty/libtrusty/Android.bp | 1 - trusty/storage/proxy/Android.bp | 1 - 5 files changed, 13 deletions(-) diff --git a/CleanSpec.mk b/CleanSpec.mk index 9fe59086c..5b5eff406 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -60,11 +60,3 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.$(TARGET_D $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.$(TARGET_DEVICE).so) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/vendor) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/init.rc) -$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libtrusty.so) -$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/libtrusty.so) -$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/keystore.trusty.so) -$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/keystore.trusty.so) -$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.trusty.so) -$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.trusty.so) -$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/storageproxyd.so) -$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/trusty_keymaster_tipc.so) diff --git a/trusty/gatekeeper/Android.bp b/trusty/gatekeeper/Android.bp index 011f4a1c6..a9566a17e 100644 --- a/trusty/gatekeeper/Android.bp +++ b/trusty/gatekeeper/Android.bp @@ -22,7 +22,6 @@ cc_library_shared { name: "gatekeeper.trusty", - vendor: true, relative_install_path: "hw", diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp index 6dcfb208b..6b9d72359 100644 --- a/trusty/keymaster/Android.bp +++ b/trusty/keymaster/Android.bp @@ -25,7 +25,6 @@ // and ECDSA keys. cc_binary { name: "trusty_keymaster_tipc", - vendor: true, srcs: [ "trusty_keymaster_device.cpp", "trusty_keymaster_ipc.cpp", @@ -46,7 +45,6 @@ cc_binary { // keystore.trusty is the HAL used by keystore on Trusty devices. cc_library_shared { name: "keystore.trusty", - vendor: true, relative_install_path: "hw", srcs: [ "module.cpp", diff --git a/trusty/libtrusty/Android.bp b/trusty/libtrusty/Android.bp index 88d624048..f316da229 100644 --- a/trusty/libtrusty/Android.bp +++ b/trusty/libtrusty/Android.bp @@ -18,7 +18,6 @@ subdirs = [ cc_library { name: "libtrusty", - vendor: true, srcs: ["trusty.c"], export_include_dirs: ["include"], diff --git a/trusty/storage/proxy/Android.bp b/trusty/storage/proxy/Android.bp index 4088696ce..eb34df014 100644 --- a/trusty/storage/proxy/Android.bp +++ b/trusty/storage/proxy/Android.bp @@ -16,7 +16,6 @@ cc_binary { name: "storageproxyd", - vendor: true, srcs: [ "ipc.c", From 077dc8fca4f2f07a014695cf6c8a70611b8607ab Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Thu, 3 Aug 2017 15:51:33 +0900 Subject: [PATCH 047/129] Mark libziparchive as VNDK in Android.bp As a VNDK module, Android.bp must have 'vndk' tag as well as 'vendor_available: true'. The 'vndk' tag for VNDK module is formated as below: vndk: { enabled: true, }, VNDK modules will be installed both in system/lib(64) as normal and in system/lib(64)/vndk as a vendor variant. Bug: 63866913 Test: build and boot with BOARD_VNDK_VERSION=current Change-Id: Iec5d3496e91a99f3e6b0c816c67ad279672ff36a --- libziparchive/Android.bp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp index 333835c34..f395c7487 100644 --- a/libziparchive/Android.bp +++ b/libziparchive/Android.bp @@ -58,6 +58,9 @@ cc_library { name: "libziparchive", host_supported: true, vendor_available: true, + vndk: { + enabled: true, + }, defaults: [ "libziparchive_defaults", From 16380365c4f665d17927e507f606a02e59e6f167 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Thu, 10 Aug 2017 12:22:44 -0700 Subject: [PATCH 048/129] init: split security functions out of init.cpp This change splits out the selinux initialization and supporting functionality into selinux.cpp and splits the security related initialization of the rng, etc to security.cpp. It also provides additional documentation for SEPolicy loading as this has been requested by some teams. It additionally cleans up sehandle and sehandle_prop. The former is static within selinux.cpp and new wrapper functions are created around selabel_lookup*() to better serve the users. The latter is moved to property_service.cpp as it is isolated to that file for its usage. Test: boot bullhead Merged-In: Idc95d493cebc681fbe686b5160502f36af149f60 Change-Id: Idc95d493cebc681fbe686b5160502f36af149f60 (cherry picked from commit 9afb86b25d8675927cb37c86119a7ecf19f74819) --- init/Android.bp | 2 + init/builtins.cpp | 37 +-- init/descriptors.cpp | 3 +- init/devices.cpp | 34 +-- init/devices.h | 1 - init/devices_test.cpp | 6 +- init/init.cpp | 610 +------------------------------------- init/init.h | 5 +- init/property_service.cpp | 23 +- init/reboot.cpp | 1 + init/security.cpp | 209 +++++++++++++ init/security.h | 33 +++ init/selinux.cpp | 462 +++++++++++++++++++++++++++++ init/selinux.h | 40 +++ init/ueventd.cpp | 6 +- init/util.cpp | 49 ++- init/util.h | 6 +- init/util_test.cpp | 4 +- 18 files changed, 844 insertions(+), 687 deletions(-) create mode 100644 init/security.cpp create mode 100644 init/security.h create mode 100644 init/selinux.cpp create mode 100644 init/selinux.h diff --git a/init/Android.bp b/init/Android.bp index 432c29870..db64f71d4 100644 --- a/init/Android.bp +++ b/init/Android.bp @@ -70,6 +70,8 @@ cc_library_static { "log.cpp", "parser.cpp", "property_service.cpp", + "security.cpp", + "selinux.cpp", "service.cpp", "tokenizer.cpp", "uevent_listener.cpp", diff --git a/init/builtins.cpp b/init/builtins.cpp index 0f5ae2bdc..48500fd3a 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -224,23 +224,22 @@ static int do_insmod(const std::vector& args) { return insmod(filename.c_str(), options.c_str(), flags); } +// mkdir [mode] [owner] [group] static int do_mkdir(const std::vector& args) { mode_t mode = 0755; - int ret; - - /* mkdir [mode] [owner] [group] */ - if (args.size() >= 3) { mode = std::strtoul(args[2].c_str(), 0, 8); } - ret = make_dir(args[1].c_str(), mode, sehandle); - /* chmod in case the directory already exists */ - if (ret == -1 && errno == EEXIST) { - ret = fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW); - } - if (ret == -1) { - return -errno; + if (!make_dir(args[1], mode)) { + /* chmod in case the directory already exists */ + if (errno == EEXIST) { + if (fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW) == -1) { + return -errno; + } + } else { + return -errno; + } } if (args.size() >= 4) { @@ -265,8 +264,7 @@ static int do_mkdir(const std::vector& args) { /* chown may have cleared S_ISUID and S_ISGID, chmod again */ if (mode & (S_ISUID | S_ISGID)) { - ret = fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW); - if (ret == -1) { + if (fchmodat(AT_FDCWD, args[1].c_str(), mode, AT_SYMLINK_NOFOLLOW) == -1) { return -errno; } } @@ -851,17 +849,6 @@ static int do_wait_for_prop(const std::vector& args) { return 0; } -/* - * Callback to make a directory from the ext4 code - */ -static int do_installkeys_ensure_dir_exists(const char* dir) { - if (make_dir(dir, 0700, sehandle) && errno != EEXIST) { - return -1; - } - - return 0; -} - static bool is_file_crypto() { return android::base::GetProperty("ro.crypto.type", "") == "file"; } @@ -871,7 +858,7 @@ static int do_installkey(const std::vector& args) { return 0; } auto unencrypted_dir = args[1] + e4crypt_unencrypted_folder; - if (do_installkeys_ensure_dir_exists(unencrypted_dir.c_str())) { + if (!make_dir(unencrypted_dir, 0700) && errno != EEXIST) { PLOG(ERROR) << "Failed to create " << unencrypted_dir; return -1; } diff --git a/init/descriptors.cpp b/init/descriptors.cpp index 0cb639a91..cc5b948e9 100644 --- a/init/descriptors.cpp +++ b/init/descriptors.cpp @@ -86,8 +86,7 @@ int SocketInfo::Create(const std::string& context) const { int flags = ((types[0] == "stream" ? SOCK_STREAM : (types[0] == "dgram" ? SOCK_DGRAM : SOCK_SEQPACKET))); bool passcred = types.size() > 1 && types[1] == "passcred"; - return CreateSocket(name().c_str(), flags, passcred, perm(), uid(), gid(), context.c_str(), - sehandle); + return CreateSocket(name().c_str(), flags, passcred, perm(), uid(), gid(), context.c_str()); } const std::string SocketInfo::key() const { diff --git a/init/devices.cpp b/init/devices.cpp index 13cf991ca..d59f53c74 100644 --- a/init/devices.cpp +++ b/init/devices.cpp @@ -30,6 +30,7 @@ #include #include +#include "selinux.h" #include "ueventd.h" #include "util.h" @@ -224,18 +225,13 @@ void DeviceHandler::MakeDevice(const std::string& path, bool block, int major, i auto[mode, uid, gid] = GetDevicePermissions(path, links); mode |= (block ? S_IFBLK : S_IFCHR); - char* secontext = nullptr; - if (sehandle_) { - std::vector c_links; - for (const auto& link : links) { - c_links.emplace_back(link.c_str()); - } - c_links.emplace_back(nullptr); - if (selabel_lookup_best_match(sehandle_, &secontext, path.c_str(), &c_links[0], mode)) { - PLOG(ERROR) << "Device '" << path << "' not created; cannot find SELinux label"; - return; - } - setfscreatecon(secontext); + std::string secontext; + if (!SelabelLookupFileContextBestMatch(path, links, mode, &secontext)) { + PLOG(ERROR) << "Device '" << path << "' not created; cannot find SELinux label"; + return; + } + if (!secontext.empty()) { + setfscreatecon(secontext.c_str()); } dev_t dev = makedev(major, minor); @@ -250,7 +246,7 @@ void DeviceHandler::MakeDevice(const std::string& path, bool block, int major, i } /* If the node already exists update its SELinux label to handle cases when * it was created with the wrong context during coldboot procedure. */ - if (mknod(path.c_str(), mode, dev) && (errno == EEXIST) && secontext) { + if (mknod(path.c_str(), mode, dev) && (errno == EEXIST) && !secontext.empty()) { char* fcon = nullptr; int rc = lgetfilecon(path.c_str(), &fcon); if (rc < 0) { @@ -258,10 +254,10 @@ void DeviceHandler::MakeDevice(const std::string& path, bool block, int major, i goto out; } - bool different = strcmp(fcon, secontext) != 0; + bool different = fcon != secontext; freecon(fcon); - if (different && lsetfilecon(path.c_str(), secontext)) { + if (different && lsetfilecon(path.c_str(), secontext.c_str())) { PLOG(ERROR) << "Cannot set '" << secontext << "' SELinux label on '" << path << "' device"; } @@ -273,8 +269,7 @@ out: PLOG(FATAL) << "setegid(AID_ROOT) failed"; } - if (secontext) { - freecon(secontext); + if (!secontext.empty()) { setfscreatecon(nullptr); } } @@ -351,7 +346,7 @@ void DeviceHandler::HandleDevice(const std::string& action, const std::string& d if (action == "add") { MakeDevice(devpath, block, major, minor, links); for (const auto& link : links) { - if (mkdir_recursive(Dirname(link), 0755, sehandle_)) { + if (!mkdir_recursive(Dirname(link), 0755)) { PLOG(ERROR) << "Failed to create directory " << Dirname(link); } @@ -415,7 +410,7 @@ void DeviceHandler::HandleDeviceEvent(const Uevent& uevent) { devpath = "/dev/" + Basename(uevent.path); } - mkdir_recursive(Dirname(devpath), 0755, sehandle_); + mkdir_recursive(Dirname(devpath), 0755); HandleDevice(uevent.action, devpath, block, uevent.major, uevent.minor, links); } @@ -426,7 +421,6 @@ DeviceHandler::DeviceHandler(std::vector dev_permissions, : dev_permissions_(std::move(dev_permissions)), sysfs_permissions_(std::move(sysfs_permissions)), subsystems_(std::move(subsystems)), - sehandle_(selinux_android_file_context_handle()), skip_restorecon_(skip_restorecon), sysfs_mount_point_("/sys") {} diff --git a/init/devices.h b/init/devices.h index c64f5fb97..dd44337dc 100644 --- a/init/devices.h +++ b/init/devices.h @@ -124,7 +124,6 @@ class DeviceHandler { std::vector dev_permissions_; std::vector sysfs_permissions_; std::vector subsystems_; - selabel_handle* sehandle_; bool skip_restorecon_; std::string sysfs_mount_point_; }; diff --git a/init/devices_test.cpp b/init/devices_test.cpp index ac4ab9b30..eba00cb78 100644 --- a/init/devices_test.cpp +++ b/init/devices_test.cpp @@ -35,13 +35,13 @@ class DeviceHandlerTester { device_handler_.sysfs_mount_point_ = fake_sys_root.path; std::string platform_device_dir = fake_sys_root.path + platform_device; - mkdir_recursive(platform_device_dir, 0777, nullptr); + mkdir_recursive(platform_device_dir, 0777); std::string platform_bus = fake_sys_root.path + "/bus/platform"s; - mkdir_recursive(platform_bus, 0777, nullptr); + mkdir_recursive(platform_bus, 0777); symlink(platform_bus.c_str(), (platform_device_dir + "/subsystem").c_str()); - mkdir_recursive(android::base::Dirname(fake_sys_root.path + uevent.path), 0777, nullptr); + mkdir_recursive(android::base::Dirname(fake_sys_root.path + uevent.path), 0777); std::vector result; result = device_handler_.GetBlockDeviceSymlinks(uevent); diff --git a/init/init.cpp b/init/init.cpp index f340bc2b9..ee3a84c29 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -16,27 +16,17 @@ #include "init.h" -#include #include -#include #include -#include -#include #include #include #include -#include -#include #include #include #include #include -#include -#include #include #include -#include -#include #include #include @@ -44,25 +34,22 @@ #include #include #include -#include #include #include #include #include -#include -#include #include #include -#include -#include "bootchart.h" #include "import_parser.h" #include "init_first_stage.h" #include "keychords.h" #include "log.h" #include "property_service.h" #include "reboot.h" +#include "security.h" +#include "selinux.h" #include "signal_handler.h" #include "ueventd.h" #include "util.h" @@ -73,14 +60,10 @@ using namespace std::string_literals; using android::base::boot_clock; using android::base::GetProperty; using android::base::Timer; -using android::base::unique_fd; namespace android { namespace init { -struct selabel_handle *sehandle; -struct selabel_handle *sehandle_prop; - static int property_triggers_enabled = 0; static char qemu[32]; @@ -277,194 +260,6 @@ static int wait_for_coldboot_done_action(const std::vector& args) { return 0; } -/* - * Writes 512 bytes of output from Hardware RNG (/dev/hw_random, backed - * by Linux kernel's hw_random framework) into Linux RNG's via /dev/urandom. - * Does nothing if Hardware RNG is not present. - * - * Since we don't yet trust the quality of Hardware RNG, these bytes are not - * mixed into the primary pool of Linux RNG and the entropy estimate is left - * unmodified. - * - * If the HW RNG device /dev/hw_random is present, we require that at least - * 512 bytes read from it are written into Linux RNG. QA is expected to catch - * devices/configurations where these I/O operations are blocking for a long - * time. We do not reboot or halt on failures, as this is a best-effort - * attempt. - */ -static int mix_hwrng_into_linux_rng_action(const std::vector& args) { - unique_fd hwrandom_fd( - TEMP_FAILURE_RETRY(open("/dev/hw_random", O_RDONLY | O_NOFOLLOW | O_CLOEXEC))); - if (hwrandom_fd == -1) { - if (errno == ENOENT) { - LOG(INFO) << "/dev/hw_random not found"; - // It's not an error to not have a Hardware RNG. - return 0; - } - PLOG(ERROR) << "Failed to open /dev/hw_random"; - return -1; - } - - unique_fd urandom_fd( - TEMP_FAILURE_RETRY(open("/dev/urandom", O_WRONLY | O_NOFOLLOW | O_CLOEXEC))); - if (urandom_fd == -1) { - PLOG(ERROR) << "Failed to open /dev/urandom"; - return -1; - } - - char buf[512]; - size_t total_bytes_written = 0; - while (total_bytes_written < sizeof(buf)) { - ssize_t chunk_size = - TEMP_FAILURE_RETRY(read(hwrandom_fd, buf, sizeof(buf) - total_bytes_written)); - if (chunk_size == -1) { - PLOG(ERROR) << "Failed to read from /dev/hw_random"; - return -1; - } else if (chunk_size == 0) { - LOG(ERROR) << "Failed to read from /dev/hw_random: EOF"; - return -1; - } - - chunk_size = TEMP_FAILURE_RETRY(write(urandom_fd, buf, chunk_size)); - if (chunk_size == -1) { - PLOG(ERROR) << "Failed to write to /dev/urandom"; - return -1; - } - total_bytes_written += chunk_size; - } - - LOG(INFO) << "Mixed " << total_bytes_written << " bytes from /dev/hw_random into /dev/urandom"; - return 0; -} - -static void security_failure() { - LOG(ERROR) << "Security failure..."; - panic(); -} - -static bool set_highest_available_option_value(std::string path, int min, int max) -{ - std::ifstream inf(path, std::fstream::in); - if (!inf) { - LOG(ERROR) << "Cannot open for reading: " << path; - return false; - } - - int current = max; - while (current >= min) { - // try to write out new value - std::string str_val = std::to_string(current); - std::ofstream of(path, std::fstream::out); - if (!of) { - LOG(ERROR) << "Cannot open for writing: " << path; - return false; - } - of << str_val << std::endl; - of.close(); - - // check to make sure it was recorded - inf.seekg(0); - std::string str_rec; - inf >> str_rec; - if (str_val.compare(str_rec) == 0) { - break; - } - current--; - } - inf.close(); - - if (current < min) { - LOG(ERROR) << "Unable to set minimum option value " << min << " in " << path; - return false; - } - return true; -} - -#define MMAP_RND_PATH "/proc/sys/vm/mmap_rnd_bits" -#define MMAP_RND_COMPAT_PATH "/proc/sys/vm/mmap_rnd_compat_bits" - -/* __attribute__((unused)) due to lack of mips support: see mips block - * in set_mmap_rnd_bits_action */ -static bool __attribute__((unused)) set_mmap_rnd_bits_min(int start, int min, bool compat) { - std::string path; - if (compat) { - path = MMAP_RND_COMPAT_PATH; - } else { - path = MMAP_RND_PATH; - } - - return set_highest_available_option_value(path, min, start); -} - -/* - * Set /proc/sys/vm/mmap_rnd_bits and potentially - * /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values. - * Returns -1 if unable to set these to an acceptable value. - * - * To support this sysctl, the following upstream commits are needed: - * - * d07e22597d1d mm: mmap: add new /proc tunable for mmap_base ASLR - * e0c25d958f78 arm: mm: support ARCH_MMAP_RND_BITS - * 8f0d3aa9de57 arm64: mm: support ARCH_MMAP_RND_BITS - * 9e08f57d684a x86: mm: support ARCH_MMAP_RND_BITS - * ec9ee4acd97c drivers: char: random: add get_random_long() - * 5ef11c35ce86 mm: ASLR: use get_random_long() - */ -static int set_mmap_rnd_bits_action(const std::vector& args) { -/* values are arch-dependent */ -#if defined(USER_MODE_LINUX) - /* uml does not support mmap_rnd_bits */ - return 0; -#elif defined(__aarch64__) - /* arm64 supports 18 - 33 bits depending on pagesize and VA_SIZE */ - if (set_mmap_rnd_bits_min(33, 24, false) - && set_mmap_rnd_bits_min(16, 16, true)) { - return 0; - } -#elif defined(__x86_64__) - /* x86_64 supports 28 - 32 bits */ - if (set_mmap_rnd_bits_min(32, 32, false) - && set_mmap_rnd_bits_min(16, 16, true)) { - return 0; - } -#elif defined(__arm__) || defined(__i386__) - /* check to see if we're running on 64-bit kernel */ - bool h64 = !access(MMAP_RND_COMPAT_PATH, F_OK); - /* supported 32-bit architecture must have 16 bits set */ - if (set_mmap_rnd_bits_min(16, 16, h64)) { - return 0; - } -#elif defined(__mips__) || defined(__mips64__) - // TODO: add mips support b/27788820 - return 0; -#else - LOG(ERROR) << "Unknown architecture"; -#endif - - LOG(ERROR) << "Unable to set adequate mmap entropy value!"; - security_failure(); - return -1; -} - -#define KPTR_RESTRICT_PATH "/proc/sys/kernel/kptr_restrict" -#define KPTR_RESTRICT_MINVALUE 2 -#define KPTR_RESTRICT_MAXVALUE 4 - -/* Set kptr_restrict to the highest available level. - * - * Aborts if unable to set this to an acceptable value. - */ -static int set_kptr_restrict_action(const std::vector& args) -{ - std::string path = KPTR_RESTRICT_PATH; - - if (!set_highest_available_option_value(path, KPTR_RESTRICT_MINVALUE, KPTR_RESTRICT_MAXVALUE)) { - LOG(ERROR) << "Unable to set adequate kptr_restrict value!"; - security_failure(); - } - return 0; -} - static int keychord_init_action(const std::vector& args) { keychord_init(); @@ -582,385 +377,6 @@ static void global_seccomp() { }); } -static void selinux_init_all_handles(void) -{ - sehandle = selinux_android_file_context_handle(); - selinux_android_set_sehandle(sehandle); - sehandle_prop = selinux_android_prop_context_handle(); -} - -enum selinux_enforcing_status { SELINUX_PERMISSIVE, SELINUX_ENFORCING }; - -static selinux_enforcing_status selinux_status_from_cmdline() { - selinux_enforcing_status status = SELINUX_ENFORCING; - - import_kernel_cmdline(false, [&](const std::string& key, const std::string& value, bool in_qemu) { - if (key == "androidboot.selinux" && value == "permissive") { - status = SELINUX_PERMISSIVE; - } - }); - - return status; -} - -static bool selinux_is_enforcing(void) -{ - if (ALLOW_PERMISSIVE_SELINUX) { - return selinux_status_from_cmdline() == SELINUX_ENFORCING; - } - return true; -} - -static int audit_callback(void *data, security_class_t /*cls*/, char *buf, size_t len) { - - property_audit_data *d = reinterpret_cast(data); - - if (!d || !d->name || !d->cr) { - LOG(ERROR) << "audit_callback invoked with null data arguments!"; - return 0; - } - - snprintf(buf, len, "property=%s pid=%d uid=%d gid=%d", d->name, - d->cr->pid, d->cr->uid, d->cr->gid); - return 0; -} - -/* - * Forks, executes the provided program in the child, and waits for the completion in the parent. - * Child's stderr is captured and logged using LOG(ERROR). - * - * Returns true if the child exited with status code 0, returns false otherwise. - */ -static bool fork_execve_and_wait_for_completion(const char* filename, char* const argv[], - char* const envp[]) { - // Create a pipe used for redirecting child process's output. - // * pipe_fds[0] is the FD the parent will use for reading. - // * pipe_fds[1] is the FD the child will use for writing. - int pipe_fds[2]; - if (pipe(pipe_fds) == -1) { - PLOG(ERROR) << "Failed to create pipe"; - return false; - } - - pid_t child_pid = fork(); - if (child_pid == -1) { - PLOG(ERROR) << "Failed to fork for " << filename; - return false; - } - - if (child_pid == 0) { - // fork succeeded -- this is executing in the child process - - // Close the pipe FD not used by this process - TEMP_FAILURE_RETRY(close(pipe_fds[0])); - - // Redirect stderr to the pipe FD provided by the parent - if (TEMP_FAILURE_RETRY(dup2(pipe_fds[1], STDERR_FILENO)) == -1) { - PLOG(ERROR) << "Failed to redirect stderr of " << filename; - _exit(127); - return false; - } - TEMP_FAILURE_RETRY(close(pipe_fds[1])); - - if (execve(filename, argv, envp) == -1) { - PLOG(ERROR) << "Failed to execve " << filename; - return false; - } - // Unreachable because execve will have succeeded and replaced this code - // with child process's code. - _exit(127); - return false; - } else { - // fork succeeded -- this is executing in the original/parent process - - // Close the pipe FD not used by this process - TEMP_FAILURE_RETRY(close(pipe_fds[1])); - - // Log the redirected output of the child process. - // It's unfortunate that there's no standard way to obtain an istream for a file descriptor. - // As a result, we're buffering all output and logging it in one go at the end of the - // invocation, instead of logging it as it comes in. - const int child_out_fd = pipe_fds[0]; - std::string child_output; - if (!android::base::ReadFdToString(child_out_fd, &child_output)) { - PLOG(ERROR) << "Failed to capture full output of " << filename; - } - TEMP_FAILURE_RETRY(close(child_out_fd)); - if (!child_output.empty()) { - // Log captured output, line by line, because LOG expects to be invoked for each line - std::istringstream in(child_output); - std::string line; - while (std::getline(in, line)) { - LOG(ERROR) << filename << ": " << line; - } - } - - // Wait for child to terminate - int status; - if (TEMP_FAILURE_RETRY(waitpid(child_pid, &status, 0)) != child_pid) { - PLOG(ERROR) << "Failed to wait for " << filename; - return false; - } - - if (WIFEXITED(status)) { - int status_code = WEXITSTATUS(status); - if (status_code == 0) { - return true; - } else { - LOG(ERROR) << filename << " exited with status " << status_code; - } - } else if (WIFSIGNALED(status)) { - LOG(ERROR) << filename << " killed by signal " << WTERMSIG(status); - } else if (WIFSTOPPED(status)) { - LOG(ERROR) << filename << " stopped by signal " << WSTOPSIG(status); - } else { - LOG(ERROR) << "waitpid for " << filename << " returned unexpected status: " << status; - } - - return false; - } -} - -static bool read_first_line(const char* file, std::string* line) { - line->clear(); - - std::string contents; - if (!android::base::ReadFileToString(file, &contents, true /* follow symlinks */)) { - return false; - } - std::istringstream in(contents); - std::getline(in, *line); - return true; -} - -static bool selinux_find_precompiled_split_policy(std::string* file) { - file->clear(); - - static constexpr const char precompiled_sepolicy[] = "/vendor/etc/selinux/precompiled_sepolicy"; - if (access(precompiled_sepolicy, R_OK) == -1) { - return false; - } - std::string actual_plat_id; - if (!read_first_line("/system/etc/selinux/plat_and_mapping_sepolicy.cil.sha256", - &actual_plat_id)) { - PLOG(INFO) << "Failed to read " - "/system/etc/selinux/plat_and_mapping_sepolicy.cil.sha256"; - return false; - } - std::string precompiled_plat_id; - if (!read_first_line("/vendor/etc/selinux/precompiled_sepolicy.plat_and_mapping.sha256", - &precompiled_plat_id)) { - PLOG(INFO) << "Failed to read " - "/vendor/etc/selinux/" - "precompiled_sepolicy.plat_and_mapping.sha256"; - return false; - } - if ((actual_plat_id.empty()) || (actual_plat_id != precompiled_plat_id)) { - return false; - } - - *file = precompiled_sepolicy; - return true; -} - -static bool selinux_get_vendor_mapping_version(std::string* plat_vers) { - if (!read_first_line("/vendor/etc/selinux/plat_sepolicy_vers.txt", plat_vers)) { - PLOG(ERROR) << "Failed to read /vendor/etc/selinux/plat_sepolicy_vers.txt"; - return false; - } - if (plat_vers->empty()) { - LOG(ERROR) << "No version present in plat_sepolicy_vers.txt"; - return false; - } - return true; -} - -static constexpr const char plat_policy_cil_file[] = "/system/etc/selinux/plat_sepolicy.cil"; - -static bool selinux_is_split_policy_device() { return access(plat_policy_cil_file, R_OK) != -1; } - -/* - * Loads SELinux policy split across platform/system and non-platform/vendor files. - * - * Returns true upon success, false otherwise (failure cause is logged). - */ -static bool selinux_load_split_policy() { - // IMPLEMENTATION NOTE: Split policy consists of three CIL files: - // * platform -- policy needed due to logic contained in the system image, - // * non-platform -- policy needed due to logic contained in the vendor image, - // * mapping -- mapping policy which helps preserve forward-compatibility of non-platform policy - // with newer versions of platform policy. - // - // secilc is invoked to compile the above three policy files into a single monolithic policy - // file. This file is then loaded into the kernel. - - // Load precompiled policy from vendor image, if a matching policy is found there. The policy - // must match the platform policy on the system image. - std::string precompiled_sepolicy_file; - if (selinux_find_precompiled_split_policy(&precompiled_sepolicy_file)) { - android::base::unique_fd fd( - open(precompiled_sepolicy_file.c_str(), O_RDONLY | O_CLOEXEC | O_BINARY)); - if (fd != -1) { - if (selinux_android_load_policy_from_fd(fd, precompiled_sepolicy_file.c_str()) < 0) { - LOG(ERROR) << "Failed to load SELinux policy from " << precompiled_sepolicy_file; - return false; - } - return true; - } - } - // No suitable precompiled policy could be loaded - - LOG(INFO) << "Compiling SELinux policy"; - - // Determine the highest policy language version supported by the kernel - set_selinuxmnt("/sys/fs/selinux"); - int max_policy_version = security_policyvers(); - if (max_policy_version == -1) { - PLOG(ERROR) << "Failed to determine highest policy version supported by kernel"; - return false; - } - - // We store the output of the compilation on /dev because this is the most convenient tmpfs - // storage mount available this early in the boot sequence. - char compiled_sepolicy[] = "/dev/sepolicy.XXXXXX"; - android::base::unique_fd compiled_sepolicy_fd(mkostemp(compiled_sepolicy, O_CLOEXEC)); - if (compiled_sepolicy_fd < 0) { - PLOG(ERROR) << "Failed to create temporary file " << compiled_sepolicy; - return false; - } - - // Determine which mapping file to include - std::string vend_plat_vers; - if (!selinux_get_vendor_mapping_version(&vend_plat_vers)) { - return false; - } - std::string mapping_file("/system/etc/selinux/mapping/" + vend_plat_vers + ".cil"); - // clang-format off - const char* compile_args[] = { - "/system/bin/secilc", - plat_policy_cil_file, - "-M", "true", "-G", "-N", - // Target the highest policy language version supported by the kernel - "-c", std::to_string(max_policy_version).c_str(), - mapping_file.c_str(), - "/vendor/etc/selinux/nonplat_sepolicy.cil", - "-o", compiled_sepolicy, - // We don't care about file_contexts output by the compiler - "-f", "/sys/fs/selinux/null", // /dev/null is not yet available - nullptr}; - // clang-format on - - if (!fork_execve_and_wait_for_completion(compile_args[0], (char**)compile_args, (char**)ENV)) { - unlink(compiled_sepolicy); - return false; - } - unlink(compiled_sepolicy); - - LOG(INFO) << "Loading compiled SELinux policy"; - if (selinux_android_load_policy_from_fd(compiled_sepolicy_fd, compiled_sepolicy) < 0) { - LOG(ERROR) << "Failed to load SELinux policy from " << compiled_sepolicy; - return false; - } - - return true; -} - -/* - * Loads SELinux policy from a monolithic file. - * - * Returns true upon success, false otherwise (failure cause is logged). - */ -static bool selinux_load_monolithic_policy() { - LOG(VERBOSE) << "Loading SELinux policy from monolithic file"; - if (selinux_android_load_policy() < 0) { - PLOG(ERROR) << "Failed to load monolithic SELinux policy"; - return false; - } - return true; -} - -/* - * Loads SELinux policy into the kernel. - * - * Returns true upon success, false otherwise (failure cause is logged). - */ -static bool selinux_load_policy() { - return selinux_is_split_policy_device() ? selinux_load_split_policy() - : selinux_load_monolithic_policy(); -} - -static void selinux_initialize(bool in_kernel_domain) { - Timer t; - - selinux_callback cb; - cb.func_log = selinux_klog_callback; - selinux_set_callback(SELINUX_CB_LOG, cb); - cb.func_audit = audit_callback; - selinux_set_callback(SELINUX_CB_AUDIT, cb); - - if (in_kernel_domain) { - LOG(INFO) << "Loading SELinux policy"; - if (!selinux_load_policy()) { - panic(); - } - - bool kernel_enforcing = (security_getenforce() == 1); - bool is_enforcing = selinux_is_enforcing(); - if (kernel_enforcing != is_enforcing) { - if (security_setenforce(is_enforcing)) { - PLOG(ERROR) << "security_setenforce(%s) failed" << (is_enforcing ? "true" : "false"); - security_failure(); - } - } - - std::string err; - if (!WriteFile("/sys/fs/selinux/checkreqprot", "0", &err)) { - LOG(ERROR) << err; - security_failure(); - } - - // init's first stage can't set properties, so pass the time to the second stage. - setenv("INIT_SELINUX_TOOK", std::to_string(t.duration().count()).c_str(), 1); - } else { - selinux_init_all_handles(); - } -} - -// The files and directories that were created before initial sepolicy load or -// files on ramdisk need to have their security context restored to the proper -// value. This must happen before /dev is populated by ueventd. -static void selinux_restore_context() { - LOG(INFO) << "Running restorecon..."; - selinux_android_restorecon("/dev", 0); - selinux_android_restorecon("/dev/kmsg", 0); - if constexpr (WORLD_WRITABLE_KMSG) { - selinux_android_restorecon("/dev/kmsg_debug", 0); - } - selinux_android_restorecon("/dev/socket", 0); - selinux_android_restorecon("/dev/random", 0); - selinux_android_restorecon("/dev/urandom", 0); - selinux_android_restorecon("/dev/__properties__", 0); - - selinux_android_restorecon("/plat_file_contexts", 0); - selinux_android_restorecon("/nonplat_file_contexts", 0); - selinux_android_restorecon("/plat_property_contexts", 0); - selinux_android_restorecon("/nonplat_property_contexts", 0); - selinux_android_restorecon("/plat_seapp_contexts", 0); - selinux_android_restorecon("/nonplat_seapp_contexts", 0); - selinux_android_restorecon("/plat_service_contexts", 0); - selinux_android_restorecon("/nonplat_service_contexts", 0); - selinux_android_restorecon("/plat_hwservice_contexts", 0); - selinux_android_restorecon("/nonplat_hwservice_contexts", 0); - selinux_android_restorecon("/sepolicy", 0); - selinux_android_restorecon("/vndservice_contexts", 0); - - selinux_android_restorecon("/dev/block", SELINUX_ANDROID_RESTORECON_RECURSE); - selinux_android_restorecon("/dev/device-mapper", 0); - - selinux_android_restorecon("/sbin/mke2fs_static", 0); - selinux_android_restorecon("/sbin/e2fsdroid_static", 0); -} - // Set the UDC controller for the ConfigFS USB Gadgets. // Read the UDC controller in use from "/sys/class/udc". // In case of multiple UDC controllers select the first one. @@ -1066,13 +482,14 @@ int main(int argc, char** argv) { global_seccomp(); // Set up SELinux, loading the SELinux policy. - selinux_initialize(true); + SelinuxSetupKernelLogging(); + SelinuxInitialize(); // We're in the kernel domain, so re-exec init to transition to the init domain now // that the SELinux policy has been loaded. if (selinux_android_restorecon("/init", 0) == -1) { - PLOG(ERROR) << "restorecon failed"; - security_failure(); + PLOG(ERROR) << "restorecon failed of /init failed"; + panic(); } setenv("INIT_SECOND_STAGE", "true", 1); @@ -1088,7 +505,7 @@ int main(int argc, char** argv) { // execv() only returns if an error happened, in which case we // panic and never fall through this conditional. PLOG(ERROR) << "execv(\"" << path << "\") failed"; - security_failure(); + panic(); } // At this point we're in the second stage of init. @@ -1129,8 +546,9 @@ int main(int argc, char** argv) { unsetenv("INIT_AVB_VERSION"); // Now set up SELinux for second stage. - selinux_initialize(false); - selinux_restore_context(); + SelinuxSetupKernelLogging(); + SelabelInitialize(); + SelinuxRestoreContext(); epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (epoll_fd == -1) { @@ -1162,9 +580,9 @@ int main(int argc, char** argv) { // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev... am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done"); // ... so that we can start queuing up actions that require stuff from /dev. - am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); - am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits"); - am.QueueBuiltinAction(set_kptr_restrict_action, "set_kptr_restrict"); + am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng"); + am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits"); + am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict"); am.QueueBuiltinAction(keychord_init_action, "keychord_init"); am.QueueBuiltinAction(console_init_action, "console_init"); @@ -1173,7 +591,7 @@ int main(int argc, char** argv) { // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random // wasn't ready immediately after wait_for_coldboot_done - am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); + am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng"); // Don't mount filesystems or start core system services in charger mode. std::string bootmode = GetProperty("ro.bootmode", ""); diff --git a/init/init.h b/init/init.h index 92b9b7003..50a7c8352 100644 --- a/init/init.h +++ b/init/init.h @@ -18,8 +18,7 @@ #define _INIT_INIT_H #include - -#include +#include #include "action.h" #include "parser.h" @@ -33,8 +32,6 @@ namespace init { // TODO: Have an Init class and remove all globals. extern const char *ENV[32]; extern std::string default_console; -extern struct selabel_handle *sehandle; -extern struct selabel_handle *sehandle_prop; extern std::vector late_import_paths; diff --git a/init/property_service.cpp b/init/property_service.cpp index fd14bd66f..bd42913b6 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -68,6 +68,8 @@ static int persistent_properties_loaded = 0; static int property_set_fd = -1; +static struct selabel_handle* sehandle_prop; + void property_init() { if (__system_property_area_init()) { LOG(ERROR) << "Failed to initialize property area"; @@ -740,11 +742,30 @@ void load_system_props() { load_recovery_id_prop(); } +static int SelinuxAuditCallback(void* data, security_class_t /*cls*/, char* buf, size_t len) { + property_audit_data* d = reinterpret_cast(data); + + if (!d || !d->name || !d->cr) { + LOG(ERROR) << "AuditCallback invoked with null data arguments!"; + return 0; + } + + snprintf(buf, len, "property=%s pid=%d uid=%d gid=%d", d->name, d->cr->pid, d->cr->uid, + d->cr->gid); + return 0; +} + void start_property_service() { + sehandle_prop = selinux_android_prop_context_handle(); + + selinux_callback cb; + cb.func_audit = SelinuxAuditCallback; + selinux_set_callback(SELINUX_CB_AUDIT, cb); + property_set("ro.property_service.version", "2"); property_set_fd = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, - false, 0666, 0, 0, nullptr, sehandle); + false, 0666, 0, 0, nullptr); if (property_set_fd == -1) { PLOG(ERROR) << "start_property_service socket creation failed"; exit(1); diff --git a/init/reboot.cpp b/init/reboot.cpp index cfd703ec1..32816fe40 100644 --- a/init/reboot.cpp +++ b/init/reboot.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include "capabilities.h" #include "init.h" diff --git a/init/security.cpp b/init/security.cpp new file mode 100644 index 000000000..45a5412bf --- /dev/null +++ b/init/security.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "security.h" + +#include +#include +#include + +#include + +#include +#include + +#include "util.h" + +using android::base::unique_fd; + +namespace android { +namespace init { + +// Writes 512 bytes of output from Hardware RNG (/dev/hw_random, backed +// by Linux kernel's hw_random framework) into Linux RNG's via /dev/urandom. +// Does nothing if Hardware RNG is not present. +// +// Since we don't yet trust the quality of Hardware RNG, these bytes are not +// mixed into the primary pool of Linux RNG and the entropy estimate is left +// unmodified. +// +// If the HW RNG device /dev/hw_random is present, we require that at least +// 512 bytes read from it are written into Linux RNG. QA is expected to catch +// devices/configurations where these I/O operations are blocking for a long +// time. We do not reboot or halt on failures, as this is a best-effort +// attempt. +int MixHwrngIntoLinuxRngAction(const std::vector& args) { + unique_fd hwrandom_fd( + TEMP_FAILURE_RETRY(open("/dev/hw_random", O_RDONLY | O_NOFOLLOW | O_CLOEXEC))); + if (hwrandom_fd == -1) { + if (errno == ENOENT) { + LOG(INFO) << "/dev/hw_random not found"; + // It's not an error to not have a Hardware RNG. + return 0; + } + PLOG(ERROR) << "Failed to open /dev/hw_random"; + return -1; + } + + unique_fd urandom_fd( + TEMP_FAILURE_RETRY(open("/dev/urandom", O_WRONLY | O_NOFOLLOW | O_CLOEXEC))); + if (urandom_fd == -1) { + PLOG(ERROR) << "Failed to open /dev/urandom"; + return -1; + } + + char buf[512]; + size_t total_bytes_written = 0; + while (total_bytes_written < sizeof(buf)) { + ssize_t chunk_size = + TEMP_FAILURE_RETRY(read(hwrandom_fd, buf, sizeof(buf) - total_bytes_written)); + if (chunk_size == -1) { + PLOG(ERROR) << "Failed to read from /dev/hw_random"; + return -1; + } else if (chunk_size == 0) { + LOG(ERROR) << "Failed to read from /dev/hw_random: EOF"; + return -1; + } + + chunk_size = TEMP_FAILURE_RETRY(write(urandom_fd, buf, chunk_size)); + if (chunk_size == -1) { + PLOG(ERROR) << "Failed to write to /dev/urandom"; + return -1; + } + total_bytes_written += chunk_size; + } + + LOG(INFO) << "Mixed " << total_bytes_written << " bytes from /dev/hw_random into /dev/urandom"; + return 0; +} + +static bool SetHighestAvailableOptionValue(std::string path, int min, int max) { + std::ifstream inf(path, std::fstream::in); + if (!inf) { + LOG(ERROR) << "Cannot open for reading: " << path; + return false; + } + + int current = max; + while (current >= min) { + // try to write out new value + std::string str_val = std::to_string(current); + std::ofstream of(path, std::fstream::out); + if (!of) { + LOG(ERROR) << "Cannot open for writing: " << path; + return false; + } + of << str_val << std::endl; + of.close(); + + // check to make sure it was recorded + inf.seekg(0); + std::string str_rec; + inf >> str_rec; + if (str_val.compare(str_rec) == 0) { + break; + } + current--; + } + inf.close(); + + if (current < min) { + LOG(ERROR) << "Unable to set minimum option value " << min << " in " << path; + return false; + } + return true; +} + +#define MMAP_RND_PATH "/proc/sys/vm/mmap_rnd_bits" +#define MMAP_RND_COMPAT_PATH "/proc/sys/vm/mmap_rnd_compat_bits" + +// __attribute__((unused)) due to lack of mips support: see mips block in SetMmapRndBitsAction +static bool __attribute__((unused)) SetMmapRndBitsMin(int start, int min, bool compat) { + std::string path; + if (compat) { + path = MMAP_RND_COMPAT_PATH; + } else { + path = MMAP_RND_PATH; + } + + return SetHighestAvailableOptionValue(path, min, start); +} + +// Set /proc/sys/vm/mmap_rnd_bits and potentially +// /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values. +// Returns -1 if unable to set these to an acceptable value. +// +// To support this sysctl, the following upstream commits are needed: +// +// d07e22597d1d mm: mmap: add new /proc tunable for mmap_base ASLR +// e0c25d958f78 arm: mm: support ARCH_MMAP_RND_BITS +// 8f0d3aa9de57 arm64: mm: support ARCH_MMAP_RND_BITS +// 9e08f57d684a x86: mm: support ARCH_MMAP_RND_BITS +// ec9ee4acd97c drivers: char: random: add get_random_long() +// 5ef11c35ce86 mm: ASLR: use get_random_long() +int SetMmapRndBitsAction(const std::vector& args) { +// values are arch-dependent +#if defined(USER_MODE_LINUX) + // uml does not support mmap_rnd_bits + return 0; +#elif defined(__aarch64__) + // arm64 supports 18 - 33 bits depending on pagesize and VA_SIZE + if (SetMmapRndBitsMin(33, 24, false) && SetMmapRndBitsMin(16, 16, true)) { + return 0; + } +#elif defined(__x86_64__) + // x86_64 supports 28 - 32 bits + if (SetMmapRndBitsMin(32, 32, false) && SetMmapRndBitsMin(16, 16, true)) { + return 0; + } +#elif defined(__arm__) || defined(__i386__) + // check to see if we're running on 64-bit kernel + bool h64 = !access(MMAP_RND_COMPAT_PATH, F_OK); + // supported 32-bit architecture must have 16 bits set + if (SetMmapRndBitsMin(16, 16, h64)) { + return 0; + } +#elif defined(__mips__) || defined(__mips64__) + // TODO: add mips support b/27788820 + return 0; +#else + LOG(ERROR) << "Unknown architecture"; +#endif + + LOG(ERROR) << "Unable to set adequate mmap entropy value!"; + panic(); + return -1; +} + +#define KPTR_RESTRICT_PATH "/proc/sys/kernel/kptr_restrict" +#define KPTR_RESTRICT_MINVALUE 2 +#define KPTR_RESTRICT_MAXVALUE 4 + +// Set kptr_restrict to the highest available level. +// +// Aborts if unable to set this to an acceptable value. +int SetKptrRestrictAction(const std::vector& args) { + std::string path = KPTR_RESTRICT_PATH; + + if (!SetHighestAvailableOptionValue(path, KPTR_RESTRICT_MINVALUE, KPTR_RESTRICT_MAXVALUE)) { + LOG(ERROR) << "Unable to set adequate kptr_restrict value!"; + panic(); + } + return 0; +} + +} // namespace init +} // namespace android diff --git a/init/security.h b/init/security.h new file mode 100644 index 000000000..c489de143 --- /dev/null +++ b/init/security.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _INIT_SECURITY_H +#define _INIT_SECURITY_H + +#include +#include + +namespace android { +namespace init { + +int MixHwrngIntoLinuxRngAction(const std::vector& args); +int SetMmapRndBitsAction(const std::vector& args); +int SetKptrRestrictAction(const std::vector& args); + +} // namespace init +} // namespace android + +#endif diff --git a/init/selinux.cpp b/init/selinux.cpp new file mode 100644 index 000000000..1bf237a4a --- /dev/null +++ b/init/selinux.cpp @@ -0,0 +1,462 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This file contains the functions that initialize SELinux during boot as well as helper functions +// for SELinux operation for init. + +// When the system boots, there is no SEPolicy present and init is running in the kernel domain. +// Init loads the SEPolicy from the file system, restores the context of /init based on this +// SEPolicy, and finally exec()'s itself to run in the proper domain. + +// The SEPolicy on Android comes in two variants: monolithic and split. + +// The monolithic policy variant is for legacy non-treble devices that contain a single SEPolicy +// file located at /sepolicy and is directly loaded into the kernel SELinux subsystem. + +// The split policy is for supporting treble devices. It splits the SEPolicy across files on +// /system/etc/selinux (the 'plat' portion of the policy) and /vendor/etc/selinux (the 'nonplat' +// portion of the policy). This is necessary to allow the system image to be updated independently +// of the vendor image, while maintaining contributions from both partitions in the SEPolicy. This +// is especially important for VTS testing, where the SEPolicy on the Google System Image may not be +// identical to the system image shipped on a vendor's device. + +// The split SEPolicy is loaded as described below: +// 1) There is a precompiled SEPolicy located at /vendor/etc/selinux/precompiled_sepolicy. +// Stored along with this file is the sha256 hash of the parts of the SEPolicy on /system that +// were used to compile this precompiled policy. The system partition contains a similar sha256 +// of the parts of the SEPolicy that it currently contains. If these two hashes match, then the +// system loads this precompiled_sepolicy directly. +// 2) If these hashes do not match, then /system has been updated out of sync with /vendor and the +// init needs to compile the SEPolicy. /system contains the SEPolicy compiler, secilc, and it +// is used by the LoadSplitPolicy() function below to compile the SEPolicy to a temp directory +// and load it. That function contains even more documentation with the specific implementation +// details of how the SEPolicy is compiled if needed. + +#include "selinux.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" + +using android::base::Timer; +using android::base::unique_fd; + +namespace android { +namespace init { + +static struct selabel_handle* sehandle = nullptr; + +namespace { + +enum EnforcingStatus { SELINUX_PERMISSIVE, SELINUX_ENFORCING }; + +EnforcingStatus StatusFromCmdline() { + EnforcingStatus status = SELINUX_ENFORCING; + + import_kernel_cmdline(false, + [&](const std::string& key, const std::string& value, bool in_qemu) { + if (key == "androidboot.selinux" && value == "permissive") { + status = SELINUX_PERMISSIVE; + } + }); + + return status; +} + +bool IsEnforcing() { + if (ALLOW_PERMISSIVE_SELINUX) { + return StatusFromCmdline() == SELINUX_ENFORCING; + } + return true; +} + +// Forks, executes the provided program in the child, and waits for the completion in the parent. +// Child's stderr is captured and logged using LOG(ERROR). +bool ForkExecveAndWaitForCompletion(const char* filename, char* const argv[]) { + // Create a pipe used for redirecting child process's output. + // * pipe_fds[0] is the FD the parent will use for reading. + // * pipe_fds[1] is the FD the child will use for writing. + int pipe_fds[2]; + if (pipe(pipe_fds) == -1) { + PLOG(ERROR) << "Failed to create pipe"; + return false; + } + + pid_t child_pid = fork(); + if (child_pid == -1) { + PLOG(ERROR) << "Failed to fork for " << filename; + return false; + } + + if (child_pid == 0) { + // fork succeeded -- this is executing in the child process + + // Close the pipe FD not used by this process + TEMP_FAILURE_RETRY(close(pipe_fds[0])); + + // Redirect stderr to the pipe FD provided by the parent + if (TEMP_FAILURE_RETRY(dup2(pipe_fds[1], STDERR_FILENO)) == -1) { + PLOG(ERROR) << "Failed to redirect stderr of " << filename; + _exit(127); + return false; + } + TEMP_FAILURE_RETRY(close(pipe_fds[1])); + + const char* envp[] = {_PATH_DEFPATH, nullptr}; + if (execve(filename, argv, (char**)envp) == -1) { + PLOG(ERROR) << "Failed to execve " << filename; + return false; + } + // Unreachable because execve will have succeeded and replaced this code + // with child process's code. + _exit(127); + return false; + } else { + // fork succeeded -- this is executing in the original/parent process + + // Close the pipe FD not used by this process + TEMP_FAILURE_RETRY(close(pipe_fds[1])); + + // Log the redirected output of the child process. + // It's unfortunate that there's no standard way to obtain an istream for a file descriptor. + // As a result, we're buffering all output and logging it in one go at the end of the + // invocation, instead of logging it as it comes in. + const int child_out_fd = pipe_fds[0]; + std::string child_output; + if (!android::base::ReadFdToString(child_out_fd, &child_output)) { + PLOG(ERROR) << "Failed to capture full output of " << filename; + } + TEMP_FAILURE_RETRY(close(child_out_fd)); + if (!child_output.empty()) { + // Log captured output, line by line, because LOG expects to be invoked for each line + std::istringstream in(child_output); + std::string line; + while (std::getline(in, line)) { + LOG(ERROR) << filename << ": " << line; + } + } + + // Wait for child to terminate + int status; + if (TEMP_FAILURE_RETRY(waitpid(child_pid, &status, 0)) != child_pid) { + PLOG(ERROR) << "Failed to wait for " << filename; + return false; + } + + if (WIFEXITED(status)) { + int status_code = WEXITSTATUS(status); + if (status_code == 0) { + return true; + } else { + LOG(ERROR) << filename << " exited with status " << status_code; + } + } else if (WIFSIGNALED(status)) { + LOG(ERROR) << filename << " killed by signal " << WTERMSIG(status); + } else if (WIFSTOPPED(status)) { + LOG(ERROR) << filename << " stopped by signal " << WSTOPSIG(status); + } else { + LOG(ERROR) << "waitpid for " << filename << " returned unexpected status: " << status; + } + + return false; + } +} + +bool ReadFirstLine(const char* file, std::string* line) { + line->clear(); + + std::string contents; + if (!android::base::ReadFileToString(file, &contents, true /* follow symlinks */)) { + return false; + } + std::istringstream in(contents); + std::getline(in, *line); + return true; +} + +bool FindPrecompiledSplitPolicy(std::string* file) { + file->clear(); + + static constexpr const char precompiled_sepolicy[] = "/vendor/etc/selinux/precompiled_sepolicy"; + if (access(precompiled_sepolicy, R_OK) == -1) { + return false; + } + std::string actual_plat_id; + if (!ReadFirstLine("/system/etc/selinux/plat_and_mapping_sepolicy.cil.sha256", &actual_plat_id)) { + PLOG(INFO) << "Failed to read " + "/system/etc/selinux/plat_and_mapping_sepolicy.cil.sha256"; + return false; + } + std::string precompiled_plat_id; + if (!ReadFirstLine("/vendor/etc/selinux/precompiled_sepolicy.plat_and_mapping.sha256", + &precompiled_plat_id)) { + PLOG(INFO) << "Failed to read " + "/vendor/etc/selinux/" + "precompiled_sepolicy.plat_and_mapping.sha256"; + return false; + } + if ((actual_plat_id.empty()) || (actual_plat_id != precompiled_plat_id)) { + return false; + } + + *file = precompiled_sepolicy; + return true; +} + +bool GetVendorMappingVersion(std::string* plat_vers) { + if (!ReadFirstLine("/vendor/etc/selinux/plat_sepolicy_vers.txt", plat_vers)) { + PLOG(ERROR) << "Failed to read /vendor/etc/selinux/plat_sepolicy_vers.txt"; + return false; + } + if (plat_vers->empty()) { + LOG(ERROR) << "No version present in plat_sepolicy_vers.txt"; + return false; + } + return true; +} + +constexpr const char plat_policy_cil_file[] = "/system/etc/selinux/plat_sepolicy.cil"; + +bool IsSplitPolicyDevice() { + return access(plat_policy_cil_file, R_OK) != -1; +} + +bool LoadSplitPolicy() { + // IMPLEMENTATION NOTE: Split policy consists of three CIL files: + // * platform -- policy needed due to logic contained in the system image, + // * non-platform -- policy needed due to logic contained in the vendor image, + // * mapping -- mapping policy which helps preserve forward-compatibility of non-platform policy + // with newer versions of platform policy. + // + // secilc is invoked to compile the above three policy files into a single monolithic policy + // file. This file is then loaded into the kernel. + + // Load precompiled policy from vendor image, if a matching policy is found there. The policy + // must match the platform policy on the system image. + std::string precompiled_sepolicy_file; + if (FindPrecompiledSplitPolicy(&precompiled_sepolicy_file)) { + unique_fd fd(open(precompiled_sepolicy_file.c_str(), O_RDONLY | O_CLOEXEC | O_BINARY)); + if (fd != -1) { + if (selinux_android_load_policy_from_fd(fd, precompiled_sepolicy_file.c_str()) < 0) { + LOG(ERROR) << "Failed to load SELinux policy from " << precompiled_sepolicy_file; + return false; + } + return true; + } + } + // No suitable precompiled policy could be loaded + + LOG(INFO) << "Compiling SELinux policy"; + + // Determine the highest policy language version supported by the kernel + set_selinuxmnt("/sys/fs/selinux"); + int max_policy_version = security_policyvers(); + if (max_policy_version == -1) { + PLOG(ERROR) << "Failed to determine highest policy version supported by kernel"; + return false; + } + + // We store the output of the compilation on /dev because this is the most convenient tmpfs + // storage mount available this early in the boot sequence. + char compiled_sepolicy[] = "/dev/sepolicy.XXXXXX"; + unique_fd compiled_sepolicy_fd(mkostemp(compiled_sepolicy, O_CLOEXEC)); + if (compiled_sepolicy_fd < 0) { + PLOG(ERROR) << "Failed to create temporary file " << compiled_sepolicy; + return false; + } + + // Determine which mapping file to include + std::string vend_plat_vers; + if (!GetVendorMappingVersion(&vend_plat_vers)) { + return false; + } + std::string mapping_file("/system/etc/selinux/mapping/" + vend_plat_vers + ".cil"); + // clang-format off + const char* compile_args[] = { + "/system/bin/secilc", + plat_policy_cil_file, + "-M", "true", "-G", "-N", + // Target the highest policy language version supported by the kernel + "-c", std::to_string(max_policy_version).c_str(), + mapping_file.c_str(), + "/vendor/etc/selinux/nonplat_sepolicy.cil", + "-o", compiled_sepolicy, + // We don't care about file_contexts output by the compiler + "-f", "/sys/fs/selinux/null", // /dev/null is not yet available + nullptr}; + // clang-format on + + if (!ForkExecveAndWaitForCompletion(compile_args[0], (char**)compile_args)) { + unlink(compiled_sepolicy); + return false; + } + unlink(compiled_sepolicy); + + LOG(INFO) << "Loading compiled SELinux policy"; + if (selinux_android_load_policy_from_fd(compiled_sepolicy_fd, compiled_sepolicy) < 0) { + LOG(ERROR) << "Failed to load SELinux policy from " << compiled_sepolicy; + return false; + } + + return true; +} + +bool LoadMonolithicPolicy() { + LOG(VERBOSE) << "Loading SELinux policy from monolithic file"; + if (selinux_android_load_policy() < 0) { + PLOG(ERROR) << "Failed to load monolithic SELinux policy"; + return false; + } + return true; +} + +bool LoadPolicy() { + return IsSplitPolicyDevice() ? LoadSplitPolicy() : LoadMonolithicPolicy(); +} + +} // namespace + +void SelinuxInitialize() { + Timer t; + + LOG(INFO) << "Loading SELinux policy"; + if (!LoadPolicy()) { + panic(); + } + + bool kernel_enforcing = (security_getenforce() == 1); + bool is_enforcing = IsEnforcing(); + if (kernel_enforcing != is_enforcing) { + if (security_setenforce(is_enforcing)) { + PLOG(ERROR) << "security_setenforce(%s) failed" << (is_enforcing ? "true" : "false"); + panic(); + } + } + + std::string err; + if (!WriteFile("/sys/fs/selinux/checkreqprot", "0", &err)) { + LOG(ERROR) << err; + panic(); + } + + // init's first stage can't set properties, so pass the time to the second stage. + setenv("INIT_SELINUX_TOOK", std::to_string(t.duration().count()).c_str(), 1); +} + +// The files and directories that were created before initial sepolicy load or +// files on ramdisk need to have their security context restored to the proper +// value. This must happen before /dev is populated by ueventd. +void SelinuxRestoreContext() { + LOG(INFO) << "Running restorecon..."; + selinux_android_restorecon("/dev", 0); + selinux_android_restorecon("/dev/kmsg", 0); + if constexpr (WORLD_WRITABLE_KMSG) { + selinux_android_restorecon("/dev/kmsg_debug", 0); + } + selinux_android_restorecon("/dev/socket", 0); + selinux_android_restorecon("/dev/random", 0); + selinux_android_restorecon("/dev/urandom", 0); + selinux_android_restorecon("/dev/__properties__", 0); + + selinux_android_restorecon("/plat_file_contexts", 0); + selinux_android_restorecon("/nonplat_file_contexts", 0); + selinux_android_restorecon("/plat_property_contexts", 0); + selinux_android_restorecon("/nonplat_property_contexts", 0); + selinux_android_restorecon("/plat_seapp_contexts", 0); + selinux_android_restorecon("/nonplat_seapp_contexts", 0); + selinux_android_restorecon("/plat_service_contexts", 0); + selinux_android_restorecon("/nonplat_service_contexts", 0); + selinux_android_restorecon("/plat_hwservice_contexts", 0); + selinux_android_restorecon("/nonplat_hwservice_contexts", 0); + selinux_android_restorecon("/sepolicy", 0); + selinux_android_restorecon("/vndservice_contexts", 0); + + selinux_android_restorecon("/dev/block", SELINUX_ANDROID_RESTORECON_RECURSE); + selinux_android_restorecon("/dev/device-mapper", 0); + + selinux_android_restorecon("/sbin/mke2fs_static", 0); + selinux_android_restorecon("/sbin/e2fsdroid_static", 0); +} + +// This function sets up SELinux logging to be written to kmsg, to match init's logging. +void SelinuxSetupKernelLogging() { + selinux_callback cb; + cb.func_log = selinux_klog_callback; + selinux_set_callback(SELINUX_CB_LOG, cb); +} + +// selinux_android_file_context_handle() takes on the order of 10+ms to run, so we want to cache +// its value. selinux_android_restorecon() also needs an sehandle for file context look up. It +// will create and store its own copy, but selinux_android_set_sehandle() can be used to provide +// one, thus eliminating an extra call to selinux_android_file_context_handle(). +void SelabelInitialize() { + sehandle = selinux_android_file_context_handle(); + selinux_android_set_sehandle(sehandle); +} + +// A C++ wrapper around selabel_lookup() using the cached sehandle. +// If sehandle is null, this returns success with an empty context. +bool SelabelLookupFileContext(const std::string& key, int type, std::string* result) { + result->clear(); + + if (!sehandle) return true; + + char* context; + if (selabel_lookup(sehandle, &context, key.c_str(), type) != 0) { + return false; + } + *result = context; + free(context); + return true; +} + +// A C++ wrapper around selabel_lookup_best_match() using the cached sehandle. +// If sehandle is null, this returns success with an empty context. +bool SelabelLookupFileContextBestMatch(const std::string& key, + const std::vector& aliases, int type, + std::string* result) { + result->clear(); + + if (!sehandle) return true; + + std::vector c_aliases; + for (const auto& alias : aliases) { + c_aliases.emplace_back(alias.c_str()); + } + c_aliases.emplace_back(nullptr); + + char* context; + if (selabel_lookup_best_match(sehandle, &context, key.c_str(), &c_aliases[0], type) != 0) { + return false; + } + *result = context; + free(context); + return true; +} + +} // namespace init +} // namespace android diff --git a/init/selinux.h b/init/selinux.h new file mode 100644 index 000000000..7b880eccc --- /dev/null +++ b/init/selinux.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _INIT_SELINUX_H +#define _INIT_SELINUX_H + +#include +#include + +namespace android { +namespace init { + +void SelinuxInitialize(); +void SelinuxRestoreContext(); + +void SelinuxSetupKernelLogging(); + +void SelabelInitialize(); +bool SelabelLookupFileContext(const std::string& key, int type, std::string* result); +bool SelabelLookupFileContextBestMatch(const std::string& key, + const std::vector& aliases, int type, + std::string* result); + +} // namespace init +} // namespace android + +#endif diff --git a/init/ueventd.cpp b/init/ueventd.cpp index c0eae1e9a..b71945acc 100644 --- a/init/ueventd.cpp +++ b/init/ueventd.cpp @@ -36,6 +36,7 @@ #include "devices.h" #include "firmware_handler.h" #include "log.h" +#include "selinux.h" #include "uevent_listener.h" #include "ueventd_parser.h" #include "util.h" @@ -257,9 +258,8 @@ int ueventd_main(int argc, char** argv) { LOG(INFO) << "ueventd started!"; - selinux_callback cb; - cb.func_log = selinux_klog_callback; - selinux_set_callback(SELINUX_CB_LOG, cb); + SelinuxSetupKernelLogging(); + SelabelInitialize(); DeviceHandler device_handler = CreateDeviceHandler(); UeventListener uevent_listener; diff --git a/init/util.cpp b/init/util.cpp index fdcb22d1c..e0379876d 100644 --- a/init/util.cpp +++ b/init/util.cpp @@ -42,6 +42,7 @@ #include #include "reboot.h" +#include "selinux.h" #ifdef _INIT_INIT_H #error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals" @@ -89,7 +90,7 @@ bool DecodeUid(const std::string& name, uid_t* uid, std::string* err) { * variable ANDROID_SOCKET_ENV_PREFIX ("ANDROID_SOCKET_foo"). */ int CreateSocket(const char* name, int type, bool passcred, mode_t perm, uid_t uid, gid_t gid, - const char* socketcon, selabel_handle* sehandle) { + const char* socketcon) { if (socketcon) { if (setsockcreatecon(socketcon) == -1) { PLOG(ERROR) << "setsockcreatecon(\"" << socketcon << "\") failed"; @@ -116,11 +117,9 @@ int CreateSocket(const char* name, int type, bool passcred, mode_t perm, uid_t u return -1; } - char *filecon = NULL; - if (sehandle) { - if (selabel_lookup(sehandle, &filecon, addr.sun_path, S_IFSOCK) == 0) { - setfscreatecon(filecon); - } + std::string secontext; + if (SelabelLookupFileContext(addr.sun_path, S_IFSOCK, &secontext) && !secontext.empty()) { + setfscreatecon(secontext.c_str()); } if (passcred) { @@ -134,8 +133,9 @@ int CreateSocket(const char* name, int type, bool passcred, mode_t perm, uid_t u int ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr)); int savederrno = errno; - setfscreatecon(NULL); - freecon(filecon); + if (!secontext.empty()) { + setfscreatecon(nullptr); + } if (ret) { errno = savederrno; @@ -210,19 +210,19 @@ bool WriteFile(const std::string& path, const std::string& content, std::string* return true; } -int mkdir_recursive(const std::string& path, mode_t mode, selabel_handle* sehandle) { +bool mkdir_recursive(const std::string& path, mode_t mode) { std::string::size_type slash = 0; while ((slash = path.find('/', slash + 1)) != std::string::npos) { auto directory = path.substr(0, slash); struct stat info; if (stat(directory.c_str(), &info) != 0) { - auto ret = make_dir(directory.c_str(), mode, sehandle); - if (ret && errno != EEXIST) return ret; + auto ret = make_dir(directory, mode); + if (!ret && errno != EEXIST) return false; } } - auto ret = make_dir(path.c_str(), mode, sehandle); - if (ret && errno != EEXIST) return ret; - return 0; + auto ret = make_dir(path, mode); + if (!ret && errno != EEXIST) return false; + return true; } int wait_for_file(const char* filename, std::chrono::nanoseconds timeout) { @@ -249,26 +249,21 @@ void import_kernel_cmdline(bool in_qemu, } } -int make_dir(const char* path, mode_t mode, selabel_handle* sehandle) { - int rc; - - char *secontext = NULL; - - if (sehandle) { - selabel_lookup(sehandle, &secontext, path, mode); - setfscreatecon(secontext); +bool make_dir(const std::string& path, mode_t mode) { + std::string secontext; + if (SelabelLookupFileContext(path, mode, &secontext) && !secontext.empty()) { + setfscreatecon(secontext.c_str()); } - rc = mkdir(path, mode); + int rc = mkdir(path.c_str(), mode); - if (secontext) { + if (!secontext.empty()) { int save_errno = errno; - freecon(secontext); - setfscreatecon(NULL); + setfscreatecon(nullptr); errno = save_errno; } - return rc; + return rc == 0; } /* diff --git a/init/util.h b/init/util.h index 29c10cba2..a81df478a 100644 --- a/init/util.h +++ b/init/util.h @@ -37,18 +37,18 @@ namespace android { namespace init { int CreateSocket(const char* name, int type, bool passcred, mode_t perm, uid_t uid, gid_t gid, - const char* socketcon, selabel_handle* sehandle); + const char* socketcon); bool ReadFile(const std::string& path, std::string* content, std::string* err); bool WriteFile(const std::string& path, const std::string& content, std::string* err); bool DecodeUid(const std::string& name, uid_t* uid, std::string* err); -int mkdir_recursive(const std::string& pathname, mode_t mode, selabel_handle* sehandle); +bool mkdir_recursive(const std::string& pathname, mode_t mode); int wait_for_file(const char *filename, std::chrono::nanoseconds timeout); void import_kernel_cmdline(bool in_qemu, const std::function&); -int make_dir(const char* path, mode_t mode, selabel_handle* sehandle); +bool make_dir(const std::string& path, mode_t mode); std::string bytes_to_hex(const uint8_t *bytes, size_t bytes_len); bool is_dir(const char* pathname); bool expand_props(const std::string& src, std::string* dst); diff --git a/init/util_test.cpp b/init/util_test.cpp index c16ab7431..5dd271cd0 100644 --- a/init/util_test.cpp +++ b/init/util_test.cpp @@ -170,7 +170,7 @@ TEST(util, is_dir) { TEST(util, mkdir_recursive) { TemporaryDir test_dir; std::string path = android::base::StringPrintf("%s/three/directories/deep", test_dir.path); - EXPECT_EQ(0, mkdir_recursive(path, 0755, nullptr)); + EXPECT_TRUE(mkdir_recursive(path, 0755)); std::string path1 = android::base::StringPrintf("%s/three", test_dir.path); EXPECT_TRUE(is_dir(path1.c_str())); std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path); @@ -182,7 +182,7 @@ TEST(util, mkdir_recursive) { TEST(util, mkdir_recursive_extra_slashes) { TemporaryDir test_dir; std::string path = android::base::StringPrintf("%s/three////directories/deep//", test_dir.path); - EXPECT_EQ(0, mkdir_recursive(path, 0755, nullptr)); + EXPECT_TRUE(mkdir_recursive(path, 0755)); std::string path1 = android::base::StringPrintf("%s/three", test_dir.path); EXPECT_TRUE(is_dir(path1.c_str())); std::string path2 = android::base::StringPrintf("%s/three/directories", test_dir.path); From caeaa655c1a60a70ef3d25429cb9731c5c34fc95 Mon Sep 17 00:00:00 2001 From: Robert Benea Date: Fri, 11 Aug 2017 16:03:20 -0700 Subject: [PATCH 049/129] Improvements to lmkd - Don't show misleading messages, add the correct description for the reason of process killing - Don't kill Launcher3 upgrade the score to perceptible (200) - Limit the verbose logging Test: tested on gobo Bug: 64316273 Change-Id: Ic7c13853d939afe4f20cdaa5b488b6e1810f5ddf --- lmkd/lmkd.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index 27cc91b75..02a9601f9 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -75,6 +75,7 @@ static int mpevfd[2]; static int medium_oomadj; static int critical_oomadj; +static int debug_process_killing; /* control socket listen and data */ static int ctrl_lfd; @@ -262,7 +263,9 @@ static void cmd_procprio(int pid, int uid, int oomadj) { } else if (oomadj >= 700) { soft_limit_mult = 0; } else if (oomadj >= 600) { - soft_limit_mult = 0; + // Launcher should be perceptible, don't kill it. + oomadj = 200; + soft_limit_mult = 1; } else if (oomadj >= 500) { soft_limit_mult = 0; } else if (oomadj >= 400) { @@ -576,9 +579,7 @@ static struct proc *proc_adj_lru(int oomadj) { } /* Kill one process specified by procp. Returns the size of the process killed */ -static int kill_one_process(struct proc *procp, int other_free, int other_file, - int minfree, int min_score_adj, bool first) -{ +static int kill_one_process(struct proc* procp, int min_score_adj, bool is_critical) { int pid = procp->pid; uid_t uid = procp->uid; char *taskname; @@ -597,12 +598,11 @@ static int kill_one_process(struct proc *procp, int other_free, int other_file, return -1; } - ALOGI("Killing '%s' (%d), uid %d, adj %d\n" - " to free %ldkB because cache %s%ldkB is below limit %ldkB for oom_adj %d\n" - " Free memory is %s%ldkB %s reserved", - taskname, pid, uid, procp->oomadj, tasksize * page_k, - first ? "" : "~", other_file * page_k, minfree * page_k, min_score_adj, - first ? "" : "~", other_free * page_k, other_free >= 0 ? "above" : "below"); + ALOGI( + "Killing '%s' (%d), uid %d, adj %d\n" + " to free %ldkB because system is under %s memory pressure oom_adj %d\n", + taskname, pid, uid, procp->oomadj, tasksize * page_k, is_critical ? "critical" : "medium", + min_score_adj); r = kill(pid, SIGKILL); pid_remove(pid); @@ -618,10 +618,8 @@ static int kill_one_process(struct proc *procp, int other_free, int other_file, * Find a process to kill based on the current (possibly estimated) free memory * and cached memory sizes. Returns the size of the killed processes. */ -static int find_and_kill_process(int other_free, int other_file, bool first, int min_score_adj) -{ +static int find_and_kill_process(int min_score_adj, bool is_critical) { int i; - int minfree = 0; int killed_size = 0; for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) { @@ -631,7 +629,7 @@ retry: procp = proc_adj_lru(i); if (procp) { - killed_size = kill_one_process(procp, other_free, other_file, minfree, min_score_adj, first); + killed_size = kill_one_process(procp, min_score_adj, is_critical); if (killed_size < 0) { goto retry; } else { @@ -646,7 +644,6 @@ retry: static void mp_event_common(bool is_critical) { int ret; unsigned long long evcount; - bool first = true; int min_adj_score = is_critical ? critical_oomadj : medium_oomadj; int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX; @@ -655,8 +652,10 @@ static void mp_event_common(bool is_critical) { ALOGE("Error reading memory pressure event fd; errno=%d", errno); - if (find_and_kill_process(0, 0, first, min_adj_score) == 0) { - ALOGI("Nothing to kill"); + if (find_and_kill_process(min_adj_score, is_critical) == 0) { + if (debug_process_killing) { + ALOGI("Nothing to kill"); + } } } @@ -665,7 +664,6 @@ static void mp_event(uint32_t events __unused) { } static void mp_event_critical(uint32_t events __unused) { - ALOGI("Memory pressure critical"); mp_event_common(true); } @@ -828,6 +826,7 @@ int main(int argc __unused, char **argv __unused) { medium_oomadj = property_get_int32("ro.lmk.medium", 800); critical_oomadj = property_get_int32("ro.lmk.critical", 0); + debug_process_killing = property_get_bool("ro.lmk.debug", false); mlockall(MCL_FUTURE); sched_setscheduler(0, SCHED_FIFO, ¶m); From 513f76394a767192965888ed495305102b318dab Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Mon, 14 Aug 2017 12:18:29 +0900 Subject: [PATCH 050/129] Add libft2.so to ll-ndk for rs namespace libft2.so is changed to ll-ndk that is available only for rs namespace. Bug: 64425518 Test: build and boot with BOARD_VNDK_VERSION=current Change-Id: I991dc774ca9b92fb6e95a7656243a6a4ecdc0ab9 --- rootdir/etc/ld.config.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index 79a27a0d2..16db77050 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt @@ -88,7 +88,7 @@ namespace.rs.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB} namespace.rs.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data namespace.rs.links = default,vndk -namespace.rs.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libvndksupport.so +namespace.rs.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libvndksupport.so:libft2.so namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so:libz.so ############################################################################### From 058e0919f6aff67d32d00591a7040fc069c6e40f Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 14 Aug 2017 15:21:28 +0900 Subject: [PATCH 051/129] Mark libsync as LL-NDK libsync is used both by platform (e.g. libui.so) and by same-process HALs (e.g. android.hardware.graphics.mapper@2.0-impl.so). Therefore it is eligible for either VNDK-SP or LL-NDK. Among the two choices, LL-NDK was selected because it is already an NDK and is just a thin wrapper around a few kernel ioctls. However, since libui (which is a vendor_available:true library) is using more symbols that are not available to NDK clients, the extra symbols are exposed as # vndk tag so that they are only available to VNDK clients, but not to NDK clients. Bug: 63866913 Test: BOARD_VNDK_VERSION=current m -j successful (2017 pixel) Test: the built image is bootable Change-Id: I60f883c049bd9b4562e6ce34d34ead47ba28af5f --- libsync/Android.bp | 10 ++++++---- libsync/libsync.map.txt | 12 ++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/libsync/Android.bp b/libsync/Android.bp index 1cd52304a..ce9e84abe 100644 --- a/libsync/Android.bp +++ b/libsync/Android.bp @@ -22,13 +22,15 @@ cc_defaults { cc_library_shared { name: "libsync", - vendor_available: true, - vndk: { - enabled: true, - }, defaults: ["libsync_defaults"], } +llndk_library { + name: "libsync", + symbol_file: "libsync.map.txt", + export_include_dirs: ["include"], +} + // libsync_recovery is only intended for the recovery binary. // Future versions of the kernel WILL require an updated libsync, and will break // anything statically linked against the current libsync. diff --git a/libsync/libsync.map.txt b/libsync/libsync.map.txt index f9057bd7f..53bb07a70 100644 --- a/libsync/libsync.map.txt +++ b/libsync/libsync.map.txt @@ -19,14 +19,10 @@ LIBSYNC { sync_merge; # introduced=26 sync_file_info; # introduced=26 sync_file_info_free; # introduced=26 + sync_wait; # vndk + sync_fence_info; # vndk + sync_pt_info; # vndk + sync_fence_info_free; # vndk local: *; }; - -LIBSYNC_PLATFORM { - global: - sync_wait; - sync_fence_info; - sync_pt_info; - sync_fence_info_free; -} LIBSYNC_PLATFORM; From 93defc17f376041437e5157a7c4d9e0344441811 Mon Sep 17 00:00:00 2001 From: Bowgo Tsai Date: Fri, 28 Jul 2017 20:29:15 +0800 Subject: [PATCH 052/129] Move adbd from root to system Bug: 63910933 Test: normal boot sailfish, checks adb works Test: recovery boot sailfish, checks adb works Test: normal boot bullhead, checks adb works Test: recovery boot bullhead, checks adb works Change-Id: I1b27910c06a4172ca718b3344736ec8e3429f477 --- adb/Android.mk | 2 -- rootdir/init.usb.rc | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/adb/Android.mk b/adb/Android.mk index 5913d940a..d5b069a88 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -360,8 +360,6 @@ endif LOCAL_MODULE := adbd LOCAL_FORCE_STATIC_EXECUTABLE := true -LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN) -LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED) LOCAL_SANITIZE := $(adb_target_sanitize) LOCAL_STRIP_MODULE := keep_symbols diff --git a/rootdir/init.usb.rc b/rootdir/init.usb.rc index 915d159a5..3168f40ba 100644 --- a/rootdir/init.usb.rc +++ b/rootdir/init.usb.rc @@ -12,7 +12,7 @@ on post-fs-data mkdir /data/adb 0700 root root # adbd is controlled via property triggers in init..usb.rc -service adbd /sbin/adbd --root_seclabel=u:r:su:s0 +service adbd /system/bin/adbd --root_seclabel=u:r:su:s0 class core socket adbd stream 660 system system disabled From 98a48d8e4bddbadca217d50a3f99f144193a5a5f Mon Sep 17 00:00:00 2001 From: Hung-ying Tyan Date: Tue, 15 Aug 2017 18:12:56 +0800 Subject: [PATCH 053/129] Remove nvram trusty implementation. Bug: 64705490 Test: build pass Change-Id: I32a1565ec935fff1c45540442134a37b55702752 --- trusty/Android.bp | 1 - trusty/nvram/Android.bp | 61 ---------- trusty/nvram/module.c | 39 ------- trusty/nvram/nvram_wipe.cpp | 66 ----------- trusty/nvram/trusty_nvram_device.cpp | 32 ------ trusty/nvram/trusty_nvram_implementation.cpp | 113 ------------------- trusty/nvram/trusty_nvram_implementation.h | 59 ---------- 7 files changed, 371 deletions(-) delete mode 100644 trusty/nvram/Android.bp delete mode 100644 trusty/nvram/module.c delete mode 100644 trusty/nvram/nvram_wipe.cpp delete mode 100644 trusty/nvram/trusty_nvram_device.cpp delete mode 100644 trusty/nvram/trusty_nvram_implementation.cpp delete mode 100644 trusty/nvram/trusty_nvram_implementation.h diff --git a/trusty/Android.bp b/trusty/Android.bp index 386fbe623..2fb2e194b 100644 --- a/trusty/Android.bp +++ b/trusty/Android.bp @@ -2,6 +2,5 @@ subdirs = [ "gatekeeper", "keymaster", "libtrusty", - "nvram", "storage/*", ] diff --git a/trusty/nvram/Android.bp b/trusty/nvram/Android.bp deleted file mode 100644 index 15e6c3e5e..000000000 --- a/trusty/nvram/Android.bp +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright (C) 2016 The Android Open-Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -// nvram.trusty is the Trusty NVRAM HAL module. -cc_library_shared { - name: "nvram.trusty", - relative_install_path: "hw", - srcs: [ - "module.c", - "trusty_nvram_device.cpp", - "trusty_nvram_implementation.cpp", - ], - - cflags: [ - "-Wall", - "-Werror", - "-Wextra", - "-fvisibility=hidden", - ], - static_libs: ["libnvram-hal"], - shared_libs: [ - "libtrusty", - "libnvram-messages", - "liblog", - ], -} - -// nvram-wipe is a helper tool for clearing NVRAM state. -cc_binary { - name: "nvram-wipe", - srcs: [ - "nvram_wipe.cpp", - "trusty_nvram_implementation.cpp", - ], - - cflags: [ - "-Wall", - "-Werror", - "-Wextra", - "-fvisibility=hidden", - ], - static_libs: ["libnvram-hal"], - shared_libs: [ - "libtrusty", - "libnvram-messages", - "liblog", - ], -} diff --git a/trusty/nvram/module.c b/trusty/nvram/module.c deleted file mode 100644 index a2e64d372..000000000 --- a/trusty/nvram/module.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -// This function is defined in trusty_nvram_device.cpp. -int trusty_nvram_open(const hw_module_t* module, - const char* device_id, - hw_device_t** device_ptr); - -static struct hw_module_methods_t nvram_module_methods = { - .open = trusty_nvram_open, -}; - -struct nvram_module HAL_MODULE_INFO_SYM - __attribute__((visibility("default"))) = { - .common = {.tag = HARDWARE_MODULE_TAG, - .module_api_version = NVRAM_MODULE_API_VERSION_0_1, - .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = NVRAM_HARDWARE_MODULE_ID, - .name = "Trusty NVRAM HAL", - .author = "The Android Open Source Project", - .methods = &nvram_module_methods, - .dso = 0, - .reserved = {}}, -}; diff --git a/trusty/nvram/nvram_wipe.cpp b/trusty/nvram/nvram_wipe.cpp deleted file mode 100644 index d0f4faded..000000000 --- a/trusty/nvram/nvram_wipe.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include - -#include "trusty_nvram_implementation.h" - -void usage(const char* program_name) { - fprintf(stderr, "Usage: %s [status|disable|wipe]\n", program_name); - exit(-1); -} - -int main(int argc, char* argv[]) { - if (argc < 2) { - usage(argv[0]); - } - - nvram::TrustyNvramImplementation nvram_proxy; - nvram::Request request; - nvram::Response response; - - if (!strcmp(argv[1], "status")) { - request.payload.Activate(); - nvram_proxy.Execute(request, &response); - const nvram::GetInfoResponse* get_info_response = - response.payload.get(); - if (response.result == NV_RESULT_SUCCESS) { - int status = get_info_response && get_info_response->wipe_disabled; - printf("Wiping disabled: %d\n", status); - return status; - } - } else if (!strcmp(argv[1], "disable")) { - request.payload.Activate(); - nvram_proxy.Execute(request, &response); - } else if (!strcmp(argv[1], "wipe")) { - request.payload.Activate(); - nvram_proxy.Execute(request, &response); - } else { - usage(argv[0]); - } - - if (response.result != NV_RESULT_SUCCESS) { - fprintf(stderr, "Command execution failure: %u\n", response.result); - return -1; - } - - return 0; -} - diff --git a/trusty/nvram/trusty_nvram_device.cpp b/trusty/nvram/trusty_nvram_device.cpp deleted file mode 100644 index 2c50915d4..000000000 --- a/trusty/nvram/trusty_nvram_device.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "trusty_nvram_implementation.h" - -extern "C" int trusty_nvram_open(const hw_module_t* module, - const char* device_id, - hw_device_t** device_ptr) { - if (strcmp(NVRAM_HARDWARE_DEVICE_ID, device_id) != 0) { - return -EINVAL; - } - - nvram::NvramDeviceAdapter* adapter = new nvram::NvramDeviceAdapter( - module, new nvram::TrustyNvramImplementation); - *device_ptr = adapter->as_device(); - return 0; -} diff --git a/trusty/nvram/trusty_nvram_implementation.cpp b/trusty/nvram/trusty_nvram_implementation.cpp deleted file mode 100644 index 9215c8502..000000000 --- a/trusty/nvram/trusty_nvram_implementation.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "TrustyNVRAM" - -#include "trusty_nvram_implementation.h" - -#include -#include -#include - -#include -#include -#include - -#include - -namespace nvram { -namespace { - -// Character device to open for Trusty IPC connections. -const char kTrustyDeviceName[] = "/dev/trusty-ipc-dev0"; - -// App identifier of the NVRAM app. -const char kTrustyNvramAppId[] = "com.android.trusty.nvram"; - -} // namespace - -TrustyNvramImplementation::~TrustyNvramImplementation() { - if (tipc_nvram_fd_ != -1) { - tipc_close(tipc_nvram_fd_); - tipc_nvram_fd_ = -1; - } -} - -void TrustyNvramImplementation::Execute(const nvram::Request& request, - nvram::Response* response) { - if (!SendRequest(request, response)) { - response->result = NV_RESULT_INTERNAL_ERROR; - } -} - -bool TrustyNvramImplementation::Connect() { - if (tipc_nvram_fd_ != -1) { - return true; - } - - int rc = tipc_connect(kTrustyDeviceName, kTrustyNvramAppId); - if (rc < 0) { - ALOGE("Failed to connect to Trusty NVRAM app: %s\n", strerror(-rc)); - return false; - } - - tipc_nvram_fd_ = rc; - return true; -} - -bool TrustyNvramImplementation::SendRequest(const nvram::Request& request, - nvram::Response* response) { - if (!Connect()) { - return false; - } - - nvram::Blob request_buffer; - if (!nvram::Encode(request, &request_buffer)) { - ALOGE("Failed to encode NVRAM request.\n"); - return false; - } - - ssize_t rc = - write(tipc_nvram_fd_, request_buffer.data(), request_buffer.size()); - if (rc < 0) { - ALOGE("Failed to send NVRAM request: %s\n", strerror(-rc)); - return false; - } - if (static_cast(rc) != request_buffer.size()) { - ALOGE("Failed to send full request buffer: %zd\n", rc); - return false; - } - - rc = read(tipc_nvram_fd_, response_buffer_, sizeof(response_buffer_)); - if (rc < 0) { - ALOGE("Failed to read NVRAM response: %s\n", strerror(-rc)); - return false; - } - - if (static_cast(rc) >= sizeof(response_buffer_)) { - ALOGE("NVRAM response exceeds response buffer size.\n"); - return false; - } - - if (!nvram::Decode(response_buffer_, static_cast(rc), response)) { - ALOGE("Failed to decode NVRAM response.\n"); - return false; - } - - return true; -} - -} // namespace nvram diff --git a/trusty/nvram/trusty_nvram_implementation.h b/trusty/nvram/trusty_nvram_implementation.h deleted file mode 100644 index 60758f7fb..000000000 --- a/trusty/nvram/trusty_nvram_implementation.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_ -#define TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_ - -#include - -#include -#include - -namespace nvram { - -// |TrustyNvramImplementation| proxies requests to the Trusty NVRAM app. It -// serializes the request objects, sends it to the Trusty app and finally reads -// back the result and decodes it. -class TrustyNvramImplementation : public nvram::NvramImplementation { - public: - ~TrustyNvramImplementation() override; - - void Execute(const nvram::Request& request, - nvram::Response* response) override; - - private: - // Connects the IPC channel to the Trusty app if it is not already open. - // Returns true if the channel is open, false on errors. - bool Connect(); - - // Dispatches a command to the trust app. Returns true if successful (note - // that the response may still indicate an error on the Trusty side), false if - // there are any I/O or encoding/decoding errors. - bool SendRequest(const nvram::Request& request, - nvram::Response* response); - - // The file descriptor for the IPC connection to the Trusty app. - int tipc_nvram_fd_ = -1; - - // Response buffer. This puts a hard size limit on the responses from the - // Trusty app. 4096 matches the maximum IPC message size currently supported - // by Trusty. - uint8_t response_buffer_[4096]; -}; - -} // namespace nvram - -#endif // TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_ From c1a56dcab711a7ee238c0af865920ca51b1408a6 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Wed, 9 Aug 2017 18:32:09 +0100 Subject: [PATCH 054/129] zip_archive: reject files that don't start with an LFH signature. Bug: 64211847 Test: zip_archive_test Change-Id: I275e7c4da05ceeb20401b560c72294f29ef63642 --- libziparchive/zip_archive.cc | 16 ++++++++++ libziparchive/zip_archive_test.cc | 49 +++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc index 17c268bc2..4559b328f 100644 --- a/libziparchive/zip_archive.cc +++ b/libziparchive/zip_archive.cc @@ -379,6 +379,22 @@ static int32_t ParseZipArchive(ZipArchive* archive) { return -1; } } + + uint32_t lfh_start_bytes; + if (!archive->mapped_zip.ReadAtOffset(reinterpret_cast(&lfh_start_bytes), + sizeof(uint32_t), 0)) { + ALOGW("Zip: Unable to read header for entry at offset == 0."); + return -1; + } + + if (lfh_start_bytes != LocalFileHeader::kSignature) { + ALOGW("Zip: Entry at offset zero has invalid LFH signature %" PRIx32, lfh_start_bytes); +#if defined(__ANDROID__) + android_errorWriteLog(0x534e4554, "64211847"); +#endif + return -1; + } + ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries); return 0; diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc index dbc14f02c..753bd4427 100644 --- a/libziparchive/zip_archive_test.cc +++ b/libziparchive/zip_archive_test.cc @@ -717,6 +717,55 @@ TEST(ziparchive, ErrorCodeString) { ASSERT_STREQ("I/O error", ErrorCodeString(kIoError)); } +// A zip file whose local file header at offset zero is corrupted. +// +// --------------- +// cat foo > a.txt +// zip a.zip a.txt +// cat a.zip | xxd -i +// +// Manual changes : +// [2] = 0xff // Corrupt the LFH signature of entry 0. +// [3] = 0xff // Corrupt the LFH signature of entry 0. +static const std::vector kZipFileWithBrokenLfhSignature{ + //[lfh-sig-----------], [lfh contents--------------------------------- + 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, + //-------------------------------------------------------------------- + 0x09, 0x4b, 0xa8, 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, + //-------------------------------] [file-name-----------------], [--- + 0x00, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, + // entry-contents------------------------------------------------------ + 0x54, 0x09, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x51, 0x24, 0x8b, 0x59, + //-------------------------------------------------------------------- + 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, + //-------------------------------------], [cd-record-sig-------], [--- + 0x13, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x0a, 0x50, 0x4b, 0x01, 0x02, 0x1e, + // cd-record----------------------------------------------------------- + 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, 0x09, 0x4b, 0xa8, + //-------------------------------------------------------------------- + 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, + //-------------------------------------------------------------------- + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, + //-] [lfh-file-header-off-], [file-name-----------------], [extra---- + 0x81, 0x00, 0x00, 0x00, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54, + //-------------------------------------------------------------------- + 0x05, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x75, 0x78, 0x0b, 0x00, 0x01, + //-------------------------------------------------------], [eocd-sig- + 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, 0x13, 0x00, 0x00, 0x50, 0x4b, + //-------], [--------------------------------------------------------- + 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x4b, 0x00, + //-------------------------------------------] + 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; + +TEST(ziparchive, BrokenLfhSignature) { + TemporaryFile tmp_file; + ASSERT_NE(-1, tmp_file.fd); + ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0], + kZipFileWithBrokenLfhSignature.size())); + ZipArchiveHandle handle; + ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle)); +} + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); From 2cf55995a1e9faf7588e02985fe68a39cdbb3461 Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Wed, 2 Aug 2017 17:54:27 -0700 Subject: [PATCH 055/129] Decrease size of LogBufferElements to 32 bytes. - Remove virtual from the destructor. - Remove mTag and derive it when calling getTag(). - Add a boolean mDropped to tell when a message is dropped. - When dropping a message, and it contains valid tag data, reallocate the message to only contain the tag data. - Add the packed tag to the class. This saves about ~150K of PSS on a typical log stream since it moves the size of the LogBufferElement from 48 bytes to 32 bytes which puts it in a smaller bin. Bug: 63792187 Test: Builds, unit tests pass. Change-Id: Ia5afce343ea3d344fcecd78c648338e94f5c9312 (cherry picked from commit 74e74f96a75209379facaf9d46f424c571b484a8) --- logd/LogBufferElement.cpp | 48 +++++++++++++++++++++++++++++---------- logd/LogBufferElement.h | 30 +++++++++--------------- 2 files changed, 47 insertions(+), 31 deletions(-) diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp index 381c97457..f20ac4514 100644 --- a/logd/LogBufferElement.cpp +++ b/logd/LogBufferElement.cpp @@ -41,22 +41,20 @@ LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, mTid(tid), mRealTime(realtime), mMsgLen(len), - mLogId(log_id) { + mLogId(log_id), + mDropped(false) { mMsg = new char[len]; memcpy(mMsg, msg, len); - mTag = (isBinary() && (mMsgLen >= sizeof(uint32_t))) - ? le32toh(reinterpret_cast(mMsg)->tag) - : 0; } LogBufferElement::LogBufferElement(const LogBufferElement& elem) - : mTag(elem.mTag), - mUid(elem.mUid), + : mUid(elem.mUid), mPid(elem.mPid), mTid(elem.mTid), mRealTime(elem.mRealTime), mMsgLen(elem.mMsgLen), - mLogId(elem.mLogId) { + mLogId(elem.mLogId), + mDropped(elem.mDropped) { mMsg = new char[mMsgLen]; memcpy(mMsg, elem.mMsg, mMsgLen); } @@ -65,6 +63,32 @@ LogBufferElement::~LogBufferElement() { delete[] mMsg; } +uint32_t LogBufferElement::getTag() const { + return (isBinary() && + ((mDropped && mMsg != nullptr) || + (!mDropped && mMsgLen >= sizeof(android_event_header_t)))) + ? reinterpret_cast(mMsg)->tag + : 0; +} + +unsigned short LogBufferElement::setDropped(unsigned short value) { + // The tag information is saved in mMsg data, if the tag is non-zero + // save only the information needed to get the tag. + if (getTag() != 0) { + if (mMsgLen > sizeof(android_event_header_t)) { + char* truncated_msg = new char[sizeof(android_event_header_t)]; + memcpy(truncated_msg, mMsg, sizeof(android_event_header_t)); + delete[] mMsg; + mMsg = truncated_msg; + } // mMsgLen == sizeof(android_event_header_t), already at minimum. + } else { + delete[] mMsg; + mMsg = nullptr; + } + mDropped = true; + return mDroppedCount = value; +} + // caller must own and free character string char* android::tidToName(pid_t tid) { char* retval = NULL; @@ -164,8 +188,8 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent // identical to below to calculate the buffer size required const char* type = lastSame ? "identical" : "expire"; size_t len = snprintf(NULL, 0, format_uid, mUid, name ? name : "", - commName ? commName : "", type, mDropped, - (mDropped > 1) ? "s" : ""); + commName ? commName : "", type, getDropped(), + (getDropped() > 1) ? "s" : ""); size_t hdrLen; if (isBinary()) { @@ -196,8 +220,8 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent } snprintf(buffer + hdrLen, len + 1, format_uid, mUid, name ? name : "", - commName ? commName : "", type, mDropped, - (mDropped > 1) ? "s" : ""); + commName ? commName : "", type, getDropped(), + (getDropped() > 1) ? "s" : ""); free(const_cast(name)); free(const_cast(commName)); @@ -225,7 +249,7 @@ log_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, char* buffer = NULL; - if (!mMsg) { + if (mDropped) { entry.len = populateDroppedMessage(buffer, parent, lastSame); if (!entry.len) return mRealTime; iovec[1].iov_base = buffer; diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h index 814ec8785..b168645f1 100644 --- a/logd/LogBufferElement.h +++ b/logd/LogBufferElement.h @@ -32,25 +32,25 @@ class LogBuffer; // chatty for the temporal expire messages #define EXPIRE_RATELIMIT 10 // maximum rate in seconds to report expiration -class LogBufferElement { +class __attribute__((packed)) LogBufferElement { friend LogBuffer; // sized to match reality of incoming log packets - uint32_t mTag; // only valid for isBinary() const uint32_t mUid; const uint32_t mPid; const uint32_t mTid; log_time mRealTime; char* mMsg; union { - const uint16_t mMsgLen; // mMSg != NULL - uint16_t mDropped; // mMsg == NULL + const uint16_t mMsgLen; // mDropped == false + uint16_t mDroppedCount; // mDropped == true }; const uint8_t mLogId; + bool mDropped; static atomic_int_fast64_t sequence; - // assumption: mMsg == NULL + // assumption: mDropped == true size_t populateDroppedMessage(char*& buffer, LogBuffer* parent, bool lastSame); @@ -58,7 +58,7 @@ class LogBufferElement { LogBufferElement(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg, unsigned short len); LogBufferElement(const LogBufferElement& elem); - virtual ~LogBufferElement(); + ~LogBufferElement(); bool isBinary(void) const { return (mLogId == LOG_ID_EVENTS) || (mLogId == LOG_ID_SECURITY); @@ -76,24 +76,16 @@ class LogBufferElement { pid_t getTid(void) const { return mTid; } - uint32_t getTag() const { - return mTag; - } + uint32_t getTag() const; unsigned short getDropped(void) const { - return mMsg ? 0 : mDropped; - } - unsigned short setDropped(unsigned short value) { - if (mMsg) { - delete[] mMsg; - mMsg = NULL; - } - return mDropped = value; + return mDropped ? mDroppedCount : 0; } + unsigned short setDropped(unsigned short value); unsigned short getMsgLen() const { - return mMsg ? mMsgLen : 0; + return mDropped ? 0 : mMsgLen; } const char* getMsg() const { - return mMsg; + return mDropped ? nullptr : mMsg; } log_time getRealTime(void) const { return mRealTime; From 2e93eda69cf20d9c04d56ea6bf1e2ea62ad62eb4 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 15 Aug 2017 07:58:20 -0700 Subject: [PATCH 056/129] Don't include the build number in the adbd binary. We want repeatable builds for minimal OTAs. Bug: http://b/64634017 Bug: 64709603 (presubmit balking at the line above) Test: repeated builds after `touch daemon/main.cpp` keep same md5sum Change-Id: Iedeb44377ea45bbf20e2212760802198a57dc14a --- adb/daemon/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp index e0629abdd..3ecbc44f2 100644 --- a/adb/daemon/main.cpp +++ b/adb/daemon/main.cpp @@ -239,8 +239,8 @@ int main(int argc, char** argv) { adb_device_banner = optarg; break; case 'v': - printf("Android Debug Bridge Daemon version %d.%d.%d (%s)\n", ADB_VERSION_MAJOR, - ADB_VERSION_MINOR, ADB_SERVER_VERSION, ADB_VERSION); + printf("Android Debug Bridge Daemon version %d.%d.%d\n", ADB_VERSION_MAJOR, + ADB_VERSION_MINOR, ADB_SERVER_VERSION); return 0; default: // getopt already prints "adbd: invalid option -- %c" for us. From 421a5e46b780cab394e4bc18745b8555ba26afa5 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Wed, 16 Aug 2017 23:32:54 +0900 Subject: [PATCH 057/129] Make the rs namespace visible This allows us to dlopen libRS_internal.so directly from the rs namespace, not from the sphal namespace. Bug: 64747884 Test: VtsHalRenderscriptV1_0TargetTest successful on the device built with BOARD_VNDK_VERSION=current and [system] namespace config is applied to /data/nativetest[64]/* processes. Change-Id: I0b441791e395798e80a84592ca01e771bb1c201a --- rootdir/etc/ld.config.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index 16db77050..57ec518cb 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt @@ -81,6 +81,7 @@ namespace.sphal.link.rs.shared_libs = libRS_internal.so # to load the compiled *.so file and libmediandk.so can be used here. ############################################################################### namespace.rs.isolated = true +namespace.rs.visible = true namespace.rs.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/vendor/${LIB} namespace.rs.permitted.paths = /vendor/${LIB}:/data From 34c001bff2ed63c26fa0f2a155ff317a44378d6c Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Mon, 7 Aug 2017 14:29:26 -0400 Subject: [PATCH 058/129] fastboot: Add --disable-verity and --disable-verification options. This can be used to disable verity and/or verification when flashing a build to a device. It works with both 'fastboot flashall' and 'fastboot flash vbmeta /path/to/vbmeta.img'. Bug: 62903976 Test: Manually tested. Merged-In: Iad22d42a9dd5befd70ecd0224803721a10a28d90 Change-Id: Iad22d42a9dd5befd70ecd0224803721a10a28d90 (cherry picked from commit b6ea435a2048a1e6abe76bd47380da6911d8b28c) --- fastboot/fastboot.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index 271ca9527..49d943837 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -93,6 +93,9 @@ static unsigned ramdisk_offset = 0x01000000; static unsigned second_offset = 0x00f00000; static unsigned tags_offset = 0x00000100; +static bool g_disable_verity = false; +static bool g_disable_verification = false; + static const std::string convert_fbe_marker_filename("convert_fbe"); enum fb_buffer_type { @@ -419,6 +422,10 @@ static int show_help() { " --skip-reboot Will not reboot the device when\n" " performing commands that normally\n" " trigger a reboot.\n" + " --disable-verity Set the disable-verity flag in the\n" + " the vbmeta image being flashed.\n" + " --disable-verification Set the disable-verification flag in" + " the vbmeta image being flashed.\n" #if !defined(_WIN32) " --wipe-and-use-fbe On devices which support it,\n" " erase userdata and cache, and\n" @@ -858,10 +865,55 @@ static bool load_buf(Transport* transport, const char* fname, struct fastboot_bu return load_buf_fd(transport, fd.release(), buf); } +static void rewrite_vbmeta_buffer(struct fastboot_buffer* buf) { + // Buffer needs to be at least the size of the VBMeta struct which + // is 256 bytes. + if (buf->sz < 256) { + return; + } + + int fd = make_temporary_fd(); + if (fd == -1) { + die("Failed to create temporary file for vbmeta rewriting"); + } + + std::string data; + if (!android::base::ReadFdToString(buf->fd, &data)) { + die("Failed reading from vbmeta"); + } + + // There's a 32-bit big endian |flags| field at offset 120 where + // bit 0 corresponds to disable-verity and bit 1 corresponds to + // disable-verification. + // + // See external/avb/libavb/avb_vbmeta_image.h for the layout of + // the VBMeta struct. + if (g_disable_verity) { + data[123] |= 0x01; + } + if (g_disable_verification) { + data[123] |= 0x02; + } + + if (!android::base::WriteStringToFd(data, fd)) { + die("Failed writing to modified vbmeta"); + } + close(buf->fd); + buf->fd = fd; + lseek(fd, 0, SEEK_SET); +} + static void flash_buf(const char *pname, struct fastboot_buffer *buf) { sparse_file** s; + // Rewrite vbmeta if that's what we're flashing and modification has been requested. + if ((g_disable_verity || g_disable_verification) && + (strcmp(pname, "vbmeta") == 0 || strcmp(pname, "vbmeta_a") == 0 || + strcmp(pname, "vbmeta_b") == 0)) { + rewrite_vbmeta_buffer(buf); + } + switch (buf->type) { case FB_BUFFER_SPARSE: { std::vector> sparse_files; @@ -1470,6 +1522,8 @@ int main(int argc, char **argv) {"set-active", optional_argument, 0, 'a'}, {"skip-secondary", no_argument, 0, 0}, {"skip-reboot", no_argument, 0, 0}, + {"disable-verity", no_argument, 0, 0}, + {"disable-verification", no_argument, 0, 0}, #if !defined(_WIN32) {"wipe-and-use-fbe", no_argument, 0, 0}, #endif @@ -1555,6 +1609,10 @@ int main(int argc, char **argv) skip_secondary = true; } else if (strcmp("skip-reboot", longopts[longindex].name) == 0 ) { skip_reboot = true; + } else if (strcmp("disable-verity", longopts[longindex].name) == 0 ) { + g_disable_verity = true; + } else if (strcmp("disable-verification", longopts[longindex].name) == 0 ) { + g_disable_verification = true; #if !defined(_WIN32) } else if (strcmp("wipe-and-use-fbe", longopts[longindex].name) == 0) { wants_wipe = true; From 68b0ec6487186d59b1ec1dfcbc85673fc452bc4a Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Wed, 16 Aug 2017 18:54:20 +0900 Subject: [PATCH 059/129] gatekeeperd: use std::unique_ptr std::unique_ptr is available in this scope. Substitue the UniquePtr to std::unique_ptr. Bug: 63686260 Test: build and boot Change-Id: Ib8ea3fb5c49c0e92d962f65f1139b073168f8698 --- gatekeeperd/SoftGateKeeper.h | 4 ++-- gatekeeperd/SoftGateKeeperDevice.h | 4 ++-- gatekeeperd/gatekeeperd.cpp | 3 ++- gatekeeperd/tests/gatekeeper_test.cpp | 1 - 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gatekeeperd/SoftGateKeeper.h b/gatekeeperd/SoftGateKeeper.h index 92d175290..2f4f4d7e6 100644 --- a/gatekeeperd/SoftGateKeeper.h +++ b/gatekeeperd/SoftGateKeeper.h @@ -27,10 +27,10 @@ extern "C" { #include #include -#include #include #include +#include namespace gatekeeper { @@ -173,7 +173,7 @@ private: typedef std::unordered_map FailureRecordMap; typedef std::unordered_map FastHashMap; - UniquePtr key_; + std::unique_ptr key_; FailureRecordMap failure_map_; FastHashMap fast_hash_map_; }; diff --git a/gatekeeperd/SoftGateKeeperDevice.h b/gatekeeperd/SoftGateKeeperDevice.h index 229f9a9e6..e3dc068fb 100644 --- a/gatekeeperd/SoftGateKeeperDevice.h +++ b/gatekeeperd/SoftGateKeeperDevice.h @@ -19,7 +19,7 @@ #include "SoftGateKeeper.h" -#include +#include using namespace gatekeeper; @@ -68,7 +68,7 @@ public: const uint8_t *provided_password, uint32_t provided_password_length, uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll); private: - UniquePtr impl_; + std::unique_ptr impl_; }; } // namespace gatekeeper diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp index 184c6d222..61c880409 100644 --- a/gatekeeperd/gatekeeperd.cpp +++ b/gatekeeperd/gatekeeperd.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -383,7 +384,7 @@ public: private: sp hw_device; - UniquePtr soft_device; + std::unique_ptr soft_device; bool clear_state_if_needed_done; }; diff --git a/gatekeeperd/tests/gatekeeper_test.cpp b/gatekeeperd/tests/gatekeeper_test.cpp index b3aea7b5d..100375fb8 100644 --- a/gatekeeperd/tests/gatekeeper_test.cpp +++ b/gatekeeperd/tests/gatekeeper_test.cpp @@ -19,7 +19,6 @@ #include #include -#include #include "../SoftGateKeeper.h" From 2c9140f54e893baf351d7f11a93285fa8227536f Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Tue, 11 Jul 2017 18:58:51 +0900 Subject: [PATCH 060/129] Make libvndksupport look for default namespace as well. In vendor process, libvndksupport must look for "default" namespace, instead of "sphal" namespace to open hal libraries. Bug: 63411330 Test: Boot the device. Change-Id: I26208b6f47708f83e0679fd72ca7471ade84fff9 --- libvndksupport/linker.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/libvndksupport/linker.c b/libvndksupport/linker.c index 703b593fa..d06cafc8e 100644 --- a/libvndksupport/linker.c +++ b/libvndksupport/linker.c @@ -23,23 +23,38 @@ extern struct android_namespace_t* android_get_exported_namespace(const char*); +static const char* namespace_name = NULL; + +static struct android_namespace_t* get_vendor_namespace() { + const char* namespace_names[] = {"sphal", "default", NULL}; + static struct android_namespace_t* vendor_namespace = NULL; + if (vendor_namespace == NULL) { + int name_idx = 0; + while (namespace_names[name_idx] != NULL) { + vendor_namespace = android_get_exported_namespace(namespace_names[name_idx]); + if (vendor_namespace != NULL) { + namespace_name = namespace_names[name_idx]; + break; + } + name_idx++; + } + } + return vendor_namespace; +} + void* android_load_sphal_library(const char* name, int flag) { - struct android_namespace_t* sphal_namespace = android_get_exported_namespace("sphal"); - if (sphal_namespace != NULL) { + struct android_namespace_t* vendor_namespace = get_vendor_namespace(); + if (vendor_namespace != NULL) { const android_dlextinfo dlextinfo = { - .flags = ANDROID_DLEXT_USE_NAMESPACE, .library_namespace = sphal_namespace, + .flags = ANDROID_DLEXT_USE_NAMESPACE, .library_namespace = vendor_namespace, }; void* handle = android_dlopen_ext(name, flag, &dlextinfo); if (!handle) { - ALOGE( - "Could not load %s from sphal namespace: %s.", - name, dlerror()); + ALOGE("Could not load %s from %s namespace: %s.", name, namespace_name, dlerror()); } return handle; } else { - ALOGD( - "Loading %s from current namespace instead of sphal namespace.", - name); + ALOGD("Loading %s from current namespace instead of sphal namespace.", name); return dlopen(name, flag); } } From c2b07dbec49687ea2e4f4a852fe2c7f86f9e3f1f Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Fri, 4 Aug 2017 17:33:54 +0900 Subject: [PATCH 061/129] Add vndk tag for libunwindstack which must be a vndk-sp As a VNDK-SP module, Android.bp must have 'vndk' tag as well as 'vendor_available: true'. The 'vndk' tag for VNDK-SP module is formated as below: vndk: { enabled: true, support_system_process: true, }, VNDK-SP modules will be installed both in system/lib(64) as normal and in system/lib(64)/vndk-sp as a vendor variant. Bug: 63866913 Test: build with BOARD_VNDK_VERSION=current Change-Id: Idb4757988d1799ffcd3341343fcc4dac34bf7ef3 (cherry picked from commit 14d540a1567994301465ad6c820e6e4973f19c85) --- libunwindstack/Android.bp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp index b971a9eda..b4a6cbad0 100644 --- a/libunwindstack/Android.bp +++ b/libunwindstack/Android.bp @@ -35,6 +35,10 @@ cc_defaults { cc_library { name: "libunwindstack", vendor_available: true, + vndk: { + enabled: true, + support_system_process: true, + }, defaults: ["libunwindstack_flags"], export_include_dirs: ["include"], From b9beeed5a33a4e7a3613d4eb41cd7f7b3ff3981c Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Mon, 21 Aug 2017 15:53:54 -0700 Subject: [PATCH 062/129] Fix use-after-free of stack-allocated temporary string. Bug: 64848081 Test: built and successfully booted again Merged-In: I93c899249bf2cc5ab8d880c0eaff471518e73121 Change-Id: I08e6f71a7c5151544b9434eb0d362a236202cd31 --- init/init.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/init/init.cpp b/init/init.cpp index 715dd72a2..9671560eb 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -807,13 +807,15 @@ static bool selinux_load_split_policy() { return false; } std::string mapping_file("/system/etc/selinux/mapping/" + vend_plat_vers + ".cil"); + const std::string version_as_string = std::to_string(max_policy_version); + // clang-format off const char* compile_args[] = { "/system/bin/secilc", plat_policy_cil_file, "-M", "true", "-G", "-N", // Target the highest policy language version supported by the kernel - "-c", std::to_string(max_policy_version).c_str(), + "-c", version_as_string.c_str(), mapping_file.c_str(), "/vendor/etc/selinux/nonplat_sepolicy.cil", "-o", compiled_sepolicy, From 063a3fa4d2b1d195eca512b3bd479a9fed882c12 Mon Sep 17 00:00:00 2001 From: Hung-ying Tyan Date: Fri, 28 Jul 2017 19:09:33 +0800 Subject: [PATCH 063/129] Move trusty reference implementations to /vendor Trusty implementations are provided by vendors. This patch moves the AOSP reference implementations to the vendor partition. Bug: 63085384 Test: Build gordon_peak which adopts trusty as the TEE and confirm that libtrusty and gateway.trusty are moved to /vendor. Test: Build marlin which does not adopt trusty as the TEE and confirm that this patch has no effect on the build result. Test: mmm BOARD_VNDK_VERSION=current system/core/trusty Change-Id: I7f6d897b86c69d06923a18d28154760e006dd193 --- CleanSpec.mk | 10 ++++++++++ trusty/gatekeeper/Android.bp | 2 ++ trusty/keymaster/Android.bp | 3 +++ trusty/libtrusty/Android.bp | 1 + trusty/libtrusty/tipc-test/Android.bp | 6 ++++-- trusty/storage/interface/Android.bp | 1 + trusty/storage/lib/Android.bp | 5 ++++- trusty/storage/proxy/Android.bp | 2 ++ trusty/storage/proxy/proxy.c | 2 +- trusty/storage/tests/Android.bp | 3 +++ 10 files changed, 31 insertions(+), 4 deletions(-) diff --git a/CleanSpec.mk b/CleanSpec.mk index 5b5eff406..d5b755461 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -60,3 +60,13 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.$(TARGET_D $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.$(TARGET_DEVICE).so) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/vendor) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/init.rc) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libtrusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/libtrusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/keystore.trusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/keystore.trusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.trusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.trusty.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/secure-storage-unit-test) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/storageproxyd) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/tipc-test) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/trusty_keymaster_tipc) diff --git a/trusty/gatekeeper/Android.bp b/trusty/gatekeeper/Android.bp index a9566a17e..65b271a79 100644 --- a/trusty/gatekeeper/Android.bp +++ b/trusty/gatekeeper/Android.bp @@ -22,6 +22,7 @@ cc_library_shared { name: "gatekeeper.trusty", + vendor: true, relative_install_path: "hw", @@ -43,4 +44,5 @@ cc_library_shared { "libcutils", "libtrusty", ], + header_libs: ["libhardware_headers"], } diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp index 6b9d72359..0820fa0ec 100644 --- a/trusty/keymaster/Android.bp +++ b/trusty/keymaster/Android.bp @@ -25,6 +25,7 @@ // and ECDSA keys. cc_binary { name: "trusty_keymaster_tipc", + vendor: true, srcs: [ "trusty_keymaster_device.cpp", "trusty_keymaster_ipc.cpp", @@ -45,6 +46,7 @@ cc_binary { // keystore.trusty is the HAL used by keystore on Trusty devices. cc_library_shared { name: "keystore.trusty", + vendor: true, relative_install_path: "hw", srcs: [ "module.cpp", @@ -65,4 +67,5 @@ cc_library_shared { "liblog", "libcutils", ], + header_libs: ["libhardware_headers"], } diff --git a/trusty/libtrusty/Android.bp b/trusty/libtrusty/Android.bp index f316da229..88d624048 100644 --- a/trusty/libtrusty/Android.bp +++ b/trusty/libtrusty/Android.bp @@ -18,6 +18,7 @@ subdirs = [ cc_library { name: "libtrusty", + vendor: true, srcs: ["trusty.c"], export_include_dirs: ["include"], diff --git a/trusty/libtrusty/tipc-test/Android.bp b/trusty/libtrusty/tipc-test/Android.bp index cb00fe772..25a3cb05f 100644 --- a/trusty/libtrusty/tipc-test/Android.bp +++ b/trusty/libtrusty/tipc-test/Android.bp @@ -14,12 +14,14 @@ cc_test { name: "tipc-test", - static_executable: true, + vendor: true, srcs: ["tipc_test.c"], static_libs: [ - "libc", "libtrusty", + ], + shared_libs: [ + "libc", "liblog", ], gtest: false, diff --git a/trusty/storage/interface/Android.bp b/trusty/storage/interface/Android.bp index a551c37aa..18b4a5f90 100644 --- a/trusty/storage/interface/Android.bp +++ b/trusty/storage/interface/Android.bp @@ -16,5 +16,6 @@ cc_library_static { name: "libtrustystorageinterface", + vendor: true, export_include_dirs: ["include"], } diff --git a/trusty/storage/lib/Android.bp b/trusty/storage/lib/Android.bp index 5eb3f0778..4e41674bd 100644 --- a/trusty/storage/lib/Android.bp +++ b/trusty/storage/lib/Android.bp @@ -16,16 +16,19 @@ cc_library_static { name: "libtrustystorage", + vendor: true, srcs: ["storage.c"], export_include_dirs: ["include"], static_libs: [ - "liblog", "libtrusty", "libtrustystorageinterface", ], + shared_libs: [ + "liblog", + ], cflags: [ "-fvisibility=hidden", diff --git a/trusty/storage/proxy/Android.bp b/trusty/storage/proxy/Android.bp index eb34df014..da8542d5a 100644 --- a/trusty/storage/proxy/Android.bp +++ b/trusty/storage/proxy/Android.bp @@ -16,6 +16,7 @@ cc_binary { name: "storageproxyd", + vendor: true, srcs: [ "ipc.c", @@ -25,6 +26,7 @@ cc_binary { ], shared_libs: ["liblog"], + header_libs: ["libcutils_headers"], static_libs: [ "libtrustystorageinterface", diff --git a/trusty/storage/proxy/proxy.c b/trusty/storage/proxy/proxy.c index 27e58917f..41263e5df 100644 --- a/trusty/storage/proxy/proxy.c +++ b/trusty/storage/proxy/proxy.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include "ipc.h" #include "log.h" diff --git a/trusty/storage/tests/Android.bp b/trusty/storage/tests/Android.bp index 3eff3f27a..1b003e9fa 100644 --- a/trusty/storage/tests/Android.bp +++ b/trusty/storage/tests/Android.bp @@ -16,6 +16,7 @@ cc_test { name: "secure-storage-unit-test", + vendor: true, cflags: [ "-g", @@ -29,6 +30,8 @@ cc_test { "libtrustystorageinterface", "libtrustystorage", "libtrusty", + ], + shared_libs: [ "liblog", ], From 24c29f1be49f47a6d8a098a10591d9c3f0d4e8ee Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Fri, 16 Jun 2017 18:11:35 +0900 Subject: [PATCH 064/129] Implement system namespace for vendor process For vendor process default namespace searches as following order: 1. /vendor/lib/(hw|egl), /vendor/lib: Vendor libs + VNDK-vnd-ext 2. /system/lib/vndk-$(ver): VNDK libs 3. /vendor/lib/vndk-sp-$(ver): VNDK-SP-vnd-ext 4. /system/lib/vndk-sp-$(ver): VNDK-SP and searches system namespace (/system/lib) only for LL-NDK libs. This configuarion is used only with BOARD_VNDK_VERSION is defined. Bug: 37192038 Test: build with 'BOARD_VNDK_VERSION=current' and boot Change-Id: If9778b9266a084846ba8fe73e6bff25828359d33 --- rootdir/Android.mk | 8 ++ rootdir/etc/ld.config.vndk.txt | 158 +++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 rootdir/etc/ld.config.vndk.txt diff --git a/rootdir/Android.mk b/rootdir/Android.mk index 046557eb2..07902fc3d 100644 --- a/rootdir/Android.mk +++ b/rootdir/Android.mk @@ -195,7 +195,15 @@ include $(CLEAR_VARS) LOCAL_MODULE := ld.config.txt ifeq ($(PRODUCT_FULL_TREBLE)|$(SANITIZE_TARGET),true|) +ifdef BOARD_VNDK_VERSION + ifeq ($(BOARD_VNDK_RUNTIME_DISABLE),true) + LOCAL_SRC_FILES := etc/ld.config.txt + else + LOCAL_SRC_FILES := etc/ld.config.vndk.txt + endif +else LOCAL_SRC_FILES := etc/ld.config.txt +endif else LOCAL_SRC_FILES := etc/ld.config.legacy.txt endif diff --git a/rootdir/etc/ld.config.vndk.txt b/rootdir/etc/ld.config.vndk.txt new file mode 100644 index 000000000..c7e257344 --- /dev/null +++ b/rootdir/etc/ld.config.vndk.txt @@ -0,0 +1,158 @@ +# Copyright (C) 2017 The Android Open Source Project +# +# Bionic loader config file. +# + +# Don't change the order here. The first pattern that matches with the +# absolution path of an executable is selected. +dir.system = /system/bin/ +dir.system = /system/xbin/ +dir.vendor = /vendor/bin/ +dir.vendor = /data/nativetest/vendor +dir.vendor = /data/nativetest64/vendor +dir.vendor = /data/benchmarktest/vendor +dir.vendor = /data/benchmarktest64/vendor +dir.system = /data/nativetest +dir.system = /data/nativetest64 +dir.system = /data/benchmarktest +dir.system = /data/benchmarktest64 + +[system] +additional.namespaces = sphal,vndk,rs + +############################################################################### +# "default" namespace +# +# Framework-side code runs in this namespace. Anything from /vendor partition +# can't be loaded in this namespace. +############################################################################### +namespace.default.isolated = false +namespace.default.search.paths = /system/${LIB}:/vendor/${LIB} +namespace.default.permitted.paths = /system/${LIB}:/vendor/${LIB} + +namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}:/data/asan/vendor/${LIB}:/vendor/${LIB} +namespace.default.asan.permitted.paths = /data/asan/system/${LIB}:/system/${LIB}:/data/asan/vendor/${LIB}:/vendor/${LIB} + +# TODO(b/37013858): remove all dependencies to /vendor/lib from system processes +# When this is done, comment out following three lines and remove the three +# lines above +#namespace.default.isolated = true +#namespace.default.search.paths = /system/${LIB} +#namespace.default.permitted.paths = /system/${LIB} +# +#namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB} +#namespace.default.asan.permitted.paths = /data/asan/system/${LIB}:/system/${LIB} + +############################################################################### +# "sphal" namespace +# +# SP-HAL(Sameprocess-HAL)s are the only vendor libraries that are allowed to be +# loaded inside system processes. libEGL_.so, libGLESv2_.so, +# android.hardware.graphics.mapper@2.0-impl.so, etc are SP-HALs. +# +# This namespace is exclusivly for SP-HALs. When the framework tries to dynami- +# cally load SP-HALs, android_dlopen_ext() is used to explicitly specifying +# that they should be searched and loaded from this namespace. +# +# Note that there is no link from the default namespace to this namespace. +############################################################################### +namespace.sphal.isolated = true +namespace.sphal.visible = true +namespace.sphal.search.paths = /vendor/${LIB}/egl:/vendor/${LIB}/hw:/vendor/${LIB} +namespace.sphal.permitted.paths = /vendor/${LIB}:/system/${LIB}/vndk-sp/hw + +namespace.sphal.asan.search.paths = /data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl:/data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}:/vendor/${LIB} +namespace.sphal.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB} + +# Once in this namespace, access to libraries in /system/lib is restricted. Only +# libs listed here can be used. +namespace.sphal.links = default,vndk,rs + +# WARNING: only NDK libs can be listed here. +namespace.sphal.link.default.shared_libs = libEGL.so:libm.so:libandroid_net.so:libvndksupport.so:libc.so:libGLESv1_CM.so:liblog.so:libsync.so:libnativewindow.so:libGLESv3.so:libdl.so:libGLESv2.so + +# WARNING: only VNDK-SP libs can be listed here. DO NOT EDIT this line. +namespace.sphal.link.vndk.shared_libs = libhardware.so:libc++.so:libhidlbase.so:libhwbinder.so:libhidltransport.so:libbase.so:libhidlmemory.so:libRS.so:libRSDriver.so:libcutils.so:libion.so:libRSCpuRef.so:android.hardware.graphics.common@1.0.so:android.hardware.graphics.mapper@2.0.so:android.hidl.memory@1.0.so:libbcinfo.so:android.hardware.graphics.allocator@2.0.so:android.hardware.renderscript@1.0.so:libutils.so:libz.so + +# Renderscript gets separate namespace +namespace.sphal.link.rs.shared_libs = libRS_internal.so + +############################################################################### +# "rs" namespace +# +# This namespace is exclusively for Renderscript internal libraries. +# This namespace has slightly looser restriction than the vndk namespace because +# of the genuine characteristics of Renderscript; /data is in the permitted path +# to load the compiled *.so file and libmediandk.so can be used here. +############################################################################### +namespace.rs.isolated = true +namespace.rs.visible = true +namespace.rs.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/vendor/${LIB} +namespace.rs.permitted.paths = /vendor/${LIB}:/data + +namespace.rs.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/vendor/${LIB}:/vendor/${LIB} +namespace.rs.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data + +namespace.rs.links = default,vndk +namespace.rs.link.default.shared_libs = libEGL.so:libm.so:libandroid_net.so:libvndksupport.so:libc.so:libGLESv1_CM.so:liblog.so:libsync.so:libnativewindow.so:libGLESv3.so:libdl.so:libGLESv2.so:libmediandk.so:libft2.so +namespace.rs.link.vndk.shared_libs = libhardware.so:libc++.so:libhidlbase.so:libhwbinder.so:libhidltransport.so:libbase.so:libhidlmemory.so:libRS.so:libRSDriver.so:libcutils.so:libion.so:libRSCpuRef.so:android.hardware.graphics.common@1.0.so:android.hardware.graphics.mapper@2.0.so:android.hidl.memory@1.0.so:libbcinfo.so:android.hardware.graphics.allocator@2.0.so:android.hardware.renderscript@1.0.so:libutils.so:libz.so + +############################################################################### +# "vndk" namespace +# +# This namespace is exclusively for vndk-sp libs. +############################################################################### +namespace.vndk.isolated = true +namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp +namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl + +namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp +namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl + +# When these NDK libs are required inside this namespace, then it is redirected +# to the default namespace. This is possible since their ABI is stable across +# Android releases. +namespace.vndk.links = default +namespace.vndk.link.default.shared_libs = libEGL.so:libm.so:libandroid_net.so:libvndksupport.so:libc.so:libGLESv1_CM.so:liblog.so:libsync.so:libnativewindow.so:libGLESv3.so:libdl.so:libGLESv2.so + +############################################################################### +# Namespace config for vendor processes. In O, no restriction is enforced for +# them. However, in O-MR1, access to /system/${LIB} will not be allowed to +# the default namespace. 'system' namespace will be added to give limited +# (LL-NDK only) access. +############################################################################### +[vendor] +additional.namespaces = system + +############################################################################### +# "default" namespace +# +# Vendor-side code runs in this namespace. +############################################################################### +namespace.default.isolated = true +namespace.default.visible = true + +namespace.default.search.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl:/vendor/${LIB}:/system/${LIB}/vndk:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp +namespace.default.permitted.paths = /vendor:/system/${LIB}/vndk:/system/${LIB}/vndk-sp + +namespace.default.asan.search.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl:/data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp +namespace.default.asan.permitted.paths = /data/asan/vendor:/vendor:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp + +namespace.default.links = system +namespace.default.link.system.shared_libs = libEGL.so:libm.so:libandroid_net.so:libvndksupport.so:libc.so:libGLESv1_CM.so:liblog.so:libsync.so:libnativewindow.so:libGLESv3.so:libdl.so:libGLESv2.so:libpowermanager.so:libmedia.so:libandroid_runtime.so +# libpowermanager.so must be removed after we have fix for libsdm-color.so (b/64732165) +# libmedia.so must be removed after we have fix for lib-dplmedia.so (b/64427765) +# libandroid_runtime.so must be removed after we have a fix for qseeproxydaemon (b/64820887) + +############################################################################### +# "system" namespace +# +# This is for vendor process to use LL-NDK in system partition. +############################################################################### +namespace.system.isolated = false +namespace.system.search.paths = /system/${LIB} +namespace.system.permitted.paths = /system/${LIB} + +namespace.system.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB} +namespace.system.asan.permitted.paths = /data/asan/system/${LIB}:/system/${LIB} + From f0ecf57e566d97cf2903dac45a1bc80302d126aa Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Wed, 23 Aug 2017 11:43:57 -0700 Subject: [PATCH 065/129] fastboot: bail out if failed to generate fs image we don't want to continue fastboot process if failed to generate fs image. Print an error message and exit early. Bug: 64915319 Change-Id: I5506d2a7a5063c188685633d6c3890239f9d658e --- fastboot/fastboot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index 271ca9527..35a29efb0 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -1411,7 +1411,7 @@ static void fb_perform_format(Transport* transport, if (fs_generator_generate(gen, output.path, size, initial_dir, eraseBlkSize, logicalBlkSize)) { - fprintf(stderr, "Cannot generate image: %s\n", strerror(errno)); + die("Cannot generate image for %s\n", partition); return; } From 3094de968443c60345f63318f14a5d919df762d5 Mon Sep 17 00:00:00 2001 From: Justin Yun Date: Fri, 25 Aug 2017 12:30:44 +0900 Subject: [PATCH 066/129] vndk: add vendor/lib(64)/vndk for vendor namespace When the vndk is extended by vendor, the libs in vendor/lib(64)/vndk will override system/lib(64)/vndk libs. Vendor binaries will search vndk libs in vendor/lib(64)/vndk prior to system/lib(64)/vndk. Also, remove a workaround for libsdm-color.so Bug: 65032513 Test: build and boot check for libsdm-color.so will be loaded on boot Test: currently no libs exist on vendor/lib(64)/vndk. No test for it Change-Id: I99ed37eb1a9e92c83533e2d92c9c06db11f01e97 --- rootdir/etc/ld.config.vndk.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/rootdir/etc/ld.config.vndk.txt b/rootdir/etc/ld.config.vndk.txt index c7e257344..063aab923 100644 --- a/rootdir/etc/ld.config.vndk.txt +++ b/rootdir/etc/ld.config.vndk.txt @@ -132,15 +132,14 @@ additional.namespaces = system namespace.default.isolated = true namespace.default.visible = true -namespace.default.search.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl:/vendor/${LIB}:/system/${LIB}/vndk:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp +namespace.default.search.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl:/vendor/${LIB}:/vendor/${LIB}/vndk:/system/${LIB}/vndk:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.default.permitted.paths = /vendor:/system/${LIB}/vndk:/system/${LIB}/vndk-sp -namespace.default.asan.search.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl:/data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp +namespace.default.asan.search.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl:/data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/vendor/${LIB}/vndk:/vendor/${LIB}/vndk:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.default.asan.permitted.paths = /data/asan/vendor:/vendor:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.default.links = system -namespace.default.link.system.shared_libs = libEGL.so:libm.so:libandroid_net.so:libvndksupport.so:libc.so:libGLESv1_CM.so:liblog.so:libsync.so:libnativewindow.so:libGLESv3.so:libdl.so:libGLESv2.so:libpowermanager.so:libmedia.so:libandroid_runtime.so -# libpowermanager.so must be removed after we have fix for libsdm-color.so (b/64732165) +namespace.default.link.system.shared_libs = libEGL.so:libm.so:libandroid_net.so:libvndksupport.so:libc.so:libGLESv1_CM.so:liblog.so:libsync.so:libnativewindow.so:libGLESv3.so:libdl.so:libGLESv2.so:libmedia.so:libandroid_runtime.so # libmedia.so must be removed after we have fix for lib-dplmedia.so (b/64427765) # libandroid_runtime.so must be removed after we have a fix for qseeproxydaemon (b/64820887) From e0515d6dba5fa50e6319ab65b94232ed88bebd72 Mon Sep 17 00:00:00 2001 From: Alan Stokes Date: Tue, 1 Aug 2017 16:43:02 +0100 Subject: [PATCH 067/129] Reading from logd in WRAP mode is expected to take a long time, don't abort it after 30s. Adds a new CTS test to verify the behaviour. Bug: 64143705 Test: New and existing CTS tests pass. Manual testing with logcat. (cherry picked from commit 64acdf77d6f89a72be9192b35e0fc34242c23e34) Change-Id: Ic2ec131a3aee293ee865c46e62566ddd82ec2507 --- liblog/logd_reader.c | 14 +++- liblog/tests/Android.mk | 3 +- liblog/tests/log_wrap_test.cpp | 121 +++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 liblog/tests/log_wrap_test.cpp diff --git a/liblog/logd_reader.c b/liblog/logd_reader.c index 600f4bb0b..603ba2469 100644 --- a/liblog/logd_reader.c +++ b/liblog/logd_reader.c @@ -590,20 +590,30 @@ static int logdRead(struct android_log_logger_list* logger_list, memset(log_msg, 0, sizeof(*log_msg)); + unsigned int new_alarm = 0; if (logger_list->mode & ANDROID_LOG_NONBLOCK) { + if ((logger_list->mode & ANDROID_LOG_WRAP) && + (logger_list->start.tv_sec || logger_list->start.tv_nsec)) { + /* b/64143705 */ + new_alarm = (ANDROID_LOG_WRAP_DEFAULT_TIMEOUT * 11) / 10 + 10; + logger_list->mode &= ~ANDROID_LOG_WRAP; + } else { + new_alarm = 30; + } + memset(&ignore, 0, sizeof(ignore)); ignore.sa_handler = caught_signal; sigemptyset(&ignore.sa_mask); /* particularily useful if tombstone is reporting for logd */ sigaction(SIGALRM, &ignore, &old_sigaction); - old_alarm = alarm(30); + old_alarm = alarm(new_alarm); } /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */ ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0); e = errno; - if (logger_list->mode & ANDROID_LOG_NONBLOCK) { + if (new_alarm) { if ((ret == 0) || (e == EINTR)) { e = EAGAIN; ret = -1; diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk index 91044ab75..5571ce955 100644 --- a/liblog/tests/Android.mk +++ b/liblog/tests/Android.mk @@ -64,7 +64,8 @@ test_src_files := \ log_radio_test.cpp \ log_read_test.cpp \ log_system_test.cpp \ - log_time_test.cpp + log_time_test.cpp \ + log_wrap_test.cpp # Build tests for the device (with .so). Run with: # adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests diff --git a/liblog/tests/log_wrap_test.cpp b/liblog/tests/log_wrap_test.cpp new file mode 100644 index 000000000..ebf0b1505 --- /dev/null +++ b/liblog/tests/log_wrap_test.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2013-2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +#include +#include +#include // minimal logging API +#include +#include +#include +#include +#include + +#ifdef __ANDROID__ +static void read_with_wrap() { + android_set_log_transport(LOGGER_LOGD); + + // Read the last line in the log to get a starting timestamp. We're assuming + // the log is not empty. + const int mode = ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK; + struct logger_list* logger_list = + android_logger_list_open(LOG_ID_MAIN, mode, 1000, 0); + + ASSERT_NE(logger_list, nullptr); + + log_msg log_msg; + int ret = android_logger_list_read(logger_list, &log_msg); + android_logger_list_close(logger_list); + ASSERT_GT(ret, 0); + + log_time start(log_msg.entry.sec, log_msg.entry.nsec); + ASSERT_NE(start, log_time()); + + logger_list = + android_logger_list_alloc_time(mode | ANDROID_LOG_WRAP, start, 0); + ASSERT_NE(logger_list, nullptr); + + struct logger* logger = android_logger_open(logger_list, LOG_ID_MAIN); + EXPECT_NE(logger, nullptr); + if (logger) { + android_logger_list_read(logger_list, &log_msg); + } + + android_logger_list_close(logger_list); +} + +static void caught_signal(int /* signum */) { +} +#endif + +// b/64143705 confirm fixed +TEST(liblog, wrap_mode_blocks) { +#ifdef __ANDROID__ + + android::base::Timer timer; + + // The read call is expected to take up to 2 hours in the happy case. + // We only want to make sure it waits for longer than 30s, but we can't + // use an alarm as the implementation uses it. So we run the test in + // a separate process. + pid_t pid = fork(); + + if (pid == 0) { + // child + read_with_wrap(); + _exit(0); + } + + struct sigaction ignore, old_sigaction; + memset(&ignore, 0, sizeof(ignore)); + ignore.sa_handler = caught_signal; + sigemptyset(&ignore.sa_mask); + sigaction(SIGALRM, &ignore, &old_sigaction); + alarm(45); + + bool killed = false; + for (;;) { + siginfo_t info = {}; + // This wait will succeed if the child exits, or fail with EINTR if the + // alarm goes off first - a loose approximation to a timed wait. + int ret = waitid(P_PID, pid, &info, WEXITED); + if (ret >= 0 || errno != EINTR) { + EXPECT_EQ(ret, 0); + if (!killed) { + EXPECT_EQ(info.si_status, 0); + } + break; + } + unsigned int alarm_left = alarm(0); + if (alarm_left > 0) { + alarm(alarm_left); + } else { + kill(pid, SIGTERM); + killed = true; + } + } + + alarm(0); + EXPECT_GT(timer.duration(), std::chrono::seconds(40)); +#else + GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif +} From 15ffc53f6d57a46e3041453865311035a18e047a Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Fri, 25 Aug 2017 12:55:52 -0700 Subject: [PATCH 068/129] init.rc: Lock down access to /proc/net/fib_trie Make /proc/net/fib_trie only readable to root. Bug: 31269937 Test: Device boots, file has appropriate permissions. Change-Id: I0d01ce5c043d576344a6732b0b9ff93d62fcaa34 --- rootdir/init.rc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rootdir/init.rc b/rootdir/init.rc index df904031a..2a7333563 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -148,6 +148,9 @@ on init write /proc/sys/net/ipv4/conf/all/accept_redirects 0 write /proc/sys/net/ipv6/conf/all/accept_redirects 0 + # /proc/net/fib_trie leaks interface IP addresses + chmod 0400 /proc/net/fib_trie + # Create cgroup mount points for process groups mkdir /dev/cpuctl mount cgroup none /dev/cpuctl cpu From c47f2992b58bfcd1f5d75cd25dc8172eb4fb5cc9 Mon Sep 17 00:00:00 2001 From: Robert Benea Date: Mon, 21 Aug 2017 15:18:31 -0700 Subject: [PATCH 069/129] Detect critical preassure When close to oom the system tend to become very thrashy and keeps paging. This change looks at the current working sent and checks it against swap. Test: tested on gobo Bug: 64721547 Change-Id: I93d42def93cbc03a01a54988fd5286ec9f124e36 --- lmkd/lmkd.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index 02a9601f9..08eff0901 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -18,17 +18,18 @@ #include #include +#include #include #include #include #include -#include #include #include #include #include #include #include +#include #include #include @@ -41,6 +42,8 @@ #endif #define MEMCG_SYSFS_PATH "/dev/memcg/" +#define MEMCG_MEMORY_USAGE "/dev/memcg/memory.usage_in_bytes" +#define MEMCG_MEMORYSW_USAGE "/dev/memcg/memory.memsw.usage_in_bytes" #define MEMPRESSURE_WATCH_MEDIUM_LEVEL "medium" #define MEMPRESSURE_WATCH_CRITICAL_LEVEL "critical" #define ZONEINFO_PATH "/proc/zoneinfo" @@ -75,7 +78,9 @@ static int mpevfd[2]; static int medium_oomadj; static int critical_oomadj; -static int debug_process_killing; +static bool debug_process_killing; +static bool enable_pressure_upgrade; +static int64_t upgrade_pressure; /* control socket listen and data */ static int ctrl_lfd; @@ -641,17 +646,58 @@ retry: return 0; } +static int64_t get_memory_usage(const char* path) { + int ret; + int64_t mem_usage; + char buf[32]; + int fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + ALOGE("%s open: errno=%d", path, errno); + return -1; + } + + ret = read_all(fd, buf, sizeof(buf) - 1); + close(fd); + if (ret < 0) { + ALOGE("%s error: errno=%d", path, errno); + return -1; + } + sscanf(buf, "%" SCNd64, &mem_usage); + if (mem_usage == 0) { + ALOGE("No memory!"); + return -1; + } + return mem_usage; +} + static void mp_event_common(bool is_critical) { int ret; unsigned long long evcount; int min_adj_score = is_critical ? critical_oomadj : medium_oomadj; int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX; + int64_t mem_usage, memsw_usage; ret = read(mpevfd[index], &evcount, sizeof(evcount)); if (ret < 0) ALOGE("Error reading memory pressure event fd; errno=%d", errno); + if (enable_pressure_upgrade && !is_critical) { + mem_usage = get_memory_usage(MEMCG_MEMORY_USAGE); + memsw_usage = get_memory_usage(MEMCG_MEMORYSW_USAGE); + if (memsw_usage < 0 || mem_usage < 0) { + find_and_kill_process(min_adj_score, is_critical); + return; + } + + // We are swapping too much, calculate percent for swappinness. + if (((mem_usage * 100) / memsw_usage) < upgrade_pressure) { + ALOGI("Event upgraded to critical."); + min_adj_score = critical_oomadj; + is_critical = true; + } + } + if (find_and_kill_process(min_adj_score, is_critical) == 0) { if (debug_process_killing) { ALOGI("Nothing to kill"); @@ -827,6 +873,8 @@ int main(int argc __unused, char **argv __unused) { medium_oomadj = property_get_int32("ro.lmk.medium", 800); critical_oomadj = property_get_int32("ro.lmk.critical", 0); debug_process_killing = property_get_bool("ro.lmk.debug", false); + enable_pressure_upgrade = property_get_bool("ro.lmk.critical_upgrade", false); + upgrade_pressure = (int64_t)property_get_int32("ro.lmk.upgrade_pressure", 50); mlockall(MCL_FUTURE); sched_setscheduler(0, SCHED_FIFO, ¶m); From a2f1335819191a0ab29aa79d343ddf7376495af3 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Mon, 28 Aug 2017 11:21:31 -0700 Subject: [PATCH 070/129] adbd: don't spin if file sync read fails. Bug: http://b/64508974 Bug: 64709603 (presubmit balking at the line above) Test: mma Change-Id: Ifba6a9dea3138b6d2a62c91cc0532f63986c048a (cherry picked from commit 1d6c01b53d4b40476225f7e074cbd7c4d50dda04) --- adb/file_sync_service.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/adb/file_sync_service.cpp b/adb/file_sync_service.cpp index 2acf661b7..3448ee053 100644 --- a/adb/file_sync_service.cpp +++ b/adb/file_sync_service.cpp @@ -283,25 +283,25 @@ fail: // reading and throwing away ID_DATA packets until the other side notices // that we've reported an error. while (true) { - if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) goto fail; + if (!ReadFdExactly(s, &msg.data, sizeof(msg.data))) break; if (msg.data.id == ID_DONE) { - goto abort; + break; } else if (msg.data.id != ID_DATA) { char id[5]; memcpy(id, &msg.data.id, sizeof(msg.data.id)); id[4] = '\0'; D("handle_send_fail received unexpected id '%s' during failure", id); - goto abort; + break; } if (msg.data.size > buffer.size()) { D("handle_send_fail received oversized packet of length '%u' during failure", msg.data.size); - goto abort; + break; } - if (!ReadFdExactly(s, &buffer[0], msg.data.size)) goto abort; + if (!ReadFdExactly(s, &buffer[0], msg.data.size)) break; } abort: From 55f05d79f9e83757acb72d3d300262f5954a00af Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 28 Aug 2017 14:42:49 +0900 Subject: [PATCH 071/129] Make default namespace for system processes isolated The default namespace for system process now becomes isolated, which means it can load only the libs that are in search.paths and under permitted.paths. /system/framework, /system/app, /system/priv-app, /vendor/app, /data, etc are added to the permitted paths since libart should be able to dlopen odex files under the locations. Following directories become unavailable: /system/lib/vndk /system/lib/vndk-sp Bug: 37013858 Bug: 64888291 Bug: 64950640 Test: 2017 pixel devices builds and boots Test: android.jni.cts.JniStaticTest#test_linker_namespaces passes Change-Id: I2bbe9cc19940c3633c2fb901f9bf8ab813e38c13 --- rootdir/etc/ld.config.vndk.txt | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/rootdir/etc/ld.config.vndk.txt b/rootdir/etc/ld.config.vndk.txt index 063aab923..adffd92e1 100644 --- a/rootdir/etc/ld.config.vndk.txt +++ b/rootdir/etc/ld.config.vndk.txt @@ -23,25 +23,21 @@ additional.namespaces = sphal,vndk,rs ############################################################################### # "default" namespace # -# Framework-side code runs in this namespace. Anything from /vendor partition +# Framework-side code runs in this namespace. Libs from /vendor partition # can't be loaded in this namespace. ############################################################################### -namespace.default.isolated = false +namespace.default.isolated = true +# TODO(b/63553457): remove /vendor/lib from the search path. For now, this is +# required since the classloader namespace for vendor apks should have access +# vendor libraries in the directory. These search paths are copied to the search +# paths of the classloader namespace. namespace.default.search.paths = /system/${LIB}:/vendor/${LIB} -namespace.default.permitted.paths = /system/${LIB}:/vendor/${LIB} +# /vendor/app, /vendor/framework were added since libart should be able to dlopen +# the odex files from the directory. +namespace.default.permitted.paths = /system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/data:/mnt/expand namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}:/data/asan/vendor/${LIB}:/vendor/${LIB} -namespace.default.asan.permitted.paths = /data/asan/system/${LIB}:/system/${LIB}:/data/asan/vendor/${LIB}:/vendor/${LIB} - -# TODO(b/37013858): remove all dependencies to /vendor/lib from system processes -# When this is done, comment out following three lines and remove the three -# lines above -#namespace.default.isolated = true -#namespace.default.search.paths = /system/${LIB} -#namespace.default.permitted.paths = /system/${LIB} -# -#namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB} -#namespace.default.asan.permitted.paths = /data/asan/system/${LIB}:/system/${LIB} +namespace.default.asan.permitted.paths = /data:/system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/mnt/expand ############################################################################### # "sphal" namespace From 9fa61b4df3443e5c0a5e393af85e8e59b686fa14 Mon Sep 17 00:00:00 2001 From: Bowgo Tsai Date: Thu, 31 Aug 2017 06:26:47 +0000 Subject: [PATCH 072/129] Revert "adbd: lessen security constraints when the device is unlocked" This reverts commit f1d3dbc32f18d9b3604da03bc043c1b4cc3f5a35. With the following changes to move /sbin/adbd to /system/bin/adbd, we don't need this workaround anymore. https://android-review.googlesource.com/#/q/topic:move-adbd-to-system+(status:open+OR+status:merged) Bug: 63313955 Bug: 63381692 Bug: 64822208 Test: 'adb root' works in VTS for a non-A/B device (userdebug GSI + user boot.img) Change-Id: Ic1249d6abd7d6e6e7380a661df16d25447853a48 Merged-In: Ic1249d6abd7d6e6e7380a661df16d25447853a48 (cherry picked from commit 0603ec4294bc92449643608ee5f18e172d99fce0) --- adb/Android.mk | 2 +- adb/daemon/main.cpp | 24 +++++++++--------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/adb/Android.mk b/adb/Android.mk index d5b069a88..ece064577 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -350,11 +350,11 @@ LOCAL_CFLAGS := \ -D_GNU_SOURCE \ -Wno-deprecated-declarations \ -LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0) LOCAL_CFLAGS += -DALLOW_ADBD_NO_AUTH=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0) ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1 +LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1 endif LOCAL_MODULE := adbd diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp index 3ecbc44f2..3c2758276 100644 --- a/adb/daemon/main.cpp +++ b/adb/daemon/main.cpp @@ -49,23 +49,17 @@ static const char* root_seclabel = nullptr; -static inline bool is_device_unlocked() { - return "orange" == android::base::GetProperty("ro.boot.verifiedbootstate", ""); -} - static void drop_capabilities_bounding_set_if_needed(struct minijail *j) { - if (ALLOW_ADBD_ROOT || is_device_unlocked()) { - if (__android_log_is_debuggable()) { - return; - } +#if defined(ALLOW_ADBD_ROOT) + if (__android_log_is_debuggable()) { + return; } +#endif minijail_capbset_drop(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID)); } static bool should_drop_privileges() { - // "adb root" not allowed, always drop privileges. - if (!ALLOW_ADBD_ROOT && !is_device_unlocked()) return true; - +#if defined(ALLOW_ADBD_ROOT) // The properties that affect `adb root` and `adb unroot` are ro.secure and // ro.debuggable. In this context the names don't make the expected behavior // particularly obvious. @@ -95,6 +89,9 @@ static bool should_drop_privileges() { } return drop; +#else + return true; // "adb root" not allowed, always drop privileges. +#endif // ALLOW_ADBD_ROOT } static void drop_privileges(int server_port) { @@ -161,10 +158,7 @@ int adbd_main(int server_port) { // descriptor will always be open. adbd_cloexec_auth_socket(); - // Respect ro.adb.secure in userdebug/eng builds (ALLOW_ADBD_NO_AUTH), or when the - // device is unlocked. - if ((ALLOW_ADBD_NO_AUTH || is_device_unlocked()) && - !android::base::GetBoolProperty("ro.adb.secure", false)) { + if (ALLOW_ADBD_NO_AUTH && !android::base::GetBoolProperty("ro.adb.secure", false)) { auth_required = false; } From 697eb2da0db5eaaa8b518e6da3b7b6377312825e Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Thu, 31 Aug 2017 22:11:35 +0900 Subject: [PATCH 073/129] libz is back to LLNDK For 2016 pixel devices, where VNDK is not fully enforced, move libz back to LLNDK so that we can pass the CTS without requiring the default namespace to be isolated. If we have libz in vndk-sp directory, test_linker_namespaces fails because /system/lib/vndk-sp/libz.so becomes accessible. In order to make the lib inaccessible, we have to make the default namespace isolated, but this can't be done for 2016 pixel devices where VNDK is not fully enforced. So, we choose to remove /system/lib/vndk-sp/libz.so and keep the single copy at /system/lib. Bug: 65018779 Test: android.jni.cts.JniStaticTest#test_linker_namespaces successful on 2016 pixel devices Change-Id: Ib6b6560b02be69d2015c0afb86acf07c02b30c2f --- rootdir/etc/ld.config.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index 57ec518cb..7f86a950b 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt @@ -64,10 +64,10 @@ namespace.sphal.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB} namespace.sphal.links = default,vndk,rs # WARNING: only NDK libs can be listed here. -namespace.sphal.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libvndksupport.so +namespace.sphal.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libvndksupport.so:libz.so # WARNING: only VNDK-SP libs can be listed here. DO NOT EDIT this line. -namespace.sphal.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so:libz.so +namespace.sphal.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so # Renderscript gets separate namespace namespace.sphal.link.rs.shared_libs = libRS_internal.so @@ -89,8 +89,8 @@ namespace.rs.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB} namespace.rs.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data namespace.rs.links = default,vndk -namespace.rs.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libvndksupport.so:libft2.so -namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so:libz.so +namespace.rs.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libvndksupport.so:libz.so:libft2.so +namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.memory@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidlmemory.so:libhidltransport.so:libion.so:libutils.so:libc++.so ############################################################################### # "vndk" namespace @@ -108,7 +108,7 @@ namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB} # to the default namespace. This is possible since their ABI is stable across # Android releases. namespace.vndk.links = default -namespace.vndk.link.default.shared_libs = android.hidl.memory@1.0-impl.so:libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libvndksupport.so +namespace.vndk.link.default.shared_libs = android.hidl.memory@1.0-impl.so:libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libvndksupport.so:libz.so ############################################################################### # Namespace config for vendor processes. In O, no restriction is enforced for From 367984602abab743630d1fba8e4940f0a69e678b Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Fri, 4 Aug 2017 19:08:06 +0900 Subject: [PATCH 074/129] templatize ld.config.txt Lists of libraries in between the linker namespaces are no longer hard-coded in ld.config.txt, but instead come from Soong. Bug: 37139976 Test: build 2017 pixel device with BOARD_VNDK_VERSION=current m -j Test: the device is bootable, basic functionalities (camera, camcorder, wifi, bt, gps, etc.) work. Change-Id: I8170e6c3f6ee04b16359791d64cc46bd2714a073 --- rootdir/Android.mk | 52 ++++++++++++++++--- .../{ld.config.vndk.txt => ld.config.txt.in} | 13 +++-- 2 files changed, 50 insertions(+), 15 deletions(-) rename rootdir/etc/{ld.config.vndk.txt => ld.config.txt.in} (81%) diff --git a/rootdir/Android.mk b/rootdir/Android.mk index 07902fc3d..3ddf9769e 100644 --- a/rootdir/Android.mk +++ b/rootdir/Android.mk @@ -193,17 +193,52 @@ bcp_dep := # ld.config.txt include $(CLEAR_VARS) +_enforce_vndk_at_runtime := false + +ifdef BOARD_VNDK_VERSION +ifneq ($(BOARD_VNDK_RUNTIME_DISABLE),true) + _enforce_vndk_at_runtime := true +endif +endif + +ifeq ($(_enforce_vndk_at_runtime),true) +LOCAL_MODULE := ld.config.txt +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) +LOCAL_MODULE_STEM := $(LOCAL_MODULE) +include $(BUILD_SYSTEM)/base_rules.mk +vndk_lib_md5 := $(word 1, $(shell echo $(LLNDK_LIBRARIES) $(VNDK_SAMEPROCESS_LIBRARIES) | $(MD5SUM))) +vndk_lib_dep := $(intermediates)/$(vndk_lib_md5).dep +$(vndk_lib_dep): + $(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@ + +llndk_libraries := $(subst $(space),:,$(addsuffix .so,$(LLNDK_LIBRARIES))) + +vndk_sameprocess_libraries := $(subst $(space),:,$(addsuffix .so,$(VNDK_SAMEPROCESS_LIBRARIES))) + +vndk_core_libraries := $(subst $(space),:,$(addsuffix .so,$(VNDK_CORE_LIBRARIES))) + +$(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES := $(llndk_libraries) +$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SAMEPROCESS_LIBRARIES := $(vndk_sameprocess_libraries) +$(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_PRIVATE_LIBRARIES := $(llndk_private_libraries) +$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_CORE_LIBRARIES := $(vndk_core_libraries) +$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/ld.config.txt.in $(vndk_lib_dep) + @echo "Generate: $< -> $@" + @mkdir -p $(dir $@) + $(hide) sed -e 's?%LLNDK_LIBRARIES%?$(PRIVATE_LLNDK_LIBRARIES)?g' $< >$@ + $(hide) sed -i -e 's?%VNDK_SAMEPROCESS_LIBRARIES%?$(PRIVATE_VNDK_SAMEPROCESS_LIBRARIES)?g' $@ + $(hide) sed -i -e 's?%VNDK_CORE_LIBRARIES%?$(PRIVATE_VNDK_CORE_LIBRARIES)?g' $@ + +vndk_lib_md5 := +vndk_lib_dep := +llndk_libraries := +vndk_sameprocess_libraries := +vndk_core_libraries := +else # if _enforce_vndk_at_runtime is not true + LOCAL_MODULE := ld.config.txt ifeq ($(PRODUCT_FULL_TREBLE)|$(SANITIZE_TARGET),true|) -ifdef BOARD_VNDK_VERSION - ifeq ($(BOARD_VNDK_RUNTIME_DISABLE),true) - LOCAL_SRC_FILES := etc/ld.config.txt - else - LOCAL_SRC_FILES := etc/ld.config.vndk.txt - endif -else LOCAL_SRC_FILES := etc/ld.config.txt -endif else LOCAL_SRC_FILES := etc/ld.config.legacy.txt endif @@ -211,3 +246,4 @@ LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) LOCAL_MODULE_STEM := $(LOCAL_MODULE) include $(BUILD_PREBUILT) +endif diff --git a/rootdir/etc/ld.config.vndk.txt b/rootdir/etc/ld.config.txt.in similarity index 81% rename from rootdir/etc/ld.config.vndk.txt rename to rootdir/etc/ld.config.txt.in index adffd92e1..401b0341b 100644 --- a/rootdir/etc/ld.config.vndk.txt +++ b/rootdir/etc/ld.config.txt.in @@ -65,10 +65,10 @@ namespace.sphal.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB} namespace.sphal.links = default,vndk,rs # WARNING: only NDK libs can be listed here. -namespace.sphal.link.default.shared_libs = libEGL.so:libm.so:libandroid_net.so:libvndksupport.so:libc.so:libGLESv1_CM.so:liblog.so:libsync.so:libnativewindow.so:libGLESv3.so:libdl.so:libGLESv2.so +namespace.sphal.link.default.shared_libs = %LLNDK_LIBRARIES% # WARNING: only VNDK-SP libs can be listed here. DO NOT EDIT this line. -namespace.sphal.link.vndk.shared_libs = libhardware.so:libc++.so:libhidlbase.so:libhwbinder.so:libhidltransport.so:libbase.so:libhidlmemory.so:libRS.so:libRSDriver.so:libcutils.so:libion.so:libRSCpuRef.so:android.hardware.graphics.common@1.0.so:android.hardware.graphics.mapper@2.0.so:android.hidl.memory@1.0.so:libbcinfo.so:android.hardware.graphics.allocator@2.0.so:android.hardware.renderscript@1.0.so:libutils.so:libz.so +namespace.sphal.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES% # Renderscript gets separate namespace namespace.sphal.link.rs.shared_libs = libRS_internal.so @@ -90,8 +90,8 @@ namespace.rs.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB} namespace.rs.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data namespace.rs.links = default,vndk -namespace.rs.link.default.shared_libs = libEGL.so:libm.so:libandroid_net.so:libvndksupport.so:libc.so:libGLESv1_CM.so:liblog.so:libsync.so:libnativewindow.so:libGLESv3.so:libdl.so:libGLESv2.so:libmediandk.so:libft2.so -namespace.rs.link.vndk.shared_libs = libhardware.so:libc++.so:libhidlbase.so:libhwbinder.so:libhidltransport.so:libbase.so:libhidlmemory.so:libRS.so:libRSDriver.so:libcutils.so:libion.so:libRSCpuRef.so:android.hardware.graphics.common@1.0.so:android.hardware.graphics.mapper@2.0.so:android.hidl.memory@1.0.so:libbcinfo.so:android.hardware.graphics.allocator@2.0.so:android.hardware.renderscript@1.0.so:libutils.so:libz.so +namespace.rs.link.default.shared_libs = %LLNDK_LIBRARIES% +namespace.rs.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES% ############################################################################### # "vndk" namespace @@ -109,7 +109,7 @@ namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB} # to the default namespace. This is possible since their ABI is stable across # Android releases. namespace.vndk.links = default -namespace.vndk.link.default.shared_libs = libEGL.so:libm.so:libandroid_net.so:libvndksupport.so:libc.so:libGLESv1_CM.so:liblog.so:libsync.so:libnativewindow.so:libGLESv3.so:libdl.so:libGLESv2.so +namespace.vndk.link.default.shared_libs = %LLNDK_LIBRARIES% ############################################################################### # Namespace config for vendor processes. In O, no restriction is enforced for @@ -135,7 +135,7 @@ namespace.default.asan.search.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB} namespace.default.asan.permitted.paths = /data/asan/vendor:/vendor:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.default.links = system -namespace.default.link.system.shared_libs = libEGL.so:libm.so:libandroid_net.so:libvndksupport.so:libc.so:libGLESv1_CM.so:liblog.so:libsync.so:libnativewindow.so:libGLESv3.so:libdl.so:libGLESv2.so:libmedia.so:libandroid_runtime.so +namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES%:libmedia.so:libandroid_runtime.so # libmedia.so must be removed after we have fix for lib-dplmedia.so (b/64427765) # libandroid_runtime.so must be removed after we have a fix for qseeproxydaemon (b/64820887) @@ -150,4 +150,3 @@ namespace.system.permitted.paths = /system/${LIB} namespace.system.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB} namespace.system.asan.permitted.paths = /data/asan/system/${LIB}:/system/${LIB} - From faefa6bd3682a0e8f5de2184cca5960a82a00020 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Thu, 31 Aug 2017 16:42:23 +0900 Subject: [PATCH 075/129] fix: boot fails on ASAN builds with VNDK restriction Fix the bug that caused boot failure on ASAN builds with VNDK restriciton. The major cause is because incorrect (old) ld.config.txt was used when the build is sanitized, which prevented the dynamic linker to find some VNDK libs that only exist in /system/lib/vndk; the old ld.config.txt does not have the directory in its search paths. So, this CL fixes the problem by having the same ld.config.txt for both sanitized and non-sanitizied builds. Furthermore, ld.config.txt is modified so that dependency to libclang_rt* libs are redirected to those in /system/lib directory. This ensures that the sanitizer runtime libs are not dual loaded but are provided for both platform and vendors. Bug: 65217017 Test: SANITIZE_TARGET=integer_overflow SANITIZE_TARGET_DIAG=integer_overflow m on 2017 pixel devices. The build is successful and the device boots to the UI. Change-Id: I0e21e20d9aca340b984968e07d4ce542ae10fd31 --- rootdir/Android.mk | 11 +++++++++++ rootdir/etc/ld.config.txt.in | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/rootdir/Android.mk b/rootdir/Android.mk index 3ddf9769e..e4b2f7bb7 100644 --- a/rootdir/Android.mk +++ b/rootdir/Android.mk @@ -218,22 +218,33 @@ vndk_sameprocess_libraries := $(subst $(space),:,$(addsuffix .so,$(VNDK_SAMEPROC vndk_core_libraries := $(subst $(space),:,$(addsuffix .so,$(VNDK_CORE_LIBRARIES))) +sanitizer_runtime_libraries := $(subst $(space),:,$(addsuffix .so,\ +$(ADDRESS_SANITIZER_RUNTIME_LIBRARY) \ +$(UBSAN_RUNTIME_LIBRARY) \ +$(TSAN_RUNTIME_LIBRARY) \ +$(2ND_ADDRESS_SANITIZER_RUNTIME_LIBRARY) \ +$(2ND_UBSAN_RUNTIME_LIBRARY) \ +$(2ND_TSAN_RUNTIME_LIBRARY))) + $(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES := $(llndk_libraries) $(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SAMEPROCESS_LIBRARIES := $(vndk_sameprocess_libraries) $(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_PRIVATE_LIBRARIES := $(llndk_private_libraries) $(LOCAL_BUILT_MODULE): PRIVATE_VNDK_CORE_LIBRARIES := $(vndk_core_libraries) +$(LOCAL_BUILT_MODULE): PRIVATE_SANITIZER_RUNTIME_LIBRARIES := $(sanitizer_runtime_libraries) $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/ld.config.txt.in $(vndk_lib_dep) @echo "Generate: $< -> $@" @mkdir -p $(dir $@) $(hide) sed -e 's?%LLNDK_LIBRARIES%?$(PRIVATE_LLNDK_LIBRARIES)?g' $< >$@ $(hide) sed -i -e 's?%VNDK_SAMEPROCESS_LIBRARIES%?$(PRIVATE_VNDK_SAMEPROCESS_LIBRARIES)?g' $@ $(hide) sed -i -e 's?%VNDK_CORE_LIBRARIES%?$(PRIVATE_VNDK_CORE_LIBRARIES)?g' $@ + $(hide) sed -i -e 's?%SANITIZER_RUNTIME_LIBRARIES%?$(PRIVATE_SANITIZER_RUNTIME_LIBRARIES)?g' $@ vndk_lib_md5 := vndk_lib_dep := llndk_libraries := vndk_sameprocess_libraries := vndk_core_libraries := +sanitizer_runtime_libraries := else # if _enforce_vndk_at_runtime is not true LOCAL_MODULE := ld.config.txt diff --git a/rootdir/etc/ld.config.txt.in b/rootdir/etc/ld.config.txt.in index 401b0341b..e741a34da 100644 --- a/rootdir/etc/ld.config.txt.in +++ b/rootdir/etc/ld.config.txt.in @@ -65,7 +65,7 @@ namespace.sphal.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB} namespace.sphal.links = default,vndk,rs # WARNING: only NDK libs can be listed here. -namespace.sphal.link.default.shared_libs = %LLNDK_LIBRARIES% +namespace.sphal.link.default.shared_libs = %LLNDK_LIBRARIES%:%SANITIZER_RUNTIME_LIBRARIES% # WARNING: only VNDK-SP libs can be listed here. DO NOT EDIT this line. namespace.sphal.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES% @@ -90,7 +90,7 @@ namespace.rs.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB} namespace.rs.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data namespace.rs.links = default,vndk -namespace.rs.link.default.shared_libs = %LLNDK_LIBRARIES% +namespace.rs.link.default.shared_libs = %LLNDK_LIBRARIES%:%SANITIZER_RUNTIME_LIBRARIES% namespace.rs.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES% ############################################################################### @@ -109,7 +109,7 @@ namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB} # to the default namespace. This is possible since their ABI is stable across # Android releases. namespace.vndk.links = default -namespace.vndk.link.default.shared_libs = %LLNDK_LIBRARIES% +namespace.vndk.link.default.shared_libs = %LLNDK_LIBRARIES%:%SANITIZER_RUNTIME_LIBRARIES% ############################################################################### # Namespace config for vendor processes. In O, no restriction is enforced for From 8f63b6cfcae8c843deb1f7e961ecf913f6603834 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 4 Sep 2017 12:18:40 +0900 Subject: [PATCH 076/129] libcutils_header exports liblog_headers cutils/log.h includes log/log.h. Therefore, libcutils_headers needs to export the liblog_headers so that the clients of libcutils don't have to explicitly include liblog (or liblog_headers). Bug: 37342627 Test: build sdk_gphone_x86 userdebug with BOARD_VNDK_VERSION=current Change-Id: I8875855222b4d073fac4a22bff488c9d082d39df --- libcutils/Android.bp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libcutils/Android.bp b/libcutils/Android.bp index d00ff5f96..0ad714fee 100644 --- a/libcutils/Android.bp +++ b/libcutils/Android.bp @@ -34,6 +34,8 @@ cc_library_headers { vendor_available: true, host_supported: true, export_include_dirs: ["include"], + header_libs: ["liblog_headers"], + export_header_lib_headers: ["liblog_headers"], target: { vendor: { export_include_dirs: ["include_vndk"], From 5e739989972eb71543f57879b769960a9a62f223 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Wed, 6 Sep 2017 01:47:15 +0000 Subject: [PATCH 077/129] Revert "libcutils_header exports liblog_headers" This reverts commit 8f63b6cfcae8c843deb1f7e961ecf913f6603834. Reason for revert: the use of cutils/log.h is discouraged. clients should use log/log.h. aosp/420955 Bug: 37342627 Change-Id: I6605aa89b0ef2b9afd0fdd52c1dee1ee0021debd --- libcutils/Android.bp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libcutils/Android.bp b/libcutils/Android.bp index 0ad714fee..d00ff5f96 100644 --- a/libcutils/Android.bp +++ b/libcutils/Android.bp @@ -34,8 +34,6 @@ cc_library_headers { vendor_available: true, host_supported: true, export_include_dirs: ["include"], - header_libs: ["liblog_headers"], - export_header_lib_headers: ["liblog_headers"], target: { vendor: { export_include_dirs: ["include_vndk"], From 4729da4c8a63ac55b905d56f26ca68af53b9ff2f Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Wed, 6 Sep 2017 13:31:12 +0900 Subject: [PATCH 078/129] libadf is a new member of VNDK The library is used by both platform (e.g. libminui) and vendors (for theor HW composer HAL impl). Bug: 64050301 Test: 2017 pixel devices build Test: libadf.so is in /system/lib[64]/vndk directory Change-Id: I20b8b9728cdc56a7491266070740c3330d4324dc --- adf/libadf/Android.bp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/adf/libadf/Android.bp b/adf/libadf/Android.bp index c276c5331..8eef2eab9 100644 --- a/adf/libadf/Android.bp +++ b/adf/libadf/Android.bp @@ -12,8 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -cc_library_static { +cc_library { name: "libadf", + vendor_available: true, + vndk: { + enabled: true, + }, srcs: ["adf.cpp"], cflags: ["-Werror"], local_include_dirs: ["include"], From e6474b7fa23f2d00c2aa9ea9162231790d9d8a2b Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Wed, 6 Sep 2017 12:21:40 +0900 Subject: [PATCH 079/129] Don't rely on transitively included headers One must explicitly include what it need. time.h for clock_gettime Bug: 37629934 Test: build Merged-In: I992eac637f373b204aa161b0b26f5563e952c27e Change-Id: I992eac637f373b204aa161b0b26f5563e952c27e --- libutils/SystemClock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libutils/SystemClock.cpp b/libutils/SystemClock.cpp index 28fc35145..73ec1be96 100644 --- a/libutils/SystemClock.cpp +++ b/libutils/SystemClock.cpp @@ -23,9 +23,9 @@ #include -#include #include #include +#include #include From 98c0d030c9a1ca7a94ebfe1d8db167973be504d3 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 4 Sep 2017 10:55:09 +0900 Subject: [PATCH 080/129] Hide implementation details of log_time struct In the future, the sizes of tv_sec and tv_nsec (or even the size of log_time struct itself) can change due to the 32-bit overflow expected to happen in the year 2138. In order to hide such implementation details to the clients of liblog, the two macros LOG_TIME_SEC and LOG_TIME_NSEC are introduced. Furthermore, vendors are provided with a simplified version of log_time.h without C++ APIs. In doing so, log_time.h no longer includes time.h. This breaks several modules that implicitly relied on the hidden dependency, which should be fixed. Bug: 37629934 Test: build with BOARD_VNDK_VERSION=current Change-Id: I01b36078c1d8f3f44824be20ae769ba1465b6feb --- liblog/include/log/log_time.h | 10 +++++-- liblog/include_vndk/log/log_time.h | 48 +++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 4 deletions(-) mode change 120000 => 100644 liblog/include_vndk/log/log_time.h diff --git a/liblog/include/log/log_time.h b/liblog/include/log/log_time.h index 3764faf75..309f5d12f 100644 --- a/liblog/include/log/log_time.h +++ b/liblog/include/log/log_time.h @@ -28,6 +28,10 @@ #ifndef __struct_log_time_defined #define __struct_log_time_defined +#define LOG_TIME_SEC(t) ((t)->tv_sec) +/* next power of two after NS_PER_SEC */ +#define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2)) + #ifdef __cplusplus /* @@ -167,15 +171,15 @@ struct log_time { #endif } __attribute__((__packed__)); -#else +#else /* __cplusplus */ typedef struct log_time { uint32_t tv_sec; uint32_t tv_nsec; } __attribute__((__packed__)) log_time; -#endif +#endif /* __cplusplus */ -#endif +#endif /* __struct_log_time_defined */ #endif /* _LIBS_LOG_LOG_TIME_H */ diff --git a/liblog/include_vndk/log/log_time.h b/liblog/include_vndk/log/log_time.h deleted file mode 120000 index abfe439ae..000000000 --- a/liblog/include_vndk/log/log_time.h +++ /dev/null @@ -1 +0,0 @@ -../../include/log/log_time.h \ No newline at end of file diff --git a/liblog/include_vndk/log/log_time.h b/liblog/include_vndk/log/log_time.h new file mode 100644 index 000000000..5a09959a7 --- /dev/null +++ b/liblog/include_vndk/log/log_time.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2005-2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _LIBS_LOG_LOG_TIME_H +#define _LIBS_LOG_LOG_TIME_H + +#include + +/* struct log_time is a wire-format variant of struct timespec */ +#ifndef NS_PER_SEC +#define NS_PER_SEC 1000000000ULL +#endif +#ifndef US_PER_SEC +#define US_PER_SEC 1000000ULL +#endif +#ifndef MS_PER_SEC +#define MS_PER_SEC 1000ULL +#endif + +#ifndef __struct_log_time_defined +#define __struct_log_time_defined + +#define LOG_TIME_SEC(t) ((t)->tv_sec) +/* next power of two after NS_PER_SEC */ +#define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2)) + +typedef struct log_time { + uint32_t tv_sec; + uint32_t tv_nsec; +} __attribute__((__packed__)) log_time; + +#endif + +#endif /* _LIBS_LOG_LOG_TIME_H */ From 26335f89b1b25fd386adbc89edfcc600191b9e07 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Tue, 22 Aug 2017 10:25:18 +0900 Subject: [PATCH 081/129] add llndk|vndksp.libraries.txt to vndk_package List of llndk and vndk-sp libraries are written in the txt file so that they can be available at run-time. The information is used by libnativeloader to configure the classloader-namespace specially for vendor apks. Bug: 64882323 Test: build 2017 pixel devices. check that the two files exist on /system/etc. Change-Id: Ifbe339a5862f6ef57a8213a14a022765ccf77283 --- rootdir/Android.mk | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/rootdir/Android.mk b/rootdir/Android.mk index 3ddf9769e..6cfbe20d4 100644 --- a/rootdir/Android.mk +++ b/rootdir/Android.mk @@ -247,3 +247,45 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) LOCAL_MODULE_STEM := $(LOCAL_MODULE) include $(BUILD_PREBUILT) endif + +####################################### +# llndk.libraries.txt +include $(CLEAR_VARS) +LOCAL_MODULE := llndk.libraries.txt +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) +LOCAL_MODULE_STEM := $(LOCAL_MODULE) +include $(BUILD_SYSTEM)/base_rules.mk +llndk_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM))) +llndk_dep = $(intermediates)/$(llndk_md5).dep +$(llndk_dep): + $(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@ + +$(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES := $(LLNDK_LIBRARIES) +$(LOCAL_BUILT_MODULE): $(llndk_dep) + @echo "Generate: $@" + @mkdir -p $(dir $@) + $(hide) echo -n > $@ + $(hide) $(foreach lib,$(PRIVATE_LLNDK_LIBRARIES), \ + echo $(lib).so >> $@;) + +####################################### +# vndksp.libraries.txt +include $(CLEAR_VARS) +LOCAL_MODULE := vndksp.libraries.txt +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) +LOCAL_MODULE_STEM := $(LOCAL_MODULE) +include $(BUILD_SYSTEM)/base_rules.mk +vndksp_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM))) +vndksp_dep = $(intermediates)/$(vndksp_md5).dep +$(vndksp_dep): + $(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@ + +$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SAMEPROCESS_LIBRARIES := $(VNDK_SAMEPROCESS_LIBRARIES) +$(LOCAL_BUILT_MODULE): $(vndksp_dep) + @echo "Generate: $@" + @mkdir -p $(dir $@) + $(hide) echo -n > $@ + $(hide) $(foreach lib,$(PRIVATE_VNDK_SAMEPROCESS_LIBRARIES), \ + echo $(lib).so >> $@;) From 47efc676c849e3abf32001d66e2d6eb887e83c48 Mon Sep 17 00:00:00 2001 From: Adam Vartanian Date: Mon, 14 Aug 2017 15:51:29 +0100 Subject: [PATCH 082/129] Fix integer overflow in utf{16,32}_to_utf8_length Without an explicit check, the return value can wrap around and return a value that is far too small to hold the data from the resulting conversion. No CTS test is provided because it would need to allocate at least SSIZE_MAX / 2 bytes of UTF-16 data, which is unreasonable on 64-bit devices. Bug: 37723026 Test: run cts -p android.security Change-Id: I56ba5e31657633b7f33685dd8839d4b3b998e586 --- libutils/Unicode.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/libutils/Unicode.cpp b/libutils/Unicode.cpp index 5fd915524..6cff0f476 100644 --- a/libutils/Unicode.cpp +++ b/libutils/Unicode.cpp @@ -180,7 +180,15 @@ ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len) size_t ret = 0; const char32_t *end = src + src_len; while (src < end) { - ret += utf32_codepoint_utf8_length(*src++); + size_t char_len = utf32_codepoint_utf8_length(*src++); + if (SSIZE_MAX - char_len < ret) { + // If this happens, we would overflow the ssize_t type when + // returning from this function, so we cannot express how + // long this string is in an ssize_t. + android_errorWriteLog(0x534e4554, "37723026"); + return -1; + } + ret += char_len; } return ret; } @@ -440,14 +448,23 @@ ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len) size_t ret = 0; const char16_t* const end = src + src_len; while (src < end) { + size_t char_len; if ((*src & 0xFC00) == 0xD800 && (src + 1) < end && (*(src + 1) & 0xFC00) == 0xDC00) { // surrogate pairs are always 4 bytes. - ret += 4; + char_len = 4; src += 2; } else { - ret += utf32_codepoint_utf8_length((char32_t) *src++); + char_len = utf32_codepoint_utf8_length((char32_t)*src++); } + if (SSIZE_MAX - char_len < ret) { + // If this happens, we would overflow the ssize_t type when + // returning from this function, so we cannot express how + // long this string is in an ssize_t. + android_errorWriteLog(0x534e4554, "37723026"); + return -1; + } + ret += char_len; } return ret; } From c17624db31b52e1a2055bfabf950cf0820bd3661 Mon Sep 17 00:00:00 2001 From: Adam Vartanian Date: Mon, 14 Aug 2017 15:51:29 +0100 Subject: [PATCH 083/129] Fix integer overflow in utf{16,32}_to_utf8_length Without an explicit check, the return value can wrap around and return a value that is far too small to hold the data from the resulting conversion. No SafetyNet logging is included because when included aapt fails to link in lmp-mr1-dev. No CTS test is provided because it would need to allocate at least SSIZE_MAX / 2 bytes of UTF-16 data, which is unreasonable on 64-bit devices. Bug: 37723026 Test: run cts -p android.security Change-Id: Ice276dc3a5b62ad389b2e9b8caf670c76b7e5218 Merged-In: Ie2606b92b9eab1acfe8ce4663b43b81156a4cad7 --- libutils/Unicode.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/libutils/Unicode.cpp b/libutils/Unicode.cpp index f5e28d4cc..dd03c6ba1 100644 --- a/libutils/Unicode.cpp +++ b/libutils/Unicode.cpp @@ -18,6 +18,7 @@ #include #include +#include #ifdef HAVE_WINSOCK # undef nhtol @@ -184,7 +185,14 @@ ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len) size_t ret = 0; const char32_t *end = src + src_len; while (src < end) { - ret += utf32_codepoint_utf8_length(*src++); + size_t char_len = utf32_codepoint_utf8_length(*src++); + if (SSIZE_MAX - char_len < ret) { + // If this happens, we would overflow the ssize_t type when + // returning from this function, so we cannot express how + // long this string is in an ssize_t. + return -1; + } + ret += char_len; } return ret; } @@ -420,14 +428,22 @@ ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len) size_t ret = 0; const char16_t* const end = src + src_len; while (src < end) { + size_t char_len; if ((*src & 0xFC00) == 0xD800 && (src + 1) < end && (*(src + 1) & 0xFC00) == 0xDC00) { // surrogate pairs are always 4 bytes. - ret += 4; + char_len = 4; src += 2; } else { - ret += utf32_codepoint_utf8_length((char32_t) *src++); + char_len = utf32_codepoint_utf8_length((char32_t)*src++); } + if (SSIZE_MAX - char_len < ret) { + // If this happens, we would overflow the ssize_t type when + // returning from this function, so we cannot express how + // long this string is in an ssize_t. + return -1; + } + ret += char_len; } return ret; } From a07f3057d00a1da240099aa77d55aaf83362c489 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Tue, 22 Aug 2017 10:26:10 +0900 Subject: [PATCH 084/129] vendor apk is unbundled For devices where VNDK restrictions are all enforced, vendor apks are recognized as unbundled; since system partition and vendor partition can be updated independently from each other. However, since vendor apks are still bundled in the vendor partition, they are allowed to do more than ordinaly unbundled apks that are downloaded and installed to the data partition. 1) /vendor/lib is allowed. So the path is added to the search_paths and permitted paths of the classloader namespace. 2) LLNDK libs are allowed in addition to the NDK libs. So, LLNDK lib list from llndk.libraries.txt is added to the list from public.libraries.txt. 3) VNDK-SP libs are allowed. To do so, the classloader namespace is linked to the 'vndk' namespace where VNDK-SP libs are searched and loaded from. The list of available VNDK-SP libs is read from vndksp.libraries.txt file. 4) Name of the namespace is changed to 'vendor-classloader-namespace' since the namespace is configured differently from the ordinary 'classloader-namespace'. Bug: 63553457 Test: 2017 pixel devices build and boots to the UI Test: a vendor apk (e.g. TimeService.apk) works. Turn the airplain mode on. Set time. Reboot the device. The time is not reset. Test: 1) set target as 2017 pixel 2) m -j CtsVendorJniTestCases 3) copy the built apk into /vendor/app/CtsVendorJniTestCases 4) reboot / factory reset 5) adb shell am instrument -w android.jni.vendor.cts Change-Id: I447452eb025c0a0fd076b5c9ac081d453dc6074e --- .../include/nativeloader/native_loader.h | 1 + libnativeloader/native_loader.cpp | 78 +++++++++++++++++-- rootdir/etc/ld.config.txt.in | 9 +-- 3 files changed, 76 insertions(+), 12 deletions(-) diff --git a/libnativeloader/include/nativeloader/native_loader.h b/libnativeloader/include/nativeloader/native_loader.h index 99ae3a759..3563fc149 100644 --- a/libnativeloader/include/nativeloader/native_loader.h +++ b/libnativeloader/include/nativeloader/native_loader.h @@ -34,6 +34,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, bool is_shared, + bool is_for_vendor, jstring library_path, jstring permitted_path); diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp index 7ccd7db95..5d160eee7 100644 --- a/libnativeloader/native_loader.cpp +++ b/libnativeloader/native_loader.cpp @@ -82,6 +82,11 @@ static constexpr const char* kPublicNativeLibrariesSystemConfigPathFromRoot = "/etc/public.libraries.txt"; static constexpr const char* kPublicNativeLibrariesVendorConfig = "/vendor/etc/public.libraries.txt"; +static constexpr const char* kLlndkNativeLibrariesSystemConfigPathFromRoot = + "/etc/llndk.libraries.txt"; +static constexpr const char* kVndkspNativeLibrariesSystemConfigPathFromRoot = + "/etc/vndksp.libraries.txt"; + // The device may be configured to have the vendor libraries loaded to a separate namespace. // For historical reasons this namespace was named sphal but effectively it is intended @@ -89,6 +94,11 @@ static constexpr const char* kPublicNativeLibrariesVendorConfig = // vendor and system namespaces. static constexpr const char* kVendorNamespaceName = "sphal"; +static constexpr const char* kVndkNamespaceName = "vndk"; + +static constexpr const char* kClassloaderNamespaceName = "classloader-namespace"; +static constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace"; + // (http://b/27588281) This is a workaround for apps using custom classloaders and calling // System.load() with an absolute path which is outside of the classloader library search path. // This list includes all directories app is allowed to access this way. @@ -108,6 +118,7 @@ class LibraryNamespaces { uint32_t target_sdk_version, jobject class_loader, bool is_shared, + bool is_for_vendor, jstring java_library_path, jstring java_permitted_path, NativeLoaderNamespace* ns, @@ -163,9 +174,39 @@ class LibraryNamespaces { is_native_bridge = NativeBridgeIsPathSupported(library_path.c_str()); } + std::string system_exposed_libraries = system_public_libraries_; + const char* namespace_name = kClassloaderNamespaceName; + android_namespace_t* vndk_ns = nullptr; + if (is_for_vendor && !is_shared) { + LOG_FATAL_IF(is_native_bridge, "Unbundled vendor apk must not use translated architecture"); + + // For vendor apks, give access to the vendor lib even though + // they are treated as unbundled; the libs and apks are still bundled + // together in the vendor partition. +#if defined(__LP64__) + std::string vendor_lib_path = "/vendor/lib64"; +#else + std::string vendor_lib_path = "/vendor/lib"; +#endif + library_path = library_path + ":" + vendor_lib_path.c_str(); + permitted_path = permitted_path + ":" + vendor_lib_path.c_str(); + + // Also give access to LLNDK libraries since they are available to vendors + system_exposed_libraries = system_exposed_libraries + ":" + system_llndk_libraries_.c_str(); + + // Give access to VNDK-SP libraries from the 'vndk' namespace. + vndk_ns = android_get_exported_namespace(kVndkNamespaceName); + LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr, + "Cannot find \"%s\" namespace for vendor apks", kVndkNamespaceName); + + // Different name is useful for debugging + namespace_name = kVendorClassloaderNamespaceName; + ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str()); + } + NativeLoaderNamespace native_loader_ns; if (!is_native_bridge) { - android_namespace_t* ns = android_create_namespace("classloader-namespace", + android_namespace_t* ns = android_create_namespace(namespace_name, nullptr, library_path.c_str(), namespace_type, @@ -181,11 +222,19 @@ class LibraryNamespaces { // which is expected behavior in this case. android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName); - if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) { + if (!android_link_namespaces(ns, nullptr, system_exposed_libraries.c_str())) { *error_msg = dlerror(); return false; } + if (vndk_ns != nullptr && !system_vndksp_libraries_.empty()) { + // vendor apks are allowed to use VNDK-SP libraries. + if (!android_link_namespaces(ns, vndk_ns, system_vndksp_libraries_.c_str())) { + *error_msg = dlerror(); + return false; + } + } + if (!vendor_public_libraries_.empty()) { if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) { *error_msg = dlerror(); @@ -195,7 +244,7 @@ class LibraryNamespaces { native_loader_ns = NativeLoaderNamespace(ns); } else { - native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace", + native_bridge_namespace_t* ns = NativeBridgeCreateNamespace(namespace_name, nullptr, library_path.c_str(), namespace_type, @@ -209,7 +258,7 @@ class LibraryNamespaces { native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace(); - if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) { + if (!NativeBridgeLinkNamespaces(ns, nullptr, system_exposed_libraries.c_str())) { *error_msg = NativeBridgeGetError(); return false; } @@ -259,6 +308,10 @@ class LibraryNamespaces { std::string root_dir = android_root_env != nullptr ? android_root_env : "/system"; std::string public_native_libraries_system_config = root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot; + std::string llndk_native_libraries_system_config = + root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot; + std::string vndksp_native_libraries_system_config = + root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot; std::string error_msg; LOG_ALWAYS_FATAL_IF(!ReadConfig(public_native_libraries_system_config, &sonames, &error_msg), @@ -293,6 +346,14 @@ class LibraryNamespaces { system_public_libraries_ = base::Join(sonames, ':'); + sonames.clear(); + ReadConfig(kLlndkNativeLibrariesSystemConfigPathFromRoot, &sonames); + system_llndk_libraries_ = base::Join(sonames, ':'); + + sonames.clear(); + ReadConfig(kVndkspNativeLibrariesSystemConfigPathFromRoot, &sonames); + system_vndksp_libraries_ = base::Join(sonames, ':'); + sonames.clear(); // This file is optional, quietly ignore if the file does not exist. ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames); @@ -404,6 +465,8 @@ class LibraryNamespaces { std::vector> namespaces_; std::string system_public_libraries_; std::string vendor_public_libraries_; + std::string system_llndk_libraries_; + std::string system_vndksp_libraries_; DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces); }; @@ -430,6 +493,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, bool is_shared, + bool is_for_vendor, jstring library_path, jstring permitted_path) { #if defined(__ANDROID__) @@ -441,6 +505,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, target_sdk_version, class_loader, is_shared, + is_for_vendor, library_path, permitted_path, &ns, @@ -449,7 +514,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env, return env->NewStringUTF(error_msg.c_str()); } #else - UNUSED(env, target_sdk_version, class_loader, is_shared, + UNUSED(env, target_sdk_version, class_loader, is_shared, is_for_vendor, library_path, permitted_path); #endif return nullptr; @@ -478,7 +543,8 @@ void* OpenNativeLibrary(JNIEnv* env, if (!g_namespaces->Create(env, target_sdk_version, class_loader, - false, + false /* is_shared */, + false /* is_for_vendor */, library_path, nullptr, &ns, diff --git a/rootdir/etc/ld.config.txt.in b/rootdir/etc/ld.config.txt.in index 401b0341b..7e23a850f 100644 --- a/rootdir/etc/ld.config.txt.in +++ b/rootdir/etc/ld.config.txt.in @@ -27,16 +27,12 @@ additional.namespaces = sphal,vndk,rs # can't be loaded in this namespace. ############################################################################### namespace.default.isolated = true -# TODO(b/63553457): remove /vendor/lib from the search path. For now, this is -# required since the classloader namespace for vendor apks should have access -# vendor libraries in the directory. These search paths are copied to the search -# paths of the classloader namespace. -namespace.default.search.paths = /system/${LIB}:/vendor/${LIB} +namespace.default.search.paths = /system/${LIB} # /vendor/app, /vendor/framework were added since libart should be able to dlopen # the odex files from the directory. namespace.default.permitted.paths = /system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/data:/mnt/expand -namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}:/data/asan/vendor/${LIB}:/vendor/${LIB} +namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB} namespace.default.asan.permitted.paths = /data:/system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/mnt/expand ############################################################################### @@ -99,6 +95,7 @@ namespace.rs.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES% # This namespace is exclusively for vndk-sp libs. ############################################################################### namespace.vndk.isolated = true +namespace.vndk.visible = true namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl From 8ca02bbeb54bed3057414d12624da5a02fa4d3be Mon Sep 17 00:00:00 2001 From: Daniel Rosenberg Date: Wed, 6 Sep 2017 15:22:54 -0700 Subject: [PATCH 085/129] Add derive_gid flag for mounting sdcardfs Turns on the derive_gid feature for sdcardfs. This was moved under a mount flag in the kernel. Test: If the derive_gid flag is supported, the first mount should succeed. If the flag is not, the second should succeed. Bug: 63245673 Change-Id: If1c1bce13d14120732e420252cb5605d33ce7c40 --- sdcard/sdcard.cpp | 60 +++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp index c342cf811..2bbb9060f 100644 --- a/sdcard/sdcard.cpp +++ b/sdcard/sdcard.cpp @@ -317,17 +317,31 @@ static void run(const char* source_path, const char* label, uid_t uid, LOG(FATAL) << "terminated prematurely"; } -static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path, uid_t fsuid, - gid_t fsgid, bool multi_user, userid_t userid, gid_t gid, mode_t mask) { - std::string opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d", - fsuid, fsgid, multi_user?"multiuser,":"", mask, userid, gid); +static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path, + uid_t fsuid, gid_t fsgid, bool multi_user, userid_t userid, gid_t gid, + mode_t mask, bool derive_gid) { + std::string opts = android::base::StringPrintf( + "fsuid=%d,fsgid=%d,%s%smask=%d,userid=%d,gid=%d", fsuid, fsgid, + multi_user ? "multiuser," : "", derive_gid ? "derive_gid," : "", mask, userid, gid); if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) { - PLOG(ERROR) << "failed to mount sdcardfs filesystem"; - return false; + if (derive_gid) { + PLOG(ERROR) << "trying to mount sdcardfs filesystem without derive_gid"; + /* Maybe this isn't supported on this kernel. Try without. */ + opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d", + fsuid, fsgid, multi_user ? "multiuser," : "", mask, + userid, gid); + if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs", + MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) { + PLOG(ERROR) << "failed to mount sdcardfs filesystem"; + return false; + } + } else { + PLOG(ERROR) << "failed to mount sdcardfs filesystem"; + return false; + } } - return true; } @@ -353,7 +367,8 @@ static bool sdcardfs_setup_bind_remount(const std::string& source_path, const st } static void run_sdcardfs(const std::string& source_path, const std::string& label, uid_t uid, - gid_t gid, userid_t userid, bool multi_user, bool full_write) { + gid_t gid, userid_t userid, bool multi_user, bool full_write, + bool derive_gid) { std::string dest_path_default = "/mnt/runtime/default/" + label; std::string dest_path_read = "/mnt/runtime/read/" + label; std::string dest_path_write = "/mnt/runtime/write/" + label; @@ -363,10 +378,10 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe // Multi-user storage is fully isolated per user, so "other" // permissions are completely masked off. if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid, - AID_SDCARD_RW, 0006) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, - AID_EVERYBODY, full_write ? 0007 : 0027)) { + AID_SDCARD_RW, 0006, derive_gid) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY, + full_write ? 0007 : 0027)) { LOG(FATAL) << "failed to sdcardfs_setup"; } } else { @@ -374,11 +389,11 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe // the Android directories are masked off to a single user // deep inside attr_from_stat(). if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid, - AID_SDCARD_RW, 0006) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, - AID_EVERYBODY, full_write ? 0027 : 0022) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, - AID_EVERYBODY, full_write ? 0007 : 0022)) { + AID_SDCARD_RW, 0006, derive_gid) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, + full_write ? 0027 : 0022) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY, + full_write ? 0007 : 0022)) { LOG(FATAL) << "failed to sdcardfs_setup"; } } @@ -435,7 +450,8 @@ static int usage() { << " -g: specify GID to run as" << " -U: specify user ID that owns device" << " -m: source_path is multi-user" - << " -w: runtime write mount has full write access"; + << " -w: runtime write mount has full write access" + << " -P preserve owners on the lower file system"; return 1; } @@ -447,12 +463,13 @@ int main(int argc, char **argv) { userid_t userid = 0; bool multi_user = false; bool full_write = false; + bool derive_gid = false; int i; struct rlimit rlim; int fs_version; int opt; - while ((opt = getopt(argc, argv, "u:g:U:mw")) != -1) { + while ((opt = getopt(argc, argv, "u:g:U:mwG")) != -1) { switch (opt) { case 'u': uid = strtoul(optarg, NULL, 10); @@ -469,6 +486,9 @@ int main(int argc, char **argv) { case 'w': full_write = true; break; + case 'G': + derive_gid = true; + break; case '?': default: return usage(); @@ -512,7 +532,7 @@ int main(int argc, char **argv) { } if (should_use_sdcardfs()) { - run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write); + run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write, derive_gid); } else { run(source_path, label, uid, gid, userid, multi_user, full_write); } From 17ffcc428076ee98b2eb2d5aafdfb302f788c79a Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Thu, 7 Sep 2017 16:14:07 -0700 Subject: [PATCH 086/129] Define priority for video threads Video threads have soft realtime requirements that must be met in order to maintain reliable frame delivery even when the system is under high load. This CL defines a new priority that can be used by video threads, enabling them to be scheduled appropriately relative to other system threads. Change-Id: Idd57207e30309dfdff24389db0acf107532f9e5a related-to-bug:63898080 --- libsystem/include/system/thread_defs.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libsystem/include/system/thread_defs.h b/libsystem/include/system/thread_defs.h index 377a48ce9..80d11608b 100644 --- a/libsystem/include/system/thread_defs.h +++ b/libsystem/include/system/thread_defs.h @@ -55,6 +55,9 @@ enum { /* ui service treads might want to run at a urgent display (uncommon) */ ANDROID_PRIORITY_URGENT_DISPLAY = HAL_PRIORITY_URGENT_DISPLAY, + /* all normal video threads */ + ANDROID_PRIORITY_VIDEO = -10, + /* all normal audio threads */ ANDROID_PRIORITY_AUDIO = -16, From f0a43dede921178b3048d40c330a8b664e94cca3 Mon Sep 17 00:00:00 2001 From: Adam Vartanian Date: Mon, 14 Aug 2017 15:51:29 +0100 Subject: [PATCH 087/129] Fix integer overflow in utf{16,32}_to_utf8_length Without an explicit check, the return value can wrap around and return a value that is far too small to hold the data from the resulting conversion. No CTS test is provided because it would need to allocate at least SSIZE_MAX / 2 bytes of UTF-16 data, which is unreasonable on 64-bit devices. Bug: 37723026 Test: run cts -p android.security Change-Id: Ie2606b92b9eab1acfe8ce4663b43b81156a4cad7 Merged-In: I56ba5e31657633b7f33685dd8839d4b3b998e586 --- libutils/Unicode.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/libutils/Unicode.cpp b/libutils/Unicode.cpp index 2b5293e74..8ae9ef24d 100644 --- a/libutils/Unicode.cpp +++ b/libutils/Unicode.cpp @@ -18,6 +18,7 @@ #include #include +#include #ifdef HAVE_WINSOCK # undef nhtol @@ -178,7 +179,15 @@ ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len) size_t ret = 0; const char32_t *end = src + src_len; while (src < end) { - ret += utf32_codepoint_utf8_length(*src++); + size_t char_len = utf32_codepoint_utf8_length(*src++); + if (SSIZE_MAX - char_len < ret) { + // If this happens, we would overflow the ssize_t type when + // returning from this function, so we cannot express how + // long this string is in an ssize_t. + android_errorWriteLog(0x534e4554, "37723026"); + return -1; + } + ret += char_len; } return ret; } @@ -414,14 +423,23 @@ ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len) size_t ret = 0; const char16_t* const end = src + src_len; while (src < end) { + size_t char_len; if ((*src & 0xFC00) == 0xD800 && (src + 1) < end && (*(src + 1) & 0xFC00) == 0xDC00) { // surrogate pairs are always 4 bytes. - ret += 4; + char_len = 4; src += 2; } else { - ret += utf32_codepoint_utf8_length((char32_t) *src++); + char_len = utf32_codepoint_utf8_length((char32_t)*src++); } + if (SSIZE_MAX - char_len < ret) { + // If this happens, we would overflow the ssize_t type when + // returning from this function, so we cannot express how + // long this string is in an ssize_t. + android_errorWriteLog(0x534e4554, "37723026"); + return -1; + } + ret += char_len; } return ret; } From 164baebc0173500b4317529b7e942100c45c7191 Mon Sep 17 00:00:00 2001 From: Robert Benea Date: Mon, 11 Sep 2017 16:53:28 -0700 Subject: [PATCH 088/129] Allow ANDROID_LOW_MEMORY_KILLER to coexist with lmkd For Go devices fallback to memcg/memory pressure events for LMK. Go devices will use memcg pressure events while inkernel module is disabled. Bug: 64852905 Test: tested on gobo Change-Id: I267ab00be85e324331f6c91551ba013184de817e --- lmkd/lmkd.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index 08eff0901..e26b2271a 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -70,6 +70,7 @@ enum lmk_cmd { /* default to old in-kernel interface if no memory pressure events */ static int use_inkernel_interface = 1; +static bool has_inkernel_module; /* memory pressure level medium event */ static int mpevfd[2]; @@ -81,6 +82,7 @@ static int critical_oomadj; static bool debug_process_killing; static bool enable_pressure_upgrade; static int64_t upgrade_pressure; +static bool is_go_device; /* control socket listen and data */ static int ctrl_lfd; @@ -332,7 +334,7 @@ static void cmd_target(int ntargets, int *params) { lowmem_targets_size = ntargets; - if (use_inkernel_interface) { + if (has_inkernel_module) { char minfreestr[128]; char killpriostr[128]; @@ -347,9 +349,9 @@ static void cmd_target(int ntargets, int *params) { strlcat(killpriostr, ",", sizeof(killpriostr)); } - snprintf(val, sizeof(val), "%d", lowmem_minfree[i]); + snprintf(val, sizeof(val), "%d", use_inkernel_interface ? lowmem_minfree[i] : 0); strlcat(minfreestr, val, sizeof(minfreestr)); - snprintf(val, sizeof(val), "%d", lowmem_adj[i]); + snprintf(val, sizeof(val), "%d", use_inkernel_interface ? lowmem_adj[i] : 0); strlcat(killpriostr, val, sizeof(killpriostr)); } @@ -821,7 +823,8 @@ static int init(void) { } maxevents++; - use_inkernel_interface = !access(INKERNEL_MINFREE_PATH, W_OK); + has_inkernel_module = !access(INKERNEL_MINFREE_PATH, W_OK); + use_inkernel_interface = has_inkernel_module && !is_go_device; if (use_inkernel_interface) { ALOGI("Using in-kernel low memory killer interface"); @@ -875,6 +878,7 @@ int main(int argc __unused, char **argv __unused) { debug_process_killing = property_get_bool("ro.lmk.debug", false); enable_pressure_upgrade = property_get_bool("ro.lmk.critical_upgrade", false); upgrade_pressure = (int64_t)property_get_int32("ro.lmk.upgrade_pressure", 50); + is_go_device = property_get_bool("ro.config.low_ram", false); mlockall(MCL_FUTURE); sched_setscheduler(0, SCHED_FIFO, ¶m); From ea2e67526d496413f0013253e586e7fad1f9cb93 Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Tue, 12 Sep 2017 14:09:06 -0700 Subject: [PATCH 089/129] bootstat: Log the ro.boot.bootreason property through the new platform_reason Tron field. Bug: 63584589 Test: none Change-Id: I369e6977c77619513eb7ce7637c1e3112e5a4b13 (cherry picked from commit 51e91f5e0b4b0d1b75dc93fa2efee85c66f6f8c0) --- bootstat/bootstat.cpp | 7 ++++++- libmetricslogger/Android.bp | 9 ++++++--- .../include/metricslogger/metrics_logger.h | 12 ++++++++++++ libmetricslogger/metrics_logger.cpp | 7 +++++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp index bd611f0b9..f887d4685 100644 --- a/bootstat/bootstat.cpp +++ b/bootstat/bootstat.cpp @@ -358,7 +358,12 @@ void RecordBootComplete() { // Records the boot_reason metric by querying the ro.boot.bootreason system // property. void RecordBootReason() { - int32_t boot_reason = BootReasonStrToEnum(GetProperty("ro.boot.bootreason")); + std::string boot_reason_str = GetProperty("ro.boot.bootreason"); + android::metricslogger::LogMultiAction(android::metricslogger::ACTION_BOOT, + android::metricslogger::FIELD_PLATFORM_REASON, + boot_reason_str); + + int32_t boot_reason = BootReasonStrToEnum(boot_reason_str); BootEventRecordStore boot_event_store; boot_event_store.AddBootEventWithValue("boot_reason", boot_reason); } diff --git a/libmetricslogger/Android.bp b/libmetricslogger/Android.bp index 26a041abd..15d1ff2f1 100644 --- a/libmetricslogger/Android.bp +++ b/libmetricslogger/Android.bp @@ -20,10 +20,13 @@ cc_defaults { "-Wextra", "-Werror", - // 524291 corresponds to sysui_histogram, from - // frameworks/base/core/java/com/android/internal/logging/EventLogTags.logtags - "-DHISTOGRAM_LOG_TAG=524292", + // The following defines map logtag IDs as represented by: + // frameworks/base/core/java/com/android/internal/logging/EventLogTags.logtags + // + // E.g., 524290 corresponds to sysui_count. "-DCOUNT_LOG_TAG=524290", + "-DHISTOGRAM_LOG_TAG=524292", + "-DMULTI_ACTION_LOG_TAG=524292", ], } diff --git a/libmetricslogger/include/metricslogger/metrics_logger.h b/libmetricslogger/include/metricslogger/metrics_logger.h index 36e124d9c..fcabcc941 100644 --- a/libmetricslogger/include/metricslogger/metrics_logger.h +++ b/libmetricslogger/include/metricslogger/metrics_logger.h @@ -28,14 +28,26 @@ void LogHistogram(const std::string& event, int32_t data); // log buffer. void LogCounter(const std::string& name, int32_t val); +// Logs a Tron multi_action with category|category| containing the string +// |value| in the field |field|. +void LogMultiAction(int32_t category, int32_t field, const std::string& value); + // TODO: replace these with the metric_logger.proto definitions enum { LOGBUILDER_CATEGORY = 757, + LOGBUILDER_TYPE = 758, LOGBUILDER_NAME = 799, LOGBUILDER_BUCKET = 801, LOGBUILDER_VALUE = 802, LOGBUILDER_COUNTER = 803, LOGBUILDER_HISTOGRAM = 804, + + ACTION_BOOT = 1092, + FIELD_PLATFORM_REASON = 1093, +}; + +enum { + TYPE_ACTION = 4, }; } // namespace metricslogger diff --git a/libmetricslogger/metrics_logger.cpp b/libmetricslogger/metrics_logger.cpp index 6f65e10f1..a0dcf09cd 100644 --- a/libmetricslogger/metrics_logger.cpp +++ b/libmetricslogger/metrics_logger.cpp @@ -37,5 +37,12 @@ void LogCounter(const std::string& name, int32_t val) { << val << LOG_ID_EVENTS; } +// Mirror com.android.internal.logging.MetricsLogger#action(). +void LogMultiAction(int32_t category, int32_t field, const std::string& value) { + android_log_event_list log(MULTI_ACTION_LOG_TAG); + log << LOGBUILDER_CATEGORY << category << LOGBUILDER_TYPE << TYPE_ACTION + << field << value << LOG_ID_EVENTS; +} + } // namespace metricslogger } // namespace android From 43a7da2c40035e010159f9f7b153232ac7302b17 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Fri, 25 Aug 2017 15:10:48 -0700 Subject: [PATCH 090/129] init: fix signal handling and LOG(FATAL) in child processes Child processes inherit the signal handlers from their parent process. In the case of init, fork()'ed processes, will attempt to reboot the system if they receive a fatal signal). This is not the correct behavior; these processes should terminate due to the provided signal like other processes on the system. This is particularly important as there are multiple LOG(FATAL) calls in service.cpp for failures after fork() but before execv() when a service is started. Note, that pthread_atfork() is not a viable solution since clone() is used in some cases instead of fork() and atfork handlers are not called with clone(). Bug: 65637054 Test: LOG(FATAL) from a child process of init and see that it terminates due to a signal correctly Test: LOG(FATAL) from init proper and see that it reboots to the bootloader Change-Id: I875ebd7a5f6b3f5e3e2c028af3306917c4409db3 --- init/init.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/init/init.cpp b/init/init.cpp index 9671560eb..58f5f2337 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -948,7 +948,7 @@ static void set_usb_controller() { } } -static void install_reboot_signal_handlers() { +static void InstallRebootSignalHandlers() { // Instead of panic'ing the kernel as is the default behavior when init crashes, // we prefer to reboot to bootloader on development builds, as this will prevent // boot looping bad configurations and allow both developers and test farms to easily @@ -956,7 +956,13 @@ static void install_reboot_signal_handlers() { struct sigaction action; memset(&action, 0, sizeof(action)); sigfillset(&action.sa_mask); - action.sa_handler = [](int) { + action.sa_handler = [](int signal) { + // These signal handlers are also caught for processes forked from init, however we do not + // want them to trigger reboot, so we directly call _exit() for children processes here. + if (getpid() != 1) { + _exit(signal); + } + // panic() reboots to bootloader panic(); }; @@ -983,7 +989,7 @@ int main(int argc, char** argv) { } if (REBOOT_BOOTLOADER_ON_PANIC) { - install_reboot_signal_handlers(); + InstallRebootSignalHandlers(); } add_environment("PATH", _PATH_DEFPATH); From 48db85c19ffa7fd54239e405b7d1f9e3c3b2d871 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Mon, 11 Sep 2017 16:08:54 -0700 Subject: [PATCH 091/129] init: fix variable scope issue with ExpandArgs() ExpandArgs() was factored out of Service::Start() to clean up init, however this introduced a bug: the scope of expanded_args ends when ExpandArgs() returns, yet pointers to the c strings contained within those std::strings are returned from the function. These pointers are invalid and have been seen to cause failures on real devices. This change moves the execv() into ExpandArgs() and renames it ExpandArgsAndExecv() to keep the clean separation of Service::Start() but fix the variable scope issue. Bug: 65303004 Test: boot fugu Change-Id: I612128631f5b58d040bffcbc2220593ad16cd450 (cherry picked from commit 5e405cacb1f3ef2265fcc71dbbf6a39c1e7dc1c1) --- init/service.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/init/service.cpp b/init/service.cpp index fe38ee205..f5e54dfda 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -134,17 +134,21 @@ static void SetUpPidNamespace(const std::string& service_name) { } } -static void ExpandArgs(const std::vector& args, std::vector* strs) { +static bool ExpandArgsAndExecve(const std::vector& args) { std::vector expanded_args; + std::vector c_strings; + expanded_args.resize(args.size()); - strs->push_back(const_cast(args[0].c_str())); + c_strings.push_back(const_cast(args[0].data())); for (std::size_t i = 1; i < args.size(); ++i) { if (!expand_props(args[i], &expanded_args[i])) { LOG(FATAL) << args[0] << ": cannot expand '" << args[i] << "'"; } - strs->push_back(const_cast(expanded_args[i].c_str())); + c_strings.push_back(expanded_args[i].data()); } - strs->push_back(nullptr); + c_strings.push_back(nullptr); + + return execve(c_strings[0], c_strings.data(), (char**)ENV) == 0; } ServiceEnvironmentInfo::ServiceEnvironmentInfo() { @@ -799,10 +803,8 @@ bool Service::Start() { // priority. Aborts on failure. SetProcessAttributes(); - std::vector strs; - ExpandArgs(args_, &strs); - if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) { - PLOG(ERROR) << "cannot execve('" << strs[0] << "')"; + if (!ExpandArgsAndExecve(args_)) { + PLOG(ERROR) << "cannot execve('" << args_[0] << "')"; } _exit(127); From 0aeeda00244a31e13d6b9557c94b00ba9457ecb2 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 13 Sep 2017 15:33:39 -0700 Subject: [PATCH 092/129] debuggerd_fallback: print maps. Bug: http://b/63400743 Bug: http://b/65590288 Bug: 64709603 (presubmit balking at the line above) Test: killall -ABRT media.codec Change-Id: I58e47dcd8e99ad7a5945604c27876dd01259e501 Merged-In: I58e47dcd8e99ad7a5945604c27876dd01259e501 (cherry picked from commit fdc95c967099d6cb963195abec9b42b3c64989fd) --- debuggerd/libdebuggerd/tombstone.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp index 011313149..5b6d42014 100644 --- a/debuggerd/libdebuggerd/tombstone.cpp +++ b/debuggerd/libdebuggerd/tombstone.cpp @@ -783,10 +783,22 @@ void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, s dump_abort_message(backtrace.get(), &log, abort_msg_address); dump_registers(&log, ucontext); - // TODO: Dump registers from the ucontext. if (backtrace->Unwind(0, ucontext)) { dump_backtrace_and_stack(backtrace.get(), &log); } else { ALOGE("Unwind failed: pid = %d, tid = %d", pid, tid); } + + // TODO: Make this match the format of dump_all_maps above. + _LOG(&log, logtype::MAPS, "memory map:\n"); + android::base::unique_fd maps_fd(open("/proc/self/maps", O_RDONLY | O_CLOEXEC)); + if (maps_fd == -1) { + _LOG(&log, logtype::MAPS, " failed to open /proc/self/maps: %s", strerror(errno)); + } else { + char buf[256]; + ssize_t rc; + while ((rc = TEMP_FAILURE_RETRY(read(maps_fd.get(), buf, sizeof(buf)))) > 0) { + android::base::WriteFully(tombstone_fd, buf, rc); + } + } } From 28dbcaa23bde48fba22c9b7874f659de2630148c Mon Sep 17 00:00:00 2001 From: Richard Uhler Date: Thu, 14 Sep 2017 14:49:19 +0000 Subject: [PATCH 093/129] Revert "Add derive_gid flag for mounting sdcardfs" This reverts commit 8ca02bbeb54bed3057414d12624da5a02fa4d3be. Causes boot loop on bullhead. Bug: 63245673 Bug: 65660058 Change-Id: Ife5f83ebf56fb956e5015d2797b5b47a515ec171 --- sdcard/sdcard.cpp | 60 ++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp index 2bbb9060f..c342cf811 100644 --- a/sdcard/sdcard.cpp +++ b/sdcard/sdcard.cpp @@ -317,31 +317,17 @@ static void run(const char* source_path, const char* label, uid_t uid, LOG(FATAL) << "terminated prematurely"; } -static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path, - uid_t fsuid, gid_t fsgid, bool multi_user, userid_t userid, gid_t gid, - mode_t mask, bool derive_gid) { - std::string opts = android::base::StringPrintf( - "fsuid=%d,fsgid=%d,%s%smask=%d,userid=%d,gid=%d", fsuid, fsgid, - multi_user ? "multiuser," : "", derive_gid ? "derive_gid," : "", mask, userid, gid); +static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path, uid_t fsuid, + gid_t fsgid, bool multi_user, userid_t userid, gid_t gid, mode_t mask) { + std::string opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d", + fsuid, fsgid, multi_user?"multiuser,":"", mask, userid, gid); if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) { - if (derive_gid) { - PLOG(ERROR) << "trying to mount sdcardfs filesystem without derive_gid"; - /* Maybe this isn't supported on this kernel. Try without. */ - opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d", - fsuid, fsgid, multi_user ? "multiuser," : "", mask, - userid, gid); - if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs", - MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) { - PLOG(ERROR) << "failed to mount sdcardfs filesystem"; - return false; - } - } else { - PLOG(ERROR) << "failed to mount sdcardfs filesystem"; - return false; - } + PLOG(ERROR) << "failed to mount sdcardfs filesystem"; + return false; } + return true; } @@ -367,8 +353,7 @@ static bool sdcardfs_setup_bind_remount(const std::string& source_path, const st } static void run_sdcardfs(const std::string& source_path, const std::string& label, uid_t uid, - gid_t gid, userid_t userid, bool multi_user, bool full_write, - bool derive_gid) { + gid_t gid, userid_t userid, bool multi_user, bool full_write) { std::string dest_path_default = "/mnt/runtime/default/" + label; std::string dest_path_read = "/mnt/runtime/read/" + label; std::string dest_path_write = "/mnt/runtime/write/" + label; @@ -378,10 +363,10 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe // Multi-user storage is fully isolated per user, so "other" // permissions are completely masked off. if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid, - AID_SDCARD_RW, 0006, derive_gid) || - !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027) || - !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY, - full_write ? 0007 : 0027)) { + AID_SDCARD_RW, 0006) + || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027) + || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, + AID_EVERYBODY, full_write ? 0007 : 0027)) { LOG(FATAL) << "failed to sdcardfs_setup"; } } else { @@ -389,11 +374,11 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe // the Android directories are masked off to a single user // deep inside attr_from_stat(). if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid, - AID_SDCARD_RW, 0006, derive_gid) || - !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, - full_write ? 0027 : 0022) || - !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY, - full_write ? 0007 : 0022)) { + AID_SDCARD_RW, 0006) + || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, + AID_EVERYBODY, full_write ? 0027 : 0022) + || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, + AID_EVERYBODY, full_write ? 0007 : 0022)) { LOG(FATAL) << "failed to sdcardfs_setup"; } } @@ -450,8 +435,7 @@ static int usage() { << " -g: specify GID to run as" << " -U: specify user ID that owns device" << " -m: source_path is multi-user" - << " -w: runtime write mount has full write access" - << " -P preserve owners on the lower file system"; + << " -w: runtime write mount has full write access"; return 1; } @@ -463,13 +447,12 @@ int main(int argc, char **argv) { userid_t userid = 0; bool multi_user = false; bool full_write = false; - bool derive_gid = false; int i; struct rlimit rlim; int fs_version; int opt; - while ((opt = getopt(argc, argv, "u:g:U:mwG")) != -1) { + while ((opt = getopt(argc, argv, "u:g:U:mw")) != -1) { switch (opt) { case 'u': uid = strtoul(optarg, NULL, 10); @@ -486,9 +469,6 @@ int main(int argc, char **argv) { case 'w': full_write = true; break; - case 'G': - derive_gid = true; - break; case '?': default: return usage(); @@ -532,7 +512,7 @@ int main(int argc, char **argv) { } if (should_use_sdcardfs()) { - run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write, derive_gid); + run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write); } else { run(source_path, label, uid, gid, userid, multi_user, full_write); } From 6e8e7106754b62f9770c1c3b69ff5a227796178e Mon Sep 17 00:00:00 2001 From: Robert Benea Date: Wed, 13 Sep 2017 15:20:30 -0700 Subject: [PATCH 094/129] Downgrade memory pressure events If the system has enough memory the pressure events are ignored or downgraded from critical to medium. Bug: 65642829 Test: tested on gobo Change-Id: I44e66d2e35508aceee5c1719313db217b80d582e --- lmkd/lmkd.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index e26b2271a..525d7b3cf 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -82,6 +82,7 @@ static int critical_oomadj; static bool debug_process_killing; static bool enable_pressure_upgrade; static int64_t upgrade_pressure; +static int64_t downgrade_pressure; static bool is_go_device; /* control socket listen and data */ @@ -678,28 +679,47 @@ static void mp_event_common(bool is_critical) { int min_adj_score = is_critical ? critical_oomadj : medium_oomadj; int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX; int64_t mem_usage, memsw_usage; + int64_t mem_pressure; ret = read(mpevfd[index], &evcount, sizeof(evcount)); if (ret < 0) ALOGE("Error reading memory pressure event fd; errno=%d", errno); - if (enable_pressure_upgrade && !is_critical) { - mem_usage = get_memory_usage(MEMCG_MEMORY_USAGE); - memsw_usage = get_memory_usage(MEMCG_MEMORYSW_USAGE); - if (memsw_usage < 0 || mem_usage < 0) { - find_and_kill_process(min_adj_score, is_critical); - return; - } + mem_usage = get_memory_usage(MEMCG_MEMORY_USAGE); + memsw_usage = get_memory_usage(MEMCG_MEMORYSW_USAGE); + if (memsw_usage < 0 || mem_usage < 0) { + find_and_kill_process(min_adj_score, is_critical); + return; + } - // We are swapping too much, calculate percent for swappinness. - if (((mem_usage * 100) / memsw_usage) < upgrade_pressure) { + // Calculate percent for swappinness. + mem_pressure = (mem_usage * 100) / memsw_usage; + + if (enable_pressure_upgrade && !is_critical) { + // We are swapping too much. + if (mem_pressure < upgrade_pressure) { ALOGI("Event upgraded to critical."); min_adj_score = critical_oomadj; is_critical = true; } } + // If the pressure is larger than downgrade_pressure lmk will not + // kill any process, since enough memory is available. + if (mem_pressure > downgrade_pressure) { + if (debug_process_killing) { + ALOGI("Ignore %s memory pressure", is_critical ? "critical" : "medium"); + } + return; + } else if (is_critical && mem_pressure > upgrade_pressure) { + if (debug_process_killing) { + ALOGI("Downgrade critical memory pressure"); + } + // Downgrade event to medium, since enough memory available. + is_critical = false; + } + if (find_and_kill_process(min_adj_score, is_critical) == 0) { if (debug_process_killing) { ALOGI("Nothing to kill"); @@ -878,6 +898,7 @@ int main(int argc __unused, char **argv __unused) { debug_process_killing = property_get_bool("ro.lmk.debug", false); enable_pressure_upgrade = property_get_bool("ro.lmk.critical_upgrade", false); upgrade_pressure = (int64_t)property_get_int32("ro.lmk.upgrade_pressure", 50); + downgrade_pressure = (int64_t)property_get_int32("ro.lmk.downgrade_pressure", 60); is_go_device = property_get_bool("ro.config.low_ram", false); mlockall(MCL_FUTURE); From ac8dc7e76fe015786fafaf508620db78ef21cf4e Mon Sep 17 00:00:00 2001 From: Rom Lemarchand Date: Fri, 15 Sep 2017 18:47:50 +0000 Subject: [PATCH 095/129] Revert "Revert "Add derive_gid flag for mounting sdcardfs"" This reverts commit 28dbcaa23bde48fba22c9b7874f659de2630148c. Reason for revert: All kernel prebuilts merged Bug: 65600849 Bug: 65573871 Change-Id: Ib3cae2908c9e8f2b69d8effe618a6f1ac94f44e2 --- sdcard/sdcard.cpp | 60 +++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp index c342cf811..2bbb9060f 100644 --- a/sdcard/sdcard.cpp +++ b/sdcard/sdcard.cpp @@ -317,17 +317,31 @@ static void run(const char* source_path, const char* label, uid_t uid, LOG(FATAL) << "terminated prematurely"; } -static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path, uid_t fsuid, - gid_t fsgid, bool multi_user, userid_t userid, gid_t gid, mode_t mask) { - std::string opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d", - fsuid, fsgid, multi_user?"multiuser,":"", mask, userid, gid); +static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path, + uid_t fsuid, gid_t fsgid, bool multi_user, userid_t userid, gid_t gid, + mode_t mask, bool derive_gid) { + std::string opts = android::base::StringPrintf( + "fsuid=%d,fsgid=%d,%s%smask=%d,userid=%d,gid=%d", fsuid, fsgid, + multi_user ? "multiuser," : "", derive_gid ? "derive_gid," : "", mask, userid, gid); if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) { - PLOG(ERROR) << "failed to mount sdcardfs filesystem"; - return false; + if (derive_gid) { + PLOG(ERROR) << "trying to mount sdcardfs filesystem without derive_gid"; + /* Maybe this isn't supported on this kernel. Try without. */ + opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d", + fsuid, fsgid, multi_user ? "multiuser," : "", mask, + userid, gid); + if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs", + MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) { + PLOG(ERROR) << "failed to mount sdcardfs filesystem"; + return false; + } + } else { + PLOG(ERROR) << "failed to mount sdcardfs filesystem"; + return false; + } } - return true; } @@ -353,7 +367,8 @@ static bool sdcardfs_setup_bind_remount(const std::string& source_path, const st } static void run_sdcardfs(const std::string& source_path, const std::string& label, uid_t uid, - gid_t gid, userid_t userid, bool multi_user, bool full_write) { + gid_t gid, userid_t userid, bool multi_user, bool full_write, + bool derive_gid) { std::string dest_path_default = "/mnt/runtime/default/" + label; std::string dest_path_read = "/mnt/runtime/read/" + label; std::string dest_path_write = "/mnt/runtime/write/" + label; @@ -363,10 +378,10 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe // Multi-user storage is fully isolated per user, so "other" // permissions are completely masked off. if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid, - AID_SDCARD_RW, 0006) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, - AID_EVERYBODY, full_write ? 0007 : 0027)) { + AID_SDCARD_RW, 0006, derive_gid) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY, + full_write ? 0007 : 0027)) { LOG(FATAL) << "failed to sdcardfs_setup"; } } else { @@ -374,11 +389,11 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe // the Android directories are masked off to a single user // deep inside attr_from_stat(). if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid, - AID_SDCARD_RW, 0006) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, - AID_EVERYBODY, full_write ? 0027 : 0022) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, - AID_EVERYBODY, full_write ? 0007 : 0022)) { + AID_SDCARD_RW, 0006, derive_gid) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, + full_write ? 0027 : 0022) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY, + full_write ? 0007 : 0022)) { LOG(FATAL) << "failed to sdcardfs_setup"; } } @@ -435,7 +450,8 @@ static int usage() { << " -g: specify GID to run as" << " -U: specify user ID that owns device" << " -m: source_path is multi-user" - << " -w: runtime write mount has full write access"; + << " -w: runtime write mount has full write access" + << " -P preserve owners on the lower file system"; return 1; } @@ -447,12 +463,13 @@ int main(int argc, char **argv) { userid_t userid = 0; bool multi_user = false; bool full_write = false; + bool derive_gid = false; int i; struct rlimit rlim; int fs_version; int opt; - while ((opt = getopt(argc, argv, "u:g:U:mw")) != -1) { + while ((opt = getopt(argc, argv, "u:g:U:mwG")) != -1) { switch (opt) { case 'u': uid = strtoul(optarg, NULL, 10); @@ -469,6 +486,9 @@ int main(int argc, char **argv) { case 'w': full_write = true; break; + case 'G': + derive_gid = true; + break; case '?': default: return usage(); @@ -512,7 +532,7 @@ int main(int argc, char **argv) { } if (should_use_sdcardfs()) { - run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write); + run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write, derive_gid); } else { run(source_path, label, uid, gid, userid, multi_user, full_write); } From cbd66d3c8a672ed1f762444e4bfd6cd9b44a924d Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Wed, 13 Sep 2017 14:39:45 -0700 Subject: [PATCH 096/129] init: fix crash when reboot is triggered by a builtin Builtin commands may set the sys.powerctl property, which causes reboot to be immediately processed. Unfortunately, part of the reboot processing involves clearing the action queue, so when this scenario happens, ActionManager::ExecuteOneCommand() can abort due to its state being unexpectedly changed. Longer term, the real fix here is to split init and property service. In this case, the property sets will be sent to property service and the reboot will only be processed once property service responds back to init that the property has been set. Since that will not happen within the action queue, there will be no risk of failure. Short term, this change sets a flag in init to shutdown the device before the next action is run, which defers the shutdown enough to fix the crash, but continues to prevent any further commands from running. Bug: 65374456 Test: force bullhead into the repro case and observe that it no longer repros Merged-In: I89c73dad8d7912a845d694b095cab061b8dcc05e Change-Id: I89c73dad8d7912a845d694b095cab061b8dcc05e (cherry picked from commit 3633a4014a1a315000c3e6dee36b419473ab44b9) --- init/builtins.cpp | 5 +++-- init/init.cpp | 22 +++++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/init/builtins.cpp b/init/builtins.cpp index 56d0ae2c8..9e2efe282 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -262,7 +262,7 @@ static int do_mkdir(const std::vector& args) { "--prompt_and_wipe_data", "--reason=set_policy_failed:"s + args[1]}; reboot_into_recovery(options); - return -1; + return 0; } } return 0; @@ -490,7 +490,8 @@ static int queue_fs_event(int code) { /* Setup a wipe via recovery, and reboot into recovery */ PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery."; const std::vector options = {"--wipe_data", "--reason=fs_mgr_mount_all" }; - ret = reboot_into_recovery(options); + reboot_into_recovery(options); + return 0; /* If reboot worked, there is no return. */ } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) { if (e4crypt_install_keyring()) { diff --git a/init/init.cpp b/init/init.cpp index 58f5f2337..f65bfe08c 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -96,6 +96,8 @@ static std::unique_ptr waiting_for_prop(nullptr); static std::string wait_prop_name; static std::string wait_prop_value; static bool shutting_down; +static std::string shutdown_command; +static bool do_shutdown = false; void DumpState() { ServiceManager::GetInstance().DumpState(); @@ -174,9 +176,16 @@ void property_changed(const std::string& name, const std::string& value) { // In non-thermal-shutdown case, 'shutdown' trigger will be fired to let device specific // commands to be executed. if (name == "sys.powerctl") { - if (HandlePowerctlMessage(value)) { - shutting_down = true; - } + // Despite the above comment, we can't call HandlePowerctlMessage() in this function, + // because it modifies the contents of the action queue, which can cause the action queue + // to get into a bad state if this function is called from a command being executed by the + // action queue. Instead we set this flag and ensure that shutdown happens before the next + // command is run in the main init loop. + // TODO: once property service is removed from init, this will never happen from a builtin, + // but rather from a callback from the property service socket, in which case this hack can + // go away. + shutdown_command = value; + do_shutdown = true; } if (property_triggers_enabled) ActionManager::GetInstance().QueuePropertyChange(name, value); @@ -1175,6 +1184,13 @@ int main(int argc, char** argv) { // By default, sleep until something happens. int epoll_timeout_ms = -1; + if (do_shutdown && !shutting_down) { + do_shutdown = false; + if (HandlePowerctlMessage(shutdown_command)) { + shutting_down = true; + } + } + if (!(waiting_for_prop || sm.IsWaitingForExec())) { am.ExecuteOneCommand(); } From 19e26708c2d8e563b20868d7a651a3485498ddf1 Mon Sep 17 00:00:00 2001 From: Robert Benea Date: Sun, 17 Sep 2017 18:31:35 -0700 Subject: [PATCH 097/129] Simplify lmkd functionality Get min adj score when needed, instead to propagate from caller funct. Bug:65642829 Test: tested on gobo_512 Change-Id: I87f15c5c6206d471002828a24d0462b0abb0d196 --- lmkd/lmkd.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c index 525d7b3cf..5cfa2c887 100644 --- a/lmkd/lmkd.c +++ b/lmkd/lmkd.c @@ -626,9 +626,10 @@ static int kill_one_process(struct proc* procp, int min_score_adj, bool is_criti * Find a process to kill based on the current (possibly estimated) free memory * and cached memory sizes. Returns the size of the killed processes. */ -static int find_and_kill_process(int min_score_adj, bool is_critical) { +static int find_and_kill_process(bool is_critical) { int i; int killed_size = 0; + int min_score_adj = is_critical ? critical_oomadj : medium_oomadj; for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) { struct proc *procp; @@ -676,7 +677,6 @@ static int64_t get_memory_usage(const char* path) { static void mp_event_common(bool is_critical) { int ret; unsigned long long evcount; - int min_adj_score = is_critical ? critical_oomadj : medium_oomadj; int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX; int64_t mem_usage, memsw_usage; int64_t mem_pressure; @@ -689,7 +689,7 @@ static void mp_event_common(bool is_critical) { mem_usage = get_memory_usage(MEMCG_MEMORY_USAGE); memsw_usage = get_memory_usage(MEMCG_MEMORYSW_USAGE); if (memsw_usage < 0 || mem_usage < 0) { - find_and_kill_process(min_adj_score, is_critical); + find_and_kill_process(is_critical); return; } @@ -700,7 +700,6 @@ static void mp_event_common(bool is_critical) { // We are swapping too much. if (mem_pressure < upgrade_pressure) { ALOGI("Event upgraded to critical."); - min_adj_score = critical_oomadj; is_critical = true; } } @@ -720,7 +719,7 @@ static void mp_event_common(bool is_critical) { is_critical = false; } - if (find_and_kill_process(min_adj_score, is_critical) == 0) { + if (find_and_kill_process(is_critical) == 0) { if (debug_process_killing) { ALOGI("Nothing to kill"); } From 9dced1626219d47c75a9d37156ed7baeef8f6403 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Wed, 9 Aug 2017 18:32:09 +0100 Subject: [PATCH 098/129] zip_archive: reject files that don't start with an LFH signature. Bug: 64211847 Test: zip_archive_test (cherry picked from commit c1a56dcab711a7ee238c0af865920ca51b1408a6) Merged-In: I275e7c4da05ceeb20401b560c72294f29ef63642 Change-Id: Ib89f0def696206ff427be27764c158fab88e4b5d --- libziparchive/zip_archive.cc | 16 ++++++++++ libziparchive/zip_archive_test.cc | 49 +++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc index 78de40aed..d0bbd7220 100644 --- a/libziparchive/zip_archive.cc +++ b/libziparchive/zip_archive.cc @@ -441,6 +441,22 @@ static int32_t ParseZipArchive(ZipArchive* archive) { return -1; } } + + uint32_t lfh_start_bytes; + if (!archive->mapped_zip.ReadAtOffset(reinterpret_cast(&lfh_start_bytes), + sizeof(uint32_t), 0)) { + ALOGW("Zip: Unable to read header for entry at offset == 0."); + return -1; + } + + if (lfh_start_bytes != LocalFileHeader::kSignature) { + ALOGW("Zip: Entry at offset zero has invalid LFH signature %" PRIx32, lfh_start_bytes); +#if defined(__ANDROID__) + android_errorWriteLog(0x534e4554, "64211847"); +#endif + return -1; + } + ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries); return 0; diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc index 493a0ce86..3035a5e82 100644 --- a/libziparchive/zip_archive_test.cc +++ b/libziparchive/zip_archive_test.cc @@ -642,6 +642,55 @@ TEST(ziparchive, StreamUncompressedBadCrc) { CloseArchive(handle); } +// A zip file whose local file header at offset zero is corrupted. +// +// --------------- +// cat foo > a.txt +// zip a.zip a.txt +// cat a.zip | xxd -i +// +// Manual changes : +// [2] = 0xff // Corrupt the LFH signature of entry 0. +// [3] = 0xff // Corrupt the LFH signature of entry 0. +static const std::vector kZipFileWithBrokenLfhSignature{ + //[lfh-sig-----------], [lfh contents--------------------------------- + 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, + //-------------------------------------------------------------------- + 0x09, 0x4b, 0xa8, 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, + //-------------------------------] [file-name-----------------], [--- + 0x00, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, + // entry-contents------------------------------------------------------ + 0x54, 0x09, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x51, 0x24, 0x8b, 0x59, + //-------------------------------------------------------------------- + 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, + //-------------------------------------], [cd-record-sig-------], [--- + 0x13, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x0a, 0x50, 0x4b, 0x01, 0x02, 0x1e, + // cd-record----------------------------------------------------------- + 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, 0x09, 0x4b, 0xa8, + //-------------------------------------------------------------------- + 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, + //-------------------------------------------------------------------- + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, + //-] [lfh-file-header-off-], [file-name-----------------], [extra---- + 0x81, 0x00, 0x00, 0x00, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54, + //-------------------------------------------------------------------- + 0x05, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x75, 0x78, 0x0b, 0x00, 0x01, + //-------------------------------------------------------], [eocd-sig- + 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, 0x13, 0x00, 0x00, 0x50, 0x4b, + //-------], [--------------------------------------------------------- + 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x4b, 0x00, + //-------------------------------------------] + 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; + +TEST(ziparchive, BrokenLfhSignature) { + TemporaryFile tmp_file; + ASSERT_NE(-1, tmp_file.fd); + ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0], + kZipFileWithBrokenLfhSignature.size())); + ZipArchiveHandle handle; + ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle)); +} + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); From 5cf1f6a8c89f5c47106266251b5c885d0fe6590e Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Tue, 19 Sep 2017 12:03:47 -0700 Subject: [PATCH 099/129] libmetricslogger: Fix one incorrect (deprecated) logtag and one duplicate logtag. Bug: 65841976 Bug: 65961260 Test: none Change-Id: I6491c3c05e3a56b45d4a77cfa83f8e14eb226e64 (cherry picked from commit 2dcca295a610be5ba0ddaca90e6887649de2413d) --- libmetricslogger/Android.bp | 6 ++---- libmetricslogger/metrics_logger.cpp | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libmetricslogger/Android.bp b/libmetricslogger/Android.bp index 15d1ff2f1..e292403b1 100644 --- a/libmetricslogger/Android.bp +++ b/libmetricslogger/Android.bp @@ -20,12 +20,10 @@ cc_defaults { "-Wextra", "-Werror", - // The following defines map logtag IDs as represented by: + // The following define maps the sysui_multi_action logtag ID as represented by: // frameworks/base/core/java/com/android/internal/logging/EventLogTags.logtags // - // E.g., 524290 corresponds to sysui_count. - "-DCOUNT_LOG_TAG=524290", - "-DHISTOGRAM_LOG_TAG=524292", + // TODO(jhawkins): Query this value at runtime. "-DMULTI_ACTION_LOG_TAG=524292", ], } diff --git a/libmetricslogger/metrics_logger.cpp b/libmetricslogger/metrics_logger.cpp index a0dcf09cd..0ca024d73 100644 --- a/libmetricslogger/metrics_logger.cpp +++ b/libmetricslogger/metrics_logger.cpp @@ -25,14 +25,14 @@ namespace metricslogger { // Mirror com.android.internal.logging.MetricsLogger#histogram(). void LogHistogram(const std::string& event, int32_t data) { - android_log_event_list log(HISTOGRAM_LOG_TAG); + android_log_event_list log(MULTI_ACTION_LOG_TAG); log << LOGBUILDER_CATEGORY << LOGBUILDER_HISTOGRAM << LOGBUILDER_NAME << event << LOGBUILDER_BUCKET << data << LOGBUILDER_VALUE << 1 << LOG_ID_EVENTS; } // Mirror com.android.internal.logging.MetricsLogger#count(). void LogCounter(const std::string& name, int32_t val) { - android_log_event_list log(COUNT_LOG_TAG); + android_log_event_list log(MULTI_ACTION_LOG_TAG); log << LOGBUILDER_CATEGORY << LOGBUILDER_COUNTER << LOGBUILDER_NAME << name << LOGBUILDER_VALUE << val << LOG_ID_EVENTS; } From 5dec8e22c3ecda25ac63baa20d2c23c7a659662c Mon Sep 17 00:00:00 2001 From: Yoshitaka Seto Date: Mon, 31 Jul 2017 17:44:36 +0900 Subject: [PATCH 100/129] Remove pstore related unit tests from CTS Pstore test cases should not belong to CTS. The test cases should be a part of GTS if really required. Test: manual Bug: 66431569 Bug: 63969981 Bug: 63913130 Signed-off-by: Srinavasa Nagaraju Signed-off-by: Yoshitaka Seto Signed-off-by: Mark Salyzyn Tested-by: Srinavasa Nagaraju Change-Id: Icd326403711ad268ce28a3863045fc9b2f211461 --- liblog/tests/Android.mk | 9 ++++++--- liblog/tests/liblog_test.cpp | 31 +++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk index 5571ce955..39b52ac35 100644 --- a/liblog/tests/Android.mk +++ b/liblog/tests/Android.mk @@ -54,7 +54,7 @@ test_c_flags := \ -Werror \ -fno-builtin \ -test_src_files := \ +cts_src_files := \ libc_test.cpp \ liblog_test_default.cpp \ liblog_test_local.cpp \ @@ -67,6 +67,9 @@ test_src_files := \ log_time_test.cpp \ log_wrap_test.cpp +test_src_files := \ + $(cts_src_files) \ + # Build tests for the device (with .so). Run with: # adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests include $(CLEAR_VARS) @@ -82,8 +85,8 @@ cts_executable := CtsLiblogTestCases include $(CLEAR_VARS) LOCAL_MODULE := $(cts_executable) LOCAL_MODULE_TAGS := tests -LOCAL_CFLAGS += $(test_c_flags) -LOCAL_SRC_FILES := $(test_src_files) +LOCAL_CFLAGS += $(test_c_flags) -DNO_PSTORE +LOCAL_SRC_FILES := $(cts_src_files) LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest LOCAL_MULTILIB := both LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32 diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp index 46ec5ef64..56dbf1f2e 100644 --- a/liblog/tests/liblog_test.cpp +++ b/liblog/tests/liblog_test.cpp @@ -116,6 +116,7 @@ static std::string popenToString(std::string command) { return ret; } +#ifndef NO_PSTORE static bool isPmsgActive() { pid_t pid = getpid(); @@ -125,6 +126,7 @@ static bool isPmsgActive() { return std::string::npos != myPidFds.find(" -> /dev/pmsg0"); } +#endif /* NO_PSTORE */ static bool isLogdwActive() { std::string logdwSignature = @@ -189,22 +191,25 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) { EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); #ifdef USING_LOGGER_DEFAULT // Check that we can close and reopen the logger - bool pmsgActiveAfter__android_log_btwrite; bool logdwActiveAfter__android_log_btwrite; if (getuid() == AID_ROOT) { tested__android_log_close = true; - pmsgActiveAfter__android_log_btwrite = isPmsgActive(); - logdwActiveAfter__android_log_btwrite = isLogdwActive(); +#ifndef NO_PSTORE + bool pmsgActiveAfter__android_log_btwrite = isPmsgActive(); EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); +#endif /* NO_PSTORE */ + logdwActiveAfter__android_log_btwrite = isLogdwActive(); EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); } else if (!tested__android_log_close) { fprintf(stderr, "WARNING: can not test __android_log_close()\n"); } __android_log_close(); if (getuid() == AID_ROOT) { +#ifndef NO_PSTORE bool pmsgActiveAfter__android_log_close = isPmsgActive(); - bool logdwActiveAfter__android_log_close = isLogdwActive(); EXPECT_FALSE(pmsgActiveAfter__android_log_close); +#endif /* NO_PSTORE */ + bool logdwActiveAfter__android_log_close = isLogdwActive(); EXPECT_FALSE(logdwActiveAfter__android_log_close); } #endif @@ -213,9 +218,11 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) { EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1))); #ifdef USING_LOGGER_DEFAULT if (getuid() == AID_ROOT) { - pmsgActiveAfter__android_log_btwrite = isPmsgActive(); - logdwActiveAfter__android_log_btwrite = isLogdwActive(); +#ifndef NO_PSTORE + bool pmsgActiveAfter__android_log_btwrite = isPmsgActive(); EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); +#endif /* NO_PSTORE */ + logdwActiveAfter__android_log_btwrite = isLogdwActive(); EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); } #endif @@ -3036,12 +3043,15 @@ TEST(liblog, android_log_write_list_buffer) { #ifdef USING_LOGGER_DEFAULT // Do not retest pmsg functionality #ifdef __ANDROID__ +#ifndef NO_PSTORE static const char __pmsg_file[] = "/data/william-shakespeare/MuchAdoAboutNothing.txt"; +#endif /* NO_PSTORE */ #endif TEST(liblog, __android_log_pmsg_file_write) { #ifdef __ANDROID__ +#ifndef NO_PSTORE __android_log_close(); if (getuid() == AID_ROOT) { tested__android_log_close = true; @@ -3092,12 +3102,16 @@ TEST(liblog, __android_log_pmsg_file_write) { EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write); EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write); } +#else /* NO_PSTORE */ + GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n"; +#endif /* NO_PSTORE */ #else GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } #ifdef __ANDROID__ +#ifndef NO_PSTORE static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename, const char* buf, size_t len, void* arg) { EXPECT_TRUE(NULL == arg); @@ -3118,10 +3132,12 @@ static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename, ? -ENOEXEC : 1; } +#endif /* NO_PSTORE */ #endif TEST(liblog, __android_log_pmsg_file_read) { #ifdef __ANDROID__ +#ifndef NO_PSTORE signaled = 0; __android_log_close(); @@ -3155,6 +3171,9 @@ TEST(liblog, __android_log_pmsg_file_read) { EXPECT_LT(0, ret); EXPECT_EQ(1U, signaled); +#else /* NO_PSTORE */ + GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n"; +#endif /* NO_PSTORE */ #else GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif From 9813914a3b5b7010bcb8d70df2b383aa9839e976 Mon Sep 17 00:00:00 2001 From: Rom Lemarchand Date: Fri, 15 Sep 2017 18:47:50 +0000 Subject: [PATCH 101/129] Revert "Revert "Add derive_gid flag for mounting sdcardfs"" This reverts commit 28dbcaa23bde48fba22c9b7874f659de2630148c. Reason for revert: All kernel prebuilts merged (cherry picked from commit ac8dc7e76fe015786fafaf508620db78ef21cf4e) Bug: 65600849 Bug: 65573871 Test: m Change-Id: Ib3cae2908c9e8f2b69d8effe618a6f1ac94f44e2 --- sdcard/sdcard.cpp | 60 +++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp index 343a90356..77d5a91f1 100644 --- a/sdcard/sdcard.cpp +++ b/sdcard/sdcard.cpp @@ -319,17 +319,31 @@ static void run(const char* source_path, const char* label, uid_t uid, LOG(FATAL) << "terminated prematurely"; } -static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path, uid_t fsuid, - gid_t fsgid, bool multi_user, userid_t userid, gid_t gid, mode_t mask) { - std::string opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d", - fsuid, fsgid, multi_user?"multiuser,":"", mask, userid, gid); +static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path, + uid_t fsuid, gid_t fsgid, bool multi_user, userid_t userid, gid_t gid, + mode_t mask, bool derive_gid) { + std::string opts = android::base::StringPrintf( + "fsuid=%d,fsgid=%d,%s%smask=%d,userid=%d,gid=%d", fsuid, fsgid, + multi_user ? "multiuser," : "", derive_gid ? "derive_gid," : "", mask, userid, gid); if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) { - PLOG(ERROR) << "failed to mount sdcardfs filesystem"; - return false; + if (derive_gid) { + PLOG(ERROR) << "trying to mount sdcardfs filesystem without derive_gid"; + /* Maybe this isn't supported on this kernel. Try without. */ + opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d", + fsuid, fsgid, multi_user ? "multiuser," : "", mask, + userid, gid); + if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs", + MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) { + PLOG(ERROR) << "failed to mount sdcardfs filesystem"; + return false; + } + } else { + PLOG(ERROR) << "failed to mount sdcardfs filesystem"; + return false; + } } - return true; } @@ -355,7 +369,8 @@ static bool sdcardfs_setup_bind_remount(const std::string& source_path, const st } static void run_sdcardfs(const std::string& source_path, const std::string& label, uid_t uid, - gid_t gid, userid_t userid, bool multi_user, bool full_write) { + gid_t gid, userid_t userid, bool multi_user, bool full_write, + bool derive_gid) { std::string dest_path_default = "/mnt/runtime/default/" + label; std::string dest_path_read = "/mnt/runtime/read/" + label; std::string dest_path_write = "/mnt/runtime/write/" + label; @@ -365,10 +380,10 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe // Multi-user storage is fully isolated per user, so "other" // permissions are completely masked off. if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid, - AID_SDCARD_RW, 0006) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, - AID_EVERYBODY, full_write ? 0007 : 0027)) { + AID_SDCARD_RW, 0006, derive_gid) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY, + full_write ? 0007 : 0027)) { LOG(FATAL) << "failed to sdcardfs_setup"; } } else { @@ -376,11 +391,11 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe // the Android directories are masked off to a single user // deep inside attr_from_stat(). if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid, - AID_SDCARD_RW, 0006) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, - AID_EVERYBODY, full_write ? 0027 : 0022) - || !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, - AID_EVERYBODY, full_write ? 0007 : 0022)) { + AID_SDCARD_RW, 0006, derive_gid) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, + full_write ? 0027 : 0022) || + !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY, + full_write ? 0007 : 0022)) { LOG(FATAL) << "failed to sdcardfs_setup"; } } @@ -437,7 +452,8 @@ static int usage() { << " -g: specify GID to run as" << " -U: specify user ID that owns device" << " -m: source_path is multi-user" - << " -w: runtime write mount has full write access"; + << " -w: runtime write mount has full write access" + << " -P preserve owners on the lower file system"; return 1; } @@ -449,12 +465,13 @@ int main(int argc, char **argv) { userid_t userid = 0; bool multi_user = false; bool full_write = false; + bool derive_gid = false; int i; struct rlimit rlim; int fs_version; int opt; - while ((opt = getopt(argc, argv, "u:g:U:mw")) != -1) { + while ((opt = getopt(argc, argv, "u:g:U:mwG")) != -1) { switch (opt) { case 'u': uid = strtoul(optarg, NULL, 10); @@ -471,6 +488,9 @@ int main(int argc, char **argv) { case 'w': full_write = true; break; + case 'G': + derive_gid = true; + break; case '?': default: return usage(); @@ -514,7 +534,7 @@ int main(int argc, char **argv) { } if (should_use_sdcardfs()) { - run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write); + run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write, derive_gid); } else { run(source_path, label, uid, gid, userid, multi_user, full_write); } From dbacd826a100f2c4408446fa912f2bd63e878a8a Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Wed, 9 Aug 2017 18:32:09 +0100 Subject: [PATCH 102/129] zip_archive: reject files that don't start with an LFH signature. Bug: 64211847 Test: zip_archive_test Merged-In: I275e7c4da05ceeb20401b560c72294f29ef63642 Change-Id: I38705f4e9688326a140aa59a1333b0878ed39c14 --- libziparchive/zip_archive.cc | 18 ++++++++++++ libziparchive/zip_archive_test.cc | 49 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc index 8c2c559b1..75f3262ea 100644 --- a/libziparchive/zip_archive.cc +++ b/libziparchive/zip_archive.cc @@ -552,6 +552,8 @@ static int32_t MapCentralDirectory(int fd, const char* debug_file_name, return result; } +static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off); + /* * Parses the Zip archive's Central Directory. Allocates and populates the * hash table. @@ -630,6 +632,22 @@ static int32_t ParseZipArchive(ZipArchive* archive) { return -1; } } + + uint32_t lfh_start_bytes; + if (ReadAtOffset(archive->fd, reinterpret_cast(&lfh_start_bytes), + sizeof(uint32_t), 0) != sizeof(uint32_t)) { + ALOGW("Zip: Unable to read header for entry at offset == 0."); + return -1; + } + + if (lfh_start_bytes != LocalFileHeader::kSignature) { + ALOGW("Zip: Entry at offset zero has invalid LFH signature %" PRIx32, lfh_start_bytes); +#if defined(__ANDROID__) + android_errorWriteLog(0x534e4554, "64211847"); +#endif + return -1; + } + ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries); return 0; diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc index c79986957..89eb496cc 100644 --- a/libziparchive/zip_archive_test.cc +++ b/libziparchive/zip_archive_test.cc @@ -530,6 +530,55 @@ TEST(ziparchive, ExtractToFile) { close(fd); } +// A zip file whose local file header at offset zero is corrupted. +// +// --------------- +// cat foo > a.txt +// zip a.zip a.txt +// cat a.zip | xxd -i +// +// Manual changes : +// [2] = 0xff // Corrupt the LFH signature of entry 0. +// [3] = 0xff // Corrupt the LFH signature of entry 0. +static const std::vector kZipFileWithBrokenLfhSignature{ + //[lfh-sig-----------], [lfh contents--------------------------------- + 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, + //-------------------------------------------------------------------- + 0x09, 0x4b, 0xa8, 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, + //-------------------------------] [file-name-----------------], [--- + 0x00, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, + // entry-contents------------------------------------------------------ + 0x54, 0x09, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x51, 0x24, 0x8b, 0x59, + //-------------------------------------------------------------------- + 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, + //-------------------------------------], [cd-record-sig-------], [--- + 0x13, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x0a, 0x50, 0x4b, 0x01, 0x02, 0x1e, + // cd-record----------------------------------------------------------- + 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, 0x09, 0x4b, 0xa8, + //-------------------------------------------------------------------- + 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, + //-------------------------------------------------------------------- + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, + //-] [lfh-file-header-off-], [file-name-----------------], [extra---- + 0x81, 0x00, 0x00, 0x00, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54, + //-------------------------------------------------------------------- + 0x05, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x75, 0x78, 0x0b, 0x00, 0x01, + //-------------------------------------------------------], [eocd-sig- + 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, 0x13, 0x00, 0x00, 0x50, 0x4b, + //-------], [--------------------------------------------------------- + 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x4b, 0x00, + //-------------------------------------------] + 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; + +TEST(ziparchive, BrokenLfhSignature) { + TemporaryFile tmp_file; + ASSERT_NE(-1, tmp_file.fd); + ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0], + kZipFileWithBrokenLfhSignature.size())); + ZipArchiveHandle handle; + ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle)); +} + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); From 1cc09e749f196774a4e6fa4afedfd4eda623ee67 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Tue, 26 Sep 2017 01:38:22 +0900 Subject: [PATCH 103/129] Fix: make vndk namespace visible for 2016 Pixes The nativeloader tries to find the 'vndk' namespace when there is a vendor apk in the classloader paths. This can happen even for a downloaded app if the app is using a vendor apk via tag. In order to prevent the nativeloader from failing to find the vndk namespace, the namespace is marked as visible. Bug: 66482442 Test: download the app mentioned in the bug, it does not crash. Change-Id: I82e2394eb6eedcb8645e1a5b3735bbfe2735b312 --- rootdir/etc/ld.config.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index 7f86a950b..01336ffde 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt @@ -98,6 +98,7 @@ namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:androi # This namespace is exclusively for vndk-sp libs. ############################################################################### namespace.vndk.isolated = true +namespace.vndk.visible = true namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl From f8025aae822fa45091807611a70bdfc2157f0d47 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Tue, 26 Sep 2017 01:54:57 +0900 Subject: [PATCH 104/129] Remove workaround for VNDK violations lib-dplmedia.so and qseeproxydaemon no longer depend on non-VNDK libraries. Remove the workaround. Bug: 64427765 Bug: 64820887 Test: 2017 pixel devices boots Change-Id: Ib8bcbbb16169dc5c997d6c0dad061c66dcd0ccfe --- rootdir/etc/ld.config.txt.in | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/rootdir/etc/ld.config.txt.in b/rootdir/etc/ld.config.txt.in index af37287da..2c73056a9 100644 --- a/rootdir/etc/ld.config.txt.in +++ b/rootdir/etc/ld.config.txt.in @@ -132,9 +132,7 @@ namespace.default.asan.search.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB} namespace.default.asan.permitted.paths = /data/asan/vendor:/vendor:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp namespace.default.links = system -namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES%:libmedia.so:libandroid_runtime.so -# libmedia.so must be removed after we have fix for lib-dplmedia.so (b/64427765) -# libandroid_runtime.so must be removed after we have a fix for qseeproxydaemon (b/64820887) +namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES% ############################################################################### # "system" namespace From c4a524b1d7a3ea0e2a51ae54f3dc7edb44afea24 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 9 Aug 2017 14:54:56 -0700 Subject: [PATCH 105/129] bootstat: switch from root.root to system.log (cherry picked from commit c3ad75be840c1f4bec5c1638da445122fc3062b1) bootstat does not need root uid and root gid permissions to perform its tasks. It appears that system uid and log gid are adequate and appropriate. Test: manual Bug: 63736262 Bug: 65843095 Change-Id: I094c2cb054e441562fa8717a4d3dc0086fb70a7a --- bootstat/bootstat.rc | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/bootstat/bootstat.rc b/bootstat/bootstat.rc index f4756d59d..d697efba0 100644 --- a/bootstat/bootstat.rc +++ b/bootstat/bootstat.rc @@ -1,7 +1,39 @@ # This file is the LOCAL_INIT_RC file for the bootstat command. on post-fs-data - mkdir /data/misc/bootstat 0700 root root + mkdir /data/misc/bootstat 0700 system log + # To deal with ota transition resulting from a change in DAC from + # root.root to system.log, may be deleted after ota has settled. + chown system log /data/misc/bootstat/absolute_boot_time + chown system log /data/misc/bootstat/boot_complete + chown system log /data/misc/bootstat/boot_complete_no_encryption + chown system log /data/misc/bootstat/boot_reason + chown system log /data/misc/bootstat/bootime.bootloader.1BLE + chown system log /data/misc/bootstat/bootime.bootloader.1BLL + chown system log /data/misc/bootstat/bootime.bootloader.2BLE + chown system log /data/misc/bootstat/bootime.bootloader.2BLL + chown system log /data/misc/bootstat/bootime.bootloader.AVB + chown system log /data/misc/bootstat/bootime.bootloader.KD + chown system log /data/misc/bootstat/bootime.bootloader.KL + chown system log /data/misc/bootstat/bootime.bootloader.ODT + chown system log /data/misc/bootstat/bootime.bootloader.SW + chown system log /data/misc/bootstat/bootime.bootloader.total + chown system log /data/misc/bootstat/build_date + chown system log /data/misc/bootstat/factory_reset + chown system log /data/misc/bootstat/factory_reset_boot_complete + chown system log /data/misc/bootstat/factory_reset_boot_complete_no_encryption + chown system log /data/misc/bootstat/factory_reset_current_time + chown system log /data/misc/bootstat/factory_reset_record_value + chown system log /data/misc/bootstat/last_boot_time_utc + chown system log /data/misc/bootstat/ota_boot_complete + chown system log /data/misc/bootstat/ota_boot_complete_no_encryption + chown system log /data/misc/bootstat/post_decrypt_time_elapsed + chown system log /data/misc/bootstat/ro.boottime.init + chown system log /data/misc/bootstat/ro.boottime.init.cold_boot_wait + chown system log /data/misc/bootstat/ro.boottime.init.selinux + chown system log /data/misc/bootstat/time_since_factory_reset + chown system log /data/misc/bootstat/time_since_last_boot + # end ota transitional support # Record the time at which the user has successfully entered the pin to decrypt # the device, /data is decrypted, and the system is entering the main boot phase. @@ -10,7 +42,7 @@ on post-fs-data # property:init.svc.bootanim=running: The boot animation is running # property:ro.crypto.type=block: FDE device on post-fs-data && property:init.svc.bootanim=running && property:ro.crypto.type=block - exec - root root -- /system/bin/bootstat -r post_decrypt_time_elapsed + exec - system log -- /system/bin/bootstat -r post_decrypt_time_elapsed # sys.logbootcomplete is a signal to enable the bootstat logging mechanism. # This signaling is necessary to prevent logging boot metrics after a runtime @@ -33,13 +65,13 @@ on property:init.svc.zygote=stopping # Record boot complete metrics. on property:sys.boot_completed=1 && property:sys.logbootcomplete=1 # Record boot_complete and related stats (decryption, etc). - exec - root root -- /system/bin/bootstat --record_boot_complete + exec - system log -- /system/bin/bootstat --record_boot_complete # Record the boot reason. - exec - root root -- /system/bin/bootstat --record_boot_reason + exec - system log -- /system/bin/bootstat --record_boot_reason # Record time since factory reset. - exec - root root -- /system/bin/bootstat --record_time_since_factory_reset + exec - system log -- /system/bin/bootstat --record_time_since_factory_reset # Log all boot events. - exec - root root -- /system/bin/bootstat -l + exec - system log -- /system/bin/bootstat -l From 594ce46f642668ac0a78bdd48561cb1939894e55 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 18 Sep 2017 10:27:01 -0700 Subject: [PATCH 106/129] bootstat: bootloader stat files misspelled (cherry picked form commit 25246ddfe6aa0d92c68ad450e206887147f766b4) Test: system/core/bootstat/boot_reason_test.sh Bug: 63736262 Bug: 65843095 Change-Id: I6620c9965f4af8b6a3829f1f4cdcc9b691471a71 --- bootstat/bootstat.rc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/bootstat/bootstat.rc b/bootstat/bootstat.rc index d697efba0..2c48faed4 100644 --- a/bootstat/bootstat.rc +++ b/bootstat/bootstat.rc @@ -8,16 +8,16 @@ on post-fs-data chown system log /data/misc/bootstat/boot_complete chown system log /data/misc/bootstat/boot_complete_no_encryption chown system log /data/misc/bootstat/boot_reason - chown system log /data/misc/bootstat/bootime.bootloader.1BLE - chown system log /data/misc/bootstat/bootime.bootloader.1BLL - chown system log /data/misc/bootstat/bootime.bootloader.2BLE - chown system log /data/misc/bootstat/bootime.bootloader.2BLL - chown system log /data/misc/bootstat/bootime.bootloader.AVB - chown system log /data/misc/bootstat/bootime.bootloader.KD - chown system log /data/misc/bootstat/bootime.bootloader.KL - chown system log /data/misc/bootstat/bootime.bootloader.ODT - chown system log /data/misc/bootstat/bootime.bootloader.SW - chown system log /data/misc/bootstat/bootime.bootloader.total + chown system log /data/misc/bootstat/boottime.bootloader.1BLE + chown system log /data/misc/bootstat/boottime.bootloader.1BLL + chown system log /data/misc/bootstat/boottime.bootloader.2BLE + chown system log /data/misc/bootstat/boottime.bootloader.2BLL + chown system log /data/misc/bootstat/boottime.bootloader.AVB + chown system log /data/misc/bootstat/boottime.bootloader.KD + chown system log /data/misc/bootstat/boottime.bootloader.KL + chown system log /data/misc/bootstat/boottime.bootloader.ODT + chown system log /data/misc/bootstat/boottime.bootloader.SW + chown system log /data/misc/bootstat/boottime.bootloader.total chown system log /data/misc/bootstat/build_date chown system log /data/misc/bootstat/factory_reset chown system log /data/misc/bootstat/factory_reset_boot_complete From bab3354ede1d651a6655457339a6f3d446eb90ab Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 26 Sep 2017 11:54:49 -0700 Subject: [PATCH 107/129] Show the number of VMAs in the tombstone. Tombstones (especially ones with lots of VMAs) are regularly truncated. We can at least show the number of VMAs, though, for anyone interested in knowing whether they got close to the default 64Ki limit. Bug: http://b/66911122 Bug: 64709603 (presubmit balking at the line above) Test: ran crasher, examined tombstone (cherry picked from commit 868d39a82fb2d9830d253409a1c28f0ae1fcac33) Change-Id: I286db66f28f132307d573dbe5164efc969dc6ddc --- debuggerd/libdebuggerd/tombstone.cpp | 12 +++++++----- libbacktrace/include/backtrace/BacktraceMap.h | 2 ++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp index 5b6d42014..b9a0bc786 100644 --- a/debuggerd/libdebuggerd/tombstone.cpp +++ b/debuggerd/libdebuggerd/tombstone.cpp @@ -415,15 +415,17 @@ static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, p } ScopedBacktraceMapIteratorLock lock(map); - _LOG(log, logtype::MAPS, "\n"); - if (!print_fault_address_marker) { - _LOG(log, logtype::MAPS, "memory map:\n"); - } else { - _LOG(log, logtype::MAPS, "memory map: (fault address prefixed with --->)\n"); + _LOG(log, logtype::MAPS, + "\n" + "memory map (%zu entries):\n", + map->size()); + if (print_fault_address_marker) { if (map->begin() != map->end() && addr < map->begin()->start) { _LOG(log, logtype::MAPS, "--->Fault address falls at %s before any mapped regions\n", get_addr_string(addr).c_str()); print_fault_address_marker = false; + } else { + _LOG(log, logtype::MAPS, "(fault address prefixed with --->)\n"); } } diff --git a/libbacktrace/include/backtrace/BacktraceMap.h b/libbacktrace/include/backtrace/BacktraceMap.h index 02a50f738..f7a55b87a 100644 --- a/libbacktrace/include/backtrace/BacktraceMap.h +++ b/libbacktrace/include/backtrace/BacktraceMap.h @@ -89,6 +89,8 @@ public: const_iterator begin() const { return maps_.begin(); } const_iterator end() const { return maps_.end(); } + size_t size() const { return maps_.size(); } + virtual bool Build(); static inline bool IsValid(const backtrace_map_t& map) { From 39103b95c8a3d666974f929647c28d1d9f51b143 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Thu, 17 Aug 2017 13:50:51 -0700 Subject: [PATCH 108/129] adb: fix deadlock in kick_all_transports. Previously, kick_all_transports would deadlock if there were any inaccessible transports, because the transport kick function would call unregister_usb_transport, which attempts to take the already-held transport lock. Fix this by switching the transport lock over to a recursive mutex. Bug: 65419665 Test: manual Change-Id: If61296ff4745e1699f3e216811c1383582627604 (cherry picked from commit 1db71afe97c0c73167bc5d1fffea574b65bfa32c) --- adb/transport.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/adb/transport.cpp b/adb/transport.cpp index 2bbbefdd4..c26252e43 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -49,7 +49,7 @@ static void transport_unref(atransport *t); static auto& transport_list = *new std::list(); static auto& pending_list = *new std::list(); -static std::mutex& transport_lock = *new std::mutex(); +static auto& transport_lock = *new std::recursive_mutex(); const char* const kFeatureShell2 = "shell_v2"; const char* const kFeatureCmd = "cmd"; @@ -298,7 +298,7 @@ static void write_transport_thread(void* _t) { } void kick_transport(atransport* t) { - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); // As kick_transport() can be called from threads without guarantee that t is valid, // check if the transport is in transport_list first. if (std::find(transport_list.begin(), transport_list.end(), t) != transport_list.end()) { @@ -330,7 +330,7 @@ static void device_tracker_remove(device_tracker* tracker) { device_tracker** pnode = &device_tracker_list; device_tracker* node = *pnode; - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); while (node) { if (node == tracker) { *pnode = node->next; @@ -403,7 +403,7 @@ asocket* create_device_tracker(void) { // Check if all of the USB transports are connected. bool iterate_transports(std::function fn) { - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); for (const auto& t : transport_list) { if (!fn(t)) { return false; @@ -507,7 +507,7 @@ static void transport_registration_func(int _fd, unsigned ev, void* data) { adb_close(t->fd); { - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); transport_list.remove(t); } @@ -546,7 +546,7 @@ static void transport_registration_func(int _fd, unsigned ev, void* data) { } { - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); pending_list.remove(t); transport_list.push_front(t); } @@ -573,7 +573,7 @@ void init_transport_registration(void) { void kick_all_transports() { // To avoid only writing part of a packet to a transport after exit, kick all transports. - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); for (auto t : transport_list) { t->Kick(); } @@ -652,7 +652,7 @@ atransport* acquire_one_transport(TransportType type, const char* serial, bool* *error_out = "no devices found"; } - std::unique_lock lock(transport_lock); + std::unique_lock lock(transport_lock); for (const auto& t : transport_list) { if (t->GetConnectionState() == kCsNoPerm) { #if ADB_HOST @@ -927,7 +927,7 @@ static void append_transport(const atransport* t, std::string* result, bool long std::string list_transports(bool long_listing) { std::string result; - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); for (const auto& t : transport_list) { append_transport(t, &result, long_listing); } @@ -935,7 +935,7 @@ std::string list_transports(bool long_listing) { } void close_usb_devices(std::function predicate) { - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); for (auto& t : transport_list) { if (predicate(t)) { t->Kick(); @@ -964,7 +964,7 @@ int register_socket_transport(int s, const char* serial, int port, int local) { return -1; } - std::unique_lock lock(transport_lock); + std::unique_lock lock(transport_lock); for (const auto& transport : pending_list) { if (transport->serial && strcmp(serial, transport->serial) == 0) { VLOG(TRANSPORT) << "socket transport " << transport->serial @@ -996,7 +996,7 @@ int register_socket_transport(int s, const char* serial, int port, int local) { atransport* find_transport(const char* serial) { atransport* result = nullptr; - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); for (auto& t : transport_list) { if (t->serial && strcmp(serial, t->serial) == 0) { result = t; @@ -1008,7 +1008,7 @@ atransport* find_transport(const char* serial) { } void kick_all_tcp_devices() { - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); for (auto& t : transport_list) { if (t->IsTcpDevice()) { // Kicking breaks the read_transport thread of this transport out of any read, then @@ -1037,7 +1037,7 @@ void register_usb_transport(usb_handle* usb, const char* serial, const char* dev } { - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); pending_list.push_front(t); } @@ -1046,7 +1046,7 @@ void register_usb_transport(usb_handle* usb, const char* serial, const char* dev // This should only be used for transports with connection_state == kCsNoPerm. void unregister_usb_transport(usb_handle* usb) { - std::lock_guard lock(transport_lock); + std::lock_guard lock(transport_lock); transport_list.remove_if( [usb](atransport* t) { return t->usb == usb && t->GetConnectionState() == kCsNoPerm; }); } From 1bd8498fc89d14b98e64142e07ad0c35c3bbffed Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 16 Aug 2017 16:57:01 -0700 Subject: [PATCH 109/129] adb: allow selection of a specific transport. Extend device selection to allow selecting a specific transport via monotonically increasing identifier (visible in devices -l). This is useful when using multiple devices (like hikey960...) that have identical bogus serial numbers like 0123456789ABCDEF. Bug: http://b/37043226 Bug: 65419665 Test: adb -t {1, 2, 9999999} {get-serialno, shell, features} Change-Id: I55e5dc5a406a4eeee0012e39b52e8cd232e608a6 (cherry picked from commit b122b175555d80b1d13dc1d864126f531e224d84) --- adb/adb.cpp | 34 ++++--- adb/adb.h | 9 +- adb/adb_client.cpp | 31 +++++-- adb/adb_client.h | 7 +- adb/bugreport.cpp | 13 ++- adb/bugreport.h | 5 +- adb/bugreport_test.cpp | 202 ++++++++++++++++++++--------------------- adb/commandline.cpp | 94 +++++++++++-------- adb/commandline.h | 6 +- adb/services.cpp | 9 +- adb/sockets.cpp | 20 +++- adb/transport.cpp | 48 ++++++++-- adb/transport.h | 22 +++-- 13 files changed, 290 insertions(+), 210 deletions(-) diff --git a/adb/adb.cpp b/adb/adb.cpp index ff7b71f81..8c24bbba3 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -956,8 +956,8 @@ int launch_server(const std::string& socket_spec) { // 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, TransportType type, const char* serial, int reply_fd) -{ +int handle_forward_request(const char* service, TransportType type, const char* serial, + TransportId transport_id, int reply_fd) { if (!strcmp(service, "list-forward")) { // Create the list of forward redirections. std::string listeners = format_listeners(); @@ -1010,7 +1010,8 @@ int handle_forward_request(const char* service, TransportType type, const char* } std::string error_msg; - atransport* transport = acquire_one_transport(type, serial, nullptr, &error_msg); + atransport* transport = + acquire_one_transport(type, serial, transport_id, nullptr, &error_msg); if (!transport) { SendFail(reply_fd, error_msg); return 1; @@ -1068,8 +1069,8 @@ static int SendOkay(int fd, const std::string& s) { return 0; } -int handle_host_request(const char* service, TransportType type, - const char* serial, int reply_fd, asocket* s) { +int handle_host_request(const char* service, TransportType type, const char* serial, + TransportId transport_id, int reply_fd, asocket* s) { if (strcmp(service, "kill") == 0) { fprintf(stderr, "adb server killed by remote request\n"); fflush(stdout); @@ -1089,7 +1090,14 @@ int handle_host_request(const char* service, TransportType type, if (!strncmp(service, "transport", strlen("transport"))) { TransportType type = kTransportAny; - if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { + if (!strncmp(service, "transport-id:", strlen("transport-id:"))) { + service += strlen("transport-id:"); + transport_id = strtoll(service, const_cast(&service), 10); + if (*service != '\0') { + SendFail(reply_fd, "invalid transport id"); + return 1; + } + } else if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { type = kTransportUsb; } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { type = kTransportLocal; @@ -1101,7 +1109,7 @@ int handle_host_request(const char* service, TransportType type, } std::string error; - atransport* t = acquire_one_transport(type, serial, nullptr, &error); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t != nullptr) { s->transport = t; SendOkay(reply_fd); @@ -1144,7 +1152,7 @@ int handle_host_request(const char* service, TransportType type, if (!strcmp(service, "features")) { std::string error; - atransport* t = acquire_one_transport(type, serial, nullptr, &error); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t != nullptr) { SendOkay(reply_fd, FeatureSetToString(t->features())); } else { @@ -1197,7 +1205,7 @@ int handle_host_request(const char* service, TransportType type, // These always report "unknown" rather than the actual error, for scripts. if (!strcmp(service, "get-serialno")) { std::string error; - atransport* t = acquire_one_transport(type, serial, nullptr, &error); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->serial ? t->serial : "unknown"); } else { @@ -1206,7 +1214,7 @@ int handle_host_request(const char* service, TransportType type, } if (!strcmp(service, "get-devpath")) { std::string error; - atransport* t = acquire_one_transport(type, serial, nullptr, &error); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->devpath ? t->devpath : "unknown"); } else { @@ -1215,7 +1223,7 @@ int handle_host_request(const char* service, TransportType type, } if (!strcmp(service, "get-state")) { std::string error; - atransport* t = acquire_one_transport(type, serial, nullptr, &error); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &error); if (t) { return SendOkay(reply_fd, t->connection_state_name()); } else { @@ -1233,7 +1241,7 @@ int handle_host_request(const char* service, TransportType type, if (!strcmp(service, "reconnect")) { std::string response; - atransport* t = acquire_one_transport(type, serial, nullptr, &response, true); + atransport* t = acquire_one_transport(type, serial, transport_id, nullptr, &response, true); if (t != nullptr) { kick_transport(t); response = @@ -1242,7 +1250,7 @@ int handle_host_request(const char* service, TransportType type, return SendOkay(reply_fd, response); } - int ret = handle_forward_request(service, type, serial, reply_fd); + int ret = handle_forward_request(service, type, serial, transport_id, reply_fd); if (ret >= 0) return ret - 1; return -1; diff --git a/adb/adb.h b/adb/adb.h index d6b2b818f..88e13b69b 100644 --- a/adb/adb.h +++ b/adb/adb.h @@ -56,6 +56,7 @@ std::string adb_version(); // Increment this when we want to force users to start a new adb server. #define ADB_SERVER_VERSION 39 +using TransportId = uint64_t; class atransport; struct amessage { @@ -149,7 +150,7 @@ atransport* find_emulator_transport_by_console_port(int console_port); int service_to_fd(const char* name, const atransport* transport); #if ADB_HOST -asocket *host_service_to_socket(const char* name, const char *serial); +asocket* host_service_to_socket(const char* name, const char* serial, TransportId transport_id); #endif #if !ADB_HOST @@ -159,7 +160,8 @@ asocket* create_jdwp_tracker_service_socket(); int create_jdwp_connection_fd(int jdwp_pid); #endif -int handle_forward_request(const char* service, TransportType type, const char* serial, int reply_fd); +int handle_forward_request(const char* service, TransportType type, const char* serial, + TransportId transport_id, int reply_fd); #if !ADB_HOST void framebuffer_service(int fd, void *cookie); @@ -216,7 +218,8 @@ extern int SHELL_EXIT_NOTIFY_FD; #define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2) #endif -int handle_host_request(const char* service, TransportType type, const char* serial, int reply_fd, asocket *s); +int handle_host_request(const char* service, TransportType type, const char* serial, + TransportId transport_id, int reply_fd, asocket* s); void handle_online(atransport *t); void handle_offline(atransport *t); diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp index e533a00eb..849a6e772 100644 --- a/adb/adb_client.cpp +++ b/adb/adb_client.cpp @@ -20,6 +20,7 @@ #include "adb_client.h" #include +#include #include #include #include @@ -46,12 +47,20 @@ static TransportType __adb_transport = kTransportAny; static const char* __adb_serial = NULL; +static TransportId __adb_transport_id = 0; static const char* __adb_server_socket_spec; -void adb_set_transport(TransportType type, const char* serial) { +void adb_set_transport(TransportType type, const char* serial, TransportId transport_id) { __adb_transport = type; __adb_serial = serial; + __adb_transport_id = transport_id; +} + +void adb_get_transport(TransportType* type, const char** serial, TransportId* transport_id) { + if (type) *type = __adb_transport; + if (serial) *serial = __adb_serial; + if (transport_id) *transport_id = __adb_transport_id; } void adb_set_socket_spec(const char* socket_spec) { @@ -63,7 +72,10 @@ void adb_set_socket_spec(const char* socket_spec) { static int switch_socket_transport(int fd, std::string* error) { std::string service; - if (__adb_serial) { + if (__adb_transport_id) { + service += "host:transport-id:"; + service += std::to_string(__adb_transport_id); + } else if (__adb_serial) { service += "host:transport:"; service += __adb_serial; } else { @@ -292,15 +304,18 @@ bool adb_query(const std::string& service, std::string* result, std::string* err return true; } -std::string format_host_command(const char* command, TransportType type, const char* serial) { - if (serial) { - return android::base::StringPrintf("host-serial:%s:%s", serial, command); +std::string format_host_command(const char* command) { + if (__adb_transport_id) { + return android::base::StringPrintf("host-transport-id:%" PRIu64 ":%s", __adb_transport_id, + command); + } else if (__adb_serial) { + return android::base::StringPrintf("host-serial:%s:%s", __adb_serial, command); } const char* prefix = "host"; - if (type == kTransportUsb) { + if (__adb_transport == kTransportUsb) { prefix = "host-usb"; - } else if (type == kTransportLocal) { + } else if (__adb_transport == kTransportLocal) { prefix = "host-local"; } return android::base::StringPrintf("%s:%s", prefix, command); @@ -308,7 +323,7 @@ std::string format_host_command(const char* command, TransportType type, const c bool adb_get_feature_set(FeatureSet* feature_set, std::string* error) { std::string result; - if (adb_query(format_host_command("features", __adb_transport, __adb_serial), &result, error)) { + if (adb_query(format_host_command("features"), &result, error)) { *feature_set = StringToFeatureSet(result); return true; } diff --git a/adb/adb_client.h b/adb/adb_client.h index fabec0050..fca435e38 100644 --- a/adb/adb_client.h +++ b/adb/adb_client.h @@ -40,7 +40,9 @@ bool adb_query(const std::string& service, std::string* _Nonnull result, std::string* _Nonnull error); // Set the preferred transport to connect to. -void adb_set_transport(TransportType type, const char* _Nullable serial); +void adb_set_transport(TransportType type, const char* _Nullable serial, TransportId transport_id); +void adb_get_transport(TransportType* _Nullable type, const char* _Nullable* _Nullable serial, + TransportId* _Nullable transport_id); // Set the socket specification for the adb server. // This function can only be called once, and the argument must live to the end of the process. @@ -57,8 +59,7 @@ int adb_send_emulator_command(int argc, const char* _Nonnull* _Nonnull argv, bool adb_status(int fd, std::string* _Nonnull error); // Create a host command corresponding to selected transport type/serial. -std::string format_host_command(const char* _Nonnull command, TransportType type, - const char* _Nullable serial); +std::string format_host_command(const char* _Nonnull command); // Get the feature set of the current preferred transport. bool adb_get_feature_set(FeatureSet* _Nonnull feature_set, std::string* _Nonnull error); diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp index 372a3b4aa..f63ac08a6 100644 --- a/adb/bugreport.cpp +++ b/adb/bugreport.cpp @@ -195,13 +195,13 @@ class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback); }; -int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, const char** argv) { +int Bugreport::DoIt(int argc, const char** argv) { if (argc > 2) return syntax_error("adb bugreport [PATH]"); // Gets bugreportz version. std::string bugz_stdout, bugz_stderr; DefaultStandardStreamsCallback version_callback(&bugz_stdout, &bugz_stderr); - int status = SendShellCommand(transport_type, serial, "bugreportz -v", false, &version_callback); + int status = SendShellCommand("bugreportz -v", false, &version_callback); std::string bugz_version = android::base::Trim(bugz_stderr); std::string bugz_output = android::base::Trim(bugz_stdout); @@ -214,7 +214,7 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, fprintf(stderr, "Failed to get bugreportz version, which is only available on devices " "running Android 7.0 or later.\nTrying a plain-text bug report instead.\n"); - return SendShellCommand(transport_type, serial, "bugreport", false); + return SendShellCommand("bugreport", false); } // But if user explicitly asked for a zipped bug report, fails instead (otherwise calling @@ -265,7 +265,7 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, bugz_command = "bugreportz"; } BugreportStandardStreamsCallback bugz_callback(dest_dir, dest_file, show_progress, this); - return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback); + return SendShellCommand(bugz_command, false, &bugz_callback); } void Bugreport::UpdateProgress(const std::string& message, int progress_percentage) { @@ -274,10 +274,9 @@ void Bugreport::UpdateProgress(const std::string& message, int progress_percenta LinePrinter::INFO); } -int Bugreport::SendShellCommand(TransportType transport_type, const char* serial, - const std::string& command, bool disable_shell_protocol, +int Bugreport::SendShellCommand(const std::string& command, bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) { - return send_shell_command(transport_type, serial, command, disable_shell_protocol, callback); + return send_shell_command(command, disable_shell_protocol, callback); } bool Bugreport::DoSyncPull(const std::vector& srcs, const char* dst, bool copy_attrs, diff --git a/adb/bugreport.h b/adb/bugreport.h index d9a4468d5..413439b74 100644 --- a/adb/bugreport.h +++ b/adb/bugreport.h @@ -29,14 +29,13 @@ class Bugreport { public: Bugreport() : line_printer_() { } - int DoIt(TransportType transport_type, const char* serial, int argc, const char** argv); + int DoIt(int argc, const char** argv); protected: // Functions below are abstractions of external functions so they can be // mocked on tests. virtual int SendShellCommand( - TransportType transport_type, const char* serial, const std::string& command, - bool disable_shell_protocol, + const std::string& command, bool disable_shell_protocol, StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK); virtual bool DoSyncPull(const std::vector& srcs, const char* dst, bool copy_attrs, diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp index d3787b40a..758f24a06 100644 --- a/adb/bugreport_test.cpp +++ b/adb/bugreport_test.cpp @@ -51,8 +51,8 @@ bool do_sync_pull(const std::vector& srcs, const char* dst, bool co // Empty functions so tests don't need to be linked against commandline.cpp DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr); -int send_shell_command(TransportType transport_type, const char* serial, const std::string& command, - bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) { +int send_shell_command(const std::string& command, bool disable_shell_protocol, + StandardStreamsCallbackInterface* callback) { ADD_FAILURE() << "send_shell_command() should have been mocked"; return -42; } @@ -62,7 +62,7 @@ enum StreamType { kStreamStderr, }; -// gmock black magic to provide a WithArg<4>(WriteOnStdout(output)) matcher +// gmock black magic to provide a WithArg<2>(WriteOnStdout(output)) matcher typedef void OnStandardStreamsCallbackFunction(StandardStreamsCallbackInterface*); class OnStandardStreamsCallbackAction : public ActionInterface { @@ -118,9 +118,8 @@ Action ReturnCallbackDone(int status = -1337) { class BugreportMock : public Bugreport { public: - MOCK_METHOD5(SendShellCommand, - int(TransportType transport_type, const char* serial, const std::string& command, - bool disable_shell_protocol, StandardStreamsCallbackInterface* callback)); + MOCK_METHOD3(SendShellCommand, int(const std::string& command, bool disable_shell_protocol, + StandardStreamsCallbackInterface* callback)); MOCK_METHOD4(DoSyncPull, bool(const std::vector& srcs, const char* dst, bool copy_attrs, const char* name)); MOCK_METHOD2(UpdateProgress, void(const std::string&, int)); @@ -136,10 +135,9 @@ class BugreportTest : public ::testing::Test { } void ExpectBugreportzVersion(const std::string& version) { - EXPECT_CALL(br_, - SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStderr(version.c_str())), - WithArg<4>(ReturnCallbackDone(0)))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStderr(version.c_str())), + WithArg<2>(ReturnCallbackDone(0)))); } void ExpectProgress(int progress_percentage, const std::string& file = "file.zip") { @@ -153,26 +151,26 @@ class BugreportTest : public ::testing::Test { // Tests when called with invalid number of arguments TEST_F(BugreportTest, InvalidNumberArgs) { const char* args[] = {"bugreport", "to", "principal"}; - ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 3, args)); + ASSERT_EQ(1, br_.DoIt(3, args)); } // Tests the 'adb bugreport' option when the device does not support 'bugreportz' - it falls back // to the flat-file format ('bugreport' binary on device) TEST_F(BugreportTest, NoArgumentsPreNDevice) { // clang-format off - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStderr("")), + EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStderr("")), // Write some bogus output on stdout to make sure it's ignored - WithArg<4>(WriteOnStdout("Dude, where is my bugreportz?")), - WithArg<4>(ReturnCallbackDone(0)))); + WithArg<2>(WriteOnStdout("Dude, where is my bugreportz?")), + WithArg<2>(ReturnCallbackDone(0)))); // clang-format on std::string bugreport = "Reported the bug was."; CaptureStdout(); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreport", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout(bugreport)), Return(0))); + EXPECT_CALL(br_, SendShellCommand("bugreport", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout(bugreport)), Return(0))); const char* args[] = {"bugreport"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args)); + ASSERT_EQ(0, br_.DoIt(1, args)); ASSERT_THAT(GetCapturedStdout(), StrEq(bugreport)); } @@ -183,15 +181,15 @@ TEST_F(BugreportTest, NoArgumentsNDevice) { std::string dest_file = android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), true, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args)); + ASSERT_EQ(0, br_.DoIt(1, args)); } // Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.1 - it will @@ -201,47 +199,47 @@ TEST_F(BugreportTest, NoArgumentsPostNDevice) { std::string dest_file = android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR); ExpectProgress(50, "da_bugreport.zip"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), - WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")), - WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip\n")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), + WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")), + WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip\n")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), true, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args)); + ASSERT_EQ(0, br_.DoIt(1, args)); } // Tests 'adb bugreport file.zip' when it succeeds and device does not support progress. TEST_F(BugreportTest, OkNDevice) { ExpectBugreportzVersion("1.0"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), true, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when it succeeds but response was sent in // multiple buffer writers and without progress updates. TEST_F(BugreportTest, OkNDeviceSplitBuffer) { ExpectBugreportzVersion("1.0"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device")), - WithArg<4>(WriteOnStdout("/bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device")), + WithArg<2>(WriteOnStdout("/bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), true, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when it succeeds and displays progress. @@ -252,32 +250,32 @@ TEST_F(BugreportTest, OkProgress) { ExpectProgress(50); ExpectProgress(99); // clang-format off - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit... .WillOnce(DoAll( // Name might change on OK, so make sure the right one is picked. - WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")), + WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")), // Progress line in one write - WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), + WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // Add some bogus lines - WithArg<4>(WriteOnStdout("\nDUDE:SWEET\n\nBLA\n\nBLA\nBLA\n\n")), + WithArg<2>(WriteOnStdout("\nDUDE:SWEET\n\nBLA\n\nBLA\nBLA\n\n")), // Multiple progress lines in one write - WithArg<4>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")), + WithArg<2>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")), // Progress line in multiple writes - WithArg<4>(WriteOnStdout("PROG")), - WithArg<4>(WriteOnStdout("RESS:99")), - WithArg<4>(WriteOnStdout("/100\n")), + WithArg<2>(WriteOnStdout("PROG")), + WithArg<2>(WriteOnStdout("RESS:99")), + WithArg<2>(WriteOnStdout("/100\n")), // Split last message as well, just in case - WithArg<4>(WriteOnStdout("OK:/device/bugreport")), - WithArg<4>(WriteOnStdout(".zip")), - WithArg<4>(ReturnCallbackDone()))); + WithArg<2>(WriteOnStdout("OK:/device/bugreport")), + WithArg<2>(WriteOnStdout(".zip")), + WithArg<2>(ReturnCallbackDone()))); // clang-format on EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), true, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when it succeeds and displays progress, even if progress recedes. @@ -287,28 +285,28 @@ TEST_F(BugreportTest, OkProgressAlwaysForward) { ExpectProgress(50); ExpectProgress(75); // clang-format off - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit... .WillOnce(DoAll( - WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")), - WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), // 1% - WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")), // 50% + WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")), + WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1% + WithArg<2>(WriteOnStdout("PROGRESS:50/100\n")), // 50% // 25% should be ignored becaused it receded. - WithArg<4>(WriteOnStdout("PROGRESS:25/100\n")), // 25% - WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75% + WithArg<2>(WriteOnStdout("PROGRESS:25/100\n")), // 25% + WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75% // 75% should be ignored becaused it didn't change. - WithArg<4>(WriteOnStdout("PROGRESS:75/100\n")), // 75% + WithArg<2>(WriteOnStdout("PROGRESS:75/100\n")), // 75% // Try a receeding percentage with a different max progress - WithArg<4>(WriteOnStdout("PROGRESS:700/1000\n")), // 70% - WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + WithArg<2>(WriteOnStdout("PROGRESS:700/1000\n")), // 70% + WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); // clang-format on EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), true, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when it succeeds and displays the initial progress of 0% @@ -317,21 +315,21 @@ TEST_F(BugreportTest, OkProgressZeroPercentIsNotIgnored) { ExpectProgress(0); ExpectProgress(1); // clang-format off - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit... .WillOnce(DoAll( - WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")), - WithArg<4>(WriteOnStdout("PROGRESS:1/100000\n")), - WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")), // 1% - WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + WithArg<2>(WriteOnStdout("BEGIN:/device/bugreport.zip\n")), + WithArg<2>(WriteOnStdout("PROGRESS:1/100000\n")), + WithArg<2>(WriteOnStdout("PROGRESS:1/100\n")), // 1% + WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); // clang-format on EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), true, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport dir' when it succeeds and destination is a directory. @@ -341,30 +339,30 @@ TEST_F(BugreportTest, OkDirectory) { std::string dest_file = android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), - WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), + WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), true, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", td.path}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file' when it succeeds TEST_F(BugreportTest, OkNoExtension) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip\n")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip\n")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), true, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file"}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport dir' when it succeeds and destination is a directory and device runs N. @@ -374,28 +372,28 @@ TEST_F(BugreportTest, OkNDeviceDirectory) { std::string dest_file = android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), - WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")), + WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), true, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", td.path}; - ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(0, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when the bugreport itself failed TEST_F(BugreportTest, BugreportzReturnedFail) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) .WillOnce( - DoAll(WithArg<4>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<4>(ReturnCallbackDone()))); + DoAll(WithArg<2>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<2>(ReturnCallbackDone()))); CaptureStderr(); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(-1, br_.DoIt(2, args)); ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!")); } @@ -404,13 +402,13 @@ TEST_F(BugreportTest, BugreportzReturnedFail) { // multiple buffer writes TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("FAIL")), WithArg<4>(WriteOnStdout(":D'OH!\n")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("FAIL")), WithArg<2>(WriteOnStdout(":D'OH!\n")), + WithArg<2>(ReturnCallbackDone()))); CaptureStderr(); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(-1, br_.DoIt(2, args)); ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!")); } @@ -418,23 +416,22 @@ TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) { // response. TEST_F(BugreportTest, BugreportzReturnedUnsupported) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("bugreportz? What am I, a zombie?")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("bugreportz? What am I, a zombie?")), + WithArg<2>(ReturnCallbackDone()))); CaptureStderr(); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(-1, br_.DoIt(2, args)); ASSERT_THAT(GetCapturedStderr(), HasSubstr("bugreportz? What am I, a zombie?")); } // Tests 'adb bugreport file.zip' when the bugreportz -v command failed TEST_F(BugreportTest, BugreportzVersionFailed) { - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _)) - .WillOnce(Return(666)); + EXPECT_CALL(br_, SendShellCommand("bugreportz -v", false, _)).WillOnce(Return(666)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(666, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when the bugreportz -v returns status 0 but with no output. @@ -442,29 +439,28 @@ TEST_F(BugreportTest, BugreportzVersionEmpty) { ExpectBugreportzVersion(""); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(-1, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when the main bugreportz command failed TEST_F(BugreportTest, BugreportzFailed) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(Return(666)); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)).WillOnce(Return(666)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(666, br_.DoIt(2, args)); } // Tests 'adb bugreport file.zip' when the bugreport could not be pulled TEST_F(BugreportTest, PullFails) { ExpectBugreportzVersion("1.1"); - EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _)) - .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")), - WithArg<4>(ReturnCallbackDone()))); + EXPECT_CALL(br_, SendShellCommand("bugreportz -p", false, _)) + .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")), + WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), true, HasSubstr("file.zip"))) .WillOnce(Return(false)); const char* args[] = {"bugreport", "file.zip"}; - ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args)); + ASSERT_EQ(1, br_.DoIt(2, args)); } diff --git a/adb/commandline.cpp b/adb/commandline.cpp index c9f1ee9cf..9fac61cdd 100644 --- a/adb/commandline.cpp +++ b/adb/commandline.cpp @@ -62,11 +62,11 @@ #include "shell_service.h" #include "sysdeps/chrono.h" -static int install_app(TransportType t, const char* serial, int argc, const char** argv); -static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv); -static int uninstall_app(TransportType t, const char* serial, int argc, const char** argv); -static int install_app_legacy(TransportType t, const char* serial, int argc, const char** argv); -static int uninstall_app_legacy(TransportType t, const char* serial, int argc, const char** argv); +static int install_app(int argc, const char** argv); +static int install_multiple_app(int argc, const char** argv); +static int uninstall_app(int argc, const char** argv); +static int install_app_legacy(int argc, const char** argv); +static int uninstall_app_legacy(int argc, const char** argv); extern int gListenAll; @@ -90,6 +90,7 @@ static void help() { " -d use USB device (error if multiple devices connected)\n" " -e use TCP/IP device (error if multiple TCP/IP devices available)\n" " -s SERIAL use device with given serial (overrides $ANDROID_SERIAL)\n" + " -t ID use device with given transport id\n" " -H name of adb server host [default=localhost]\n" " -P port of adb server [default=5037]\n" " -L SOCKET listen on given socket for adb server [default=tcp:localhost:5037]\n" @@ -986,13 +987,16 @@ static int ppp(int argc, const char** argv) { #endif /* !defined(_WIN32) */ } -static bool wait_for_device(const char* service, TransportType t, const char* serial) { +static bool wait_for_device(const char* service) { std::vector components = android::base::Split(service, "-"); if (components.size() < 3 || components.size() > 4) { fprintf(stderr, "adb: couldn't parse 'wait-for' command: %s\n", service); return false; } + TransportType t; + adb_get_transport(&t, nullptr, nullptr); + // Was the caller vague about what they'd like us to wait for? // If so, check they weren't more specific in their choice of transport type. if (components.size() == 3) { @@ -1019,7 +1023,7 @@ static bool wait_for_device(const char* service, TransportType t, const char* se return false; } - std::string cmd = format_host_command(android::base::Join(components, "-").c_str(), t, serial); + std::string cmd = format_host_command(android::base::Join(components, "-").c_str()); return adb_command(cmd); } @@ -1065,8 +1069,8 @@ static bool adb_root(const char* command) { return true; } -int send_shell_command(TransportType transport_type, const char* serial, const std::string& command, - bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) { +int send_shell_command(const std::string& command, bool disable_shell_protocol, + StandardStreamsCallbackInterface* callback) { int fd; bool use_shell_protocol = false; @@ -1097,7 +1101,7 @@ int send_shell_command(TransportType transport_type, const char* serial, const s } fprintf(stderr, "- waiting for device -\n"); - if (!wait_for_device("wait-for-device", transport_type, serial)) { + if (!wait_for_device("wait-for-device")) { return 1; } } @@ -1111,7 +1115,7 @@ int send_shell_command(TransportType transport_type, const char* serial, const s return exit_code; } -static int logcat(TransportType transport, const char* serial, int argc, const char** argv) { +static int logcat(int argc, const char** argv) { char* log_tags = getenv("ANDROID_LOG_TAGS"); std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags); @@ -1128,7 +1132,7 @@ static int logcat(TransportType transport, const char* serial, int argc, const c } // No need for shell protocol with logcat, always disable for simplicity. - return send_shell_command(transport, serial, cmd, true); + return send_shell_command(cmd, true); } static void write_zeros(int bytes, int fd) { @@ -1340,6 +1344,7 @@ int adb_commandline(int argc, const char** argv) { // We need to check for -d and -e before we look at $ANDROID_SERIAL. const char* serial = nullptr; + TransportId transport_id = 0; while (argc > 0) { if (!strcmp(argv[0],"server")) { @@ -1359,7 +1364,7 @@ int adb_commandline(int argc, const char** argv) { fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str); return 1; } - } else if (argv[0][0]=='-' && argv[0][1]=='s') { + } else if (!strncmp(argv[0], "-s", 2)) { if (isdigit(argv[0][2])) { serial = argv[0] + 2; } else { @@ -1368,6 +1373,19 @@ int adb_commandline(int argc, const char** argv) { argc--; argv++; } + } else if (!strncmp(argv[0], "-t", 2)) { + const char* id; + if (isdigit(argv[0][2])) { + id = argv[0] + 2; + } else { + id = argv[1]; + argc--; + argv++; + } + transport_id = strtoll(id, const_cast(&id), 10); + if (*id != '\0') { + return syntax_error("invalid transport id"); + } } else if (!strcmp(argv[0],"-d")) { transport_type = kTransportUsb; } else if (!strcmp(argv[0],"-e")) { @@ -1451,7 +1469,7 @@ int adb_commandline(int argc, const char** argv) { serial = getenv("ANDROID_SERIAL"); } - adb_set_transport(transport_type, serial); + adb_set_transport(transport_type, serial, transport_id); if (is_server) { if (no_daemon || is_daemon) { @@ -1478,7 +1496,7 @@ int adb_commandline(int argc, const char** argv) { if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) { const char* service = argv[0]; - if (!wait_for_device(service, transport_type, serial)) { + if (!wait_for_device(service)) { return 1; } @@ -1589,7 +1607,7 @@ int adb_commandline(int argc, const char** argv) { return adb_root(argv[0]) ? 0 : 1; } else if (!strcmp(argv[0], "bugreport")) { Bugreport bugreport; - return bugreport.DoIt(transport_type, serial, argc, argv); + return bugreport.DoIt(argc, argv); } else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) { bool reverse = !strcmp(argv[0], "reverse"); ++argv; @@ -1685,20 +1703,20 @@ int adb_commandline(int argc, const char** argv) { else if (!strcmp(argv[0], "install")) { if (argc < 2) return syntax_error("install requires an argument"); if (_use_legacy_install()) { - return install_app_legacy(transport_type, serial, argc, argv); + return install_app_legacy(argc, argv); } - return install_app(transport_type, serial, argc, argv); + return install_app(argc, argv); } else if (!strcmp(argv[0], "install-multiple")) { if (argc < 2) return syntax_error("install-multiple requires an argument"); - return install_multiple_app(transport_type, serial, argc, argv); + return install_multiple_app(argc, argv); } else if (!strcmp(argv[0], "uninstall")) { if (argc < 2) return syntax_error("uninstall requires an argument"); if (_use_legacy_install()) { - return uninstall_app_legacy(transport_type, serial, argc, argv); + return uninstall_app_legacy(argc, argv); } - return uninstall_app(transport_type, serial, argc, argv); + return uninstall_app(argc, argv); } else if (!strcmp(argv[0], "sync")) { std::string src; @@ -1752,11 +1770,11 @@ int adb_commandline(int argc, const char** argv) { !strcmp(argv[0],"get-serialno") || !strcmp(argv[0],"get-devpath")) { - return adb_query_command(format_host_command(argv[0], transport_type, serial)); + return adb_query_command(format_host_command(argv[0])); } /* other commands */ else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) { - return logcat(transport_type, serial, argc, argv); + return logcat(argc, argv); } else if (!strcmp(argv[0],"ppp")) { return ppp(argc, argv); @@ -1819,7 +1837,7 @@ int adb_commandline(int argc, const char** argv) { return adb_query_command("host:host-features"); } else if (!strcmp(argv[0], "reconnect")) { if (argc == 1) { - return adb_query_command(format_host_command(argv[0], transport_type, serial)); + return adb_query_command(format_host_command(argv[0])); } else if (argc == 2) { if (!strcmp(argv[1], "device")) { std::string err; @@ -1838,7 +1856,7 @@ int adb_commandline(int argc, const char** argv) { return 1; } -static int uninstall_app(TransportType transport, const char* serial, int argc, const char** argv) { +static int uninstall_app(int argc, const char** argv) { // 'adb uninstall' takes the same arguments as 'cmd package uninstall' on device std::string cmd = "cmd package"; while (argc-- > 0) { @@ -1854,10 +1872,10 @@ static int uninstall_app(TransportType transport, const char* serial, int argc, cmd += " " + escape_arg(*argv++); } - return send_shell_command(transport, serial, cmd, false); + return send_shell_command(cmd, false); } -static int install_app(TransportType transport, const char* serial, int argc, const char** argv) { +static int install_app(int argc, const char** argv) { // The last argument must be the APK file const char* file = argv[argc - 1]; if (!android::base::EndsWithIgnoreCase(file, ".apk")) { @@ -1910,9 +1928,7 @@ static int install_app(TransportType transport, const char* serial, int argc, co return 1; } -static int install_multiple_app(TransportType transport, const char* serial, int argc, - const char** argv) -{ +static int install_multiple_app(int argc, const char** argv) { // Find all APK arguments starting at end. // All other arguments passed through verbatim. int first_apk = -1; @@ -2037,17 +2053,17 @@ finalize_session: return EXIT_FAILURE; } -static int pm_command(TransportType transport, const char* serial, int argc, const char** argv) { +static int pm_command(int argc, const char** argv) { std::string cmd = "pm"; while (argc-- > 0) { cmd += " " + escape_arg(*argv++); } - return send_shell_command(transport, serial, cmd, false); + return send_shell_command(cmd, false); } -static int uninstall_app_legacy(TransportType transport, const char* serial, int argc, const char** argv) { +static int uninstall_app_legacy(int argc, const char** argv) { /* if the user choose the -k option, we refuse to do it until devices are out with the option to uninstall the remaining data somehow (adb/ui) */ int i; @@ -2063,15 +2079,15 @@ static int uninstall_app_legacy(TransportType transport, const char* serial, int } /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */ - return pm_command(transport, serial, argc, argv); + return pm_command(argc, argv); } -static int delete_file(TransportType transport, const char* serial, const std::string& filename) { +static int delete_file(const std::string& filename) { std::string cmd = "rm -f " + escape_arg(filename); - return send_shell_command(transport, serial, cmd, false); + return send_shell_command(cmd, false); } -static int install_app_legacy(TransportType transport, const char* serial, int argc, const char** argv) { +static int install_app_legacy(int argc, const char** argv) { static const char *const DATA_DEST = "/data/local/tmp/%s"; static const char *const SD_DEST = "/sdcard/tmp/%s"; const char* where = DATA_DEST; @@ -2100,9 +2116,9 @@ static int install_app_legacy(TransportType transport, const char* serial, int a where, android::base::Basename(argv[last_apk]).c_str()); if (!do_sync_push(apk_file, apk_dest.c_str(), false)) goto cleanup_apk; argv[last_apk] = apk_dest.c_str(); /* destination name, not source location */ - result = pm_command(transport, serial, argc, argv); + result = pm_command(argc, argv); cleanup_apk: - delete_file(transport, serial, apk_dest); + delete_file(apk_dest); return result; } diff --git a/adb/commandline.h b/adb/commandline.h index 9ba69a396..36cd79841 100644 --- a/adb/commandline.h +++ b/adb/commandline.h @@ -91,8 +91,8 @@ int adb_commandline(int argc, const char** argv); // Connects to the device "shell" service with |command| and prints the // resulting output. // if |callback| is non-null, stdout/stderr output will be handled by it. -int send_shell_command(TransportType transport_type, const char* serial, const std::string& command, - bool disable_shell_protocol, StandardStreamsCallbackInterface* callback = - &DEFAULT_STANDARD_STREAMS_CALLBACK); +int send_shell_command( + const std::string& command, bool disable_shell_protocol, + StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK); #endif // COMMANDLINE_H diff --git a/adb/services.cpp b/adb/services.cpp index 9605e6ec0..378074741 100644 --- a/adb/services.cpp +++ b/adb/services.cpp @@ -187,7 +187,7 @@ int reverse_service(const char* command) { return -1; } VLOG(SERVICES) << "service socketpair: " << s[0] << ", " << s[1]; - if (handle_forward_request(command, kTransportAny, nullptr, s[1]) < 0) { + if (handle_forward_request(command, kTransportAny, nullptr, 0, s[1]) < 0) { SendFail(s[1], "not a reverse forwarding command"); } adb_close(s[1]); @@ -334,6 +334,7 @@ int service_to_fd(const char* name, const atransport* transport) { struct state_info { TransportType transport_type; std::string serial; + TransportId transport_id; ConnectionState state; }; @@ -346,7 +347,8 @@ static void wait_for_state(int fd, void* data) { bool is_ambiguous = false; std::string error = "unknown error"; const char* serial = sinfo->serial.length() ? sinfo->serial.c_str() : NULL; - atransport* t = acquire_one_transport(sinfo->transport_type, serial, &is_ambiguous, &error); + atransport* t = acquire_one_transport(sinfo->transport_type, serial, sinfo->transport_id, + &is_ambiguous, &error); if (t != nullptr && (sinfo->state == kCsAny || sinfo->state == t->GetConnectionState())) { SendOkay(fd); break; @@ -437,7 +439,7 @@ static void connect_service(int fd, void* data) { #endif #if ADB_HOST -asocket* host_service_to_socket(const char* name, const char* serial) { +asocket* host_service_to_socket(const char* name, const char* serial, TransportId transport_id) { if (!strcmp(name,"track-devices")) { return create_device_tracker(); } else if (android::base::StartsWith(name, "wait-for-")) { @@ -450,6 +452,7 @@ asocket* host_service_to_socket(const char* name, const char* serial) { } if (serial) sinfo->serial = serial; + sinfo->transport_id = transport_id; if (android::base::StartsWith(name, "local")) { name += strlen("local"); diff --git a/adb/sockets.cpp b/adb/sockets.cpp index e0143c611..f28a3df50 100644 --- a/adb/sockets.cpp +++ b/adb/sockets.cpp @@ -430,10 +430,11 @@ asocket* create_local_service_socket(const char* name, const atransport* transpo } #if ADB_HOST -static asocket* create_host_service_socket(const char* name, const char* serial) { +static asocket* create_host_service_socket(const char* name, const char* serial, + TransportId transport_id) { asocket* s; - s = host_service_to_socket(name, serial); + s = host_service_to_socket(name, serial, transport_id); if (s != NULL) { D("LS(%d) bound to '%s'", s->id, name); @@ -658,6 +659,7 @@ static int smart_socket_enqueue(asocket* s, apacket* p) { #if ADB_HOST char* service = nullptr; char* serial = nullptr; + TransportId transport_id = 0; TransportType type = kTransportAny; #endif @@ -715,6 +717,14 @@ static int smart_socket_enqueue(asocket* s, apacket* p) { serial = service; service = serial_end + 1; } + } else if (!strncmp(service, "host-transport-id:", strlen("host-transport-id:"))) { + service += strlen("host-transport-id:"); + transport_id = strtoll(service, &service, 10); + + if (*service != ':') { + return -1; + } + service++; } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) { type = kTransportUsb; service += strlen("host-usb:"); @@ -736,7 +746,7 @@ static int smart_socket_enqueue(asocket* s, apacket* p) { ** the OKAY or FAIL message and all we have to do ** is clean up. */ - if (handle_host_request(service, type, serial, s->peer->fd, s) == 0) { + if (handle_host_request(service, type, serial, transport_id, s->peer->fd, s) == 0) { /* XXX fail message? */ D("SS(%d): handled host service '%s'", s->id, service); goto fail; @@ -751,7 +761,7 @@ static int smart_socket_enqueue(asocket* s, apacket* p) { ** if no such service exists, we'll fail out ** and tear down here. */ - s2 = create_host_service_socket(service, serial); + s2 = create_host_service_socket(service, serial, transport_id); if (s2 == 0) { D("SS(%d): couldn't create host service '%s'", s->id, service); SendFail(s->peer->fd, "unknown host service"); @@ -783,7 +793,7 @@ static int smart_socket_enqueue(asocket* s, apacket* p) { #else /* !ADB_HOST */ if (s->transport == nullptr) { std::string error_msg = "unknown failure"; - s->transport = acquire_one_transport(kTransportAny, nullptr, nullptr, &error_msg); + s->transport = acquire_one_transport(kTransportAny, nullptr, 0, nullptr, &error_msg); if (s->transport == nullptr) { SendFail(s->peer->fd, error_msg); goto fail; diff --git a/adb/transport.cpp b/adb/transport.cpp index c26252e43..91d708f6a 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include #include "adb.h" #include "adb_auth.h" @@ -46,6 +48,7 @@ static void transport_unref(atransport *t); +// TODO: unordered_map static auto& transport_list = *new std::list(); static auto& pending_list = *new std::list(); @@ -57,6 +60,11 @@ const char* const kFeatureStat2 = "stat_v2"; const char* const kFeatureLibusb = "libusb"; const char* const kFeaturePushSync = "push_sync"; +TransportId NextTransportId() { + static std::atomic next(1); + return next++; +} + static std::string dump_packet(const char* name, const char* func, apacket* p) { unsigned command = p->msg.command; int len = p->msg.data_length; @@ -301,6 +309,8 @@ void kick_transport(atransport* t) { std::lock_guard lock(transport_lock); // As kick_transport() can be called from threads without guarantee that t is valid, // check if the transport is in transport_list first. + // + // TODO(jmgao): WTF? Is this actually true? if (std::find(transport_list.begin(), transport_list.end(), t) != transport_list.end()) { t->Kick(); } @@ -638,11 +648,15 @@ static int qual_match(const char* to_test, const char* prefix, const char* qual, return !*to_test; } -atransport* acquire_one_transport(TransportType type, const char* serial, bool* is_ambiguous, - std::string* error_out, bool accept_any_state) { +atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id, + bool* is_ambiguous, std::string* error_out, + bool accept_any_state) { atransport* result = nullptr; - if (serial) { + if (transport_id != 0) { + *error_out = + android::base::StringPrintf("no device with transport id '%" PRIu64 "'", transport_id); + } else if (serial) { *error_out = android::base::StringPrintf("device '%s' not found", serial); } else if (type == kTransportLocal) { *error_out = "no emulators found"; @@ -661,8 +675,12 @@ atransport* acquire_one_transport(TransportType type, const char* serial, bool* continue; } - // Check for matching serial number. - if (serial) { + if (transport_id) { + if (t->id == transport_id) { + result = t; + break; + } + } else if (serial) { if (t->MatchesTarget(serial)) { if (result) { *error_out = "more than one device"; @@ -889,18 +907,23 @@ bool atransport::MatchesTarget(const std::string& target) const { #if ADB_HOST +// We use newline as our delimiter, make sure to never output it. +static std::string sanitize(std::string str, bool alphanumeric) { + auto pred = alphanumeric ? [](const char c) { return !isalnum(c); } + : [](const char c) { return c == '\n'; }; + std::replace_if(str.begin(), str.end(), pred, '_'); + return str; +} + static void append_transport_info(std::string* result, const char* key, const char* value, - bool sanitize) { + bool alphanumeric) { if (value == nullptr || *value == '\0') { return; } *result += ' '; *result += key; - - for (const char* p = value; *p; ++p) { - result->push_back((!sanitize || isalnum(*p)) ? *p : '_'); - } + *result += sanitize(value, alphanumeric); } static void append_transport(const atransport* t, std::string* result, bool long_listing) { @@ -920,6 +943,11 @@ static void append_transport(const atransport* t, std::string* result, bool long append_transport_info(result, "product:", t->product, false); append_transport_info(result, "model:", t->model, true); append_transport_info(result, "device:", t->device, false); + + // Put id at the end, so that anyone parsing the output here can always find it by scanning + // backwards from newlines, even with hypothetical devices named 'transport_id:1'. + *result += " transport_id:"; + *result += std::to_string(t->id); } *result += '\n'; } diff --git a/adb/transport.h b/adb/transport.h index 4a89ed993..238e959f2 100644 --- a/adb/transport.h +++ b/adb/transport.h @@ -54,14 +54,17 @@ extern const char* const kFeatureLibusb; // The server supports `push --sync`. extern const char* const kFeaturePushSync; +TransportId NextTransportId(); + class atransport { -public: + public: // TODO(danalbert): We expose waaaaaaay too much stuff because this was // historically just a struct, but making the whole thing a more idiomatic // class in one go is a very large change. Given how bad our testing is, // it's better to do this piece by piece. - atransport(ConnectionState state = kCsOffline) : ref_count(0), connection_state_(state) { + atransport(ConnectionState state = kCsOffline) + : id(NextTransportId()), ref_count(0), connection_state_(state) { transport_fde = {}; protocol_version = A_VERSION; max_payload = MAX_PAYLOAD; @@ -72,12 +75,8 @@ public: void (*close)(atransport* t) = nullptr; void SetWriteFunction(int (*write_func)(apacket*, atransport*)) { write_func_ = write_func; } - void SetKickFunction(void (*kick_func)(atransport*)) { - kick_func_ = kick_func; - } - bool IsKicked() { - return kicked_; - } + void SetKickFunction(void (*kick_func)(atransport*)) { kick_func_ = kick_func; } + bool IsKicked() { return kicked_; } int Write(apacket* p); void Kick(); @@ -85,6 +84,7 @@ public: ConnectionState GetConnectionState() const; void SetConnectionState(ConnectionState state); + const TransportId id; int fd = -1; int transport_socket = -1; fdevent transport_fde; @@ -191,12 +191,14 @@ private: /* * Obtain a transport from the available transports. * If serial is non-null then only the device with that serial will be chosen. + * If transport_id is non-zero then only the device with that transport ID will be chosen. * If multiple devices/emulators would match, *is_ambiguous (if non-null) * is set to true and nullptr returned. * If no suitable transport is found, error is set and nullptr returned. */ -atransport* acquire_one_transport(TransportType type, const char* serial, bool* is_ambiguous, - std::string* error_out, bool accept_any_state = false); +atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id, + bool* is_ambiguous, std::string* error_out, + bool accept_any_state = false); void kick_transport(atransport* t); void update_transports(void); From c78ecca70b44be14b06f526f17db199773ad160c Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 13 Sep 2017 13:40:57 -0700 Subject: [PATCH 110/129] Revert "adb: fix deadlock between transport_unref and usb_close." This reverts commit 7e197ef83307ffcf2f55d1b8a603d0d3bd2e1d4d. The mutex lock in transport_unref hides a race that seems otherwise hard to fix. Specifically, there's no synchronization between acquiring a transport and attaching it to an asocket*, leading to badness if the transport is closed in between the two operations. Fix the original problem the reverted patch addressed by manually unlocking before calling unregister_usb_transport. Bug: http://b/65419665 Bug: 64709603 (presubmit balking at the line above) Test: python test_device.py Change-Id: I0ed0044129b1671b2c5dd1b9fa2e70a9b4475dc5 (cherry picked from commit e48ecce671a2ab6647cc26a3cb11163aec0b712c) --- adb/client/usb_libusb.cpp | 7 ++++++- adb/transport.cpp | 10 +++++----- adb/transport.h | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp index e7f44c685..7025f283c 100644 --- a/adb/client/usb_libusb.cpp +++ b/adb/client/usb_libusb.cpp @@ -412,8 +412,13 @@ static void device_disconnected(libusb_device* device) { if (it != usb_handles.end()) { if (!it->second->device_handle) { // If the handle is null, we were never able to open the device. - unregister_usb_transport(it->second.get()); + + // Temporarily release the usb handles mutex to avoid deadlock. + std::unique_ptr handle = std::move(it->second); usb_handles.erase(it); + lock.unlock(); + unregister_usb_transport(handle.get()); + lock.lock(); } else { // Closure of the transport will erase the usb_handle. } diff --git a/adb/transport.cpp b/adb/transport.cpp index 91d708f6a..3cfb3f330 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -613,15 +613,15 @@ static void remove_transport(atransport* transport) { static void transport_unref(atransport* t) { CHECK(t != nullptr); - size_t old_refcount = t->ref_count--; - CHECK_GT(old_refcount, 0u); - - if (old_refcount == 1u) { + std::lock_guard lock(transport_lock); + CHECK_GT(t->ref_count, 0u); + t->ref_count--; + if (t->ref_count == 0) { D("transport: %s unref (kicking and closing)", t->serial); t->close(t); remove_transport(t); } else { - D("transport: %s unref (count=%zu)", t->serial, old_refcount - 1); + D("transport: %s unref (count=%zu)", t->serial, t->ref_count); } } diff --git a/adb/transport.h b/adb/transport.h index 238e959f2..dee27e16f 100644 --- a/adb/transport.h +++ b/adb/transport.h @@ -64,7 +64,7 @@ class atransport { // it's better to do this piece by piece. atransport(ConnectionState state = kCsOffline) - : id(NextTransportId()), ref_count(0), connection_state_(state) { + : id(NextTransportId()), connection_state_(state) { transport_fde = {}; protocol_version = A_VERSION; max_payload = MAX_PAYLOAD; @@ -88,7 +88,7 @@ class atransport { int fd = -1; int transport_socket = -1; fdevent transport_fde; - std::atomic ref_count; + size_t ref_count = 0; uint32_t sync_token = 0; bool online = false; TransportType type = kTransportAny; From 2b933918fcdbfb411502a9b12d77d6a1895855ce Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 13 Sep 2017 11:17:33 -0700 Subject: [PATCH 111/129] adb: add lock to remove_socket. The comment that was previously here says that local_socket_list_lock must be taken, but this function is exposed to external callers that can't possibly take the lock. Bug: http://b/65419665 Bug: 64709603 (presubmit balking at the line above) Test: python test_device.py Change-Id: I12d464933936b2a210a827ccf19ea201020d8d78 (cherry picked from commit 62c92f0c0529d8d1817afb4ff0c83151e4bb0ea0) --- adb/sockets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adb/sockets.cpp b/adb/sockets.cpp index f28a3df50..c53fbb4ff 100644 --- a/adb/sockets.cpp +++ b/adb/sockets.cpp @@ -96,7 +96,7 @@ void install_local_socket(asocket* s) { } void remove_socket(asocket* s) { - // socket_list_lock should already be held + std::lock_guard lock(local_socket_list_lock); if (s->prev && s->next) { s->prev->next = s->next; s->next->prev = s->prev; From 326b783ad92048432c4a8a70a35c8342b35128b0 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Fri, 29 Sep 2017 05:04:00 +0900 Subject: [PATCH 112/129] Tests are run with proper namespace configs by their locations Tests in /data/[nativetest|benchmarktest] run with namespace config for system and tests in /data/[nativetest|benchmarktest]/vendor run with namespace config for vendor. They no longer run in the 'test' namespace config which didn't impose any restriction for libraries. Bug: 67028906 Test: sailfish/marlin builds and boots Test: no VTS regression on system.img from GSI + vendor.img from marlin/sailfish Test: VtsKernelLibcutilsTest successful in above config Change-Id: I28cdef960d087565c8a22dca0e9a154fb1c3bb94 --- rootdir/etc/ld.config.txt | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index 7f86a950b..8afd4361e 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt @@ -7,10 +7,14 @@ dir.system = /system/bin/ dir.system = /system/xbin/ dir.vendor = /vendor/bin/ -dir.test = /data/nativetest/ -dir.test = /data/nativetest64/ -dir.test = /data/benchmarktest/ -dir.test = /data/benchmarktest64/ +dir.vendor = /data/nativetest/vendor +dir.vendor = /data/nativetest64/vendor +dir.vendor = /data/benchmarktest/vendor +dir.vendor = /data/benchmarktest64/vendor +dir.system = /data/nativetest +dir.system = /data/nativetest64 +dir.system = /data/benchmarktest +dir.system = /data/benchmarktest64 [system] additional.namespaces = sphal,vndk,rs @@ -121,12 +125,3 @@ namespace.default.isolated = false namespace.default.search.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl:/vendor/${LIB}:/system/${LIB}/vndk:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/system/${LIB} namespace.default.asan.search.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl:/data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB} - -############################################################################### -# Namespace config for tests. No VNDK restriction is enforced for these tests. -############################################################################### -[test] -namespace.default.isolated = false -namespace.default.search.paths = /vendor/${LIB}:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/system/${LIB} - -namespace.default.asan.search.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB} From c4c0a7136b7736f26f065c600a766d2400ace76c Mon Sep 17 00:00:00 2001 From: Ting-Yuan Huang Date: Tue, 15 Aug 2017 15:07:21 -0700 Subject: [PATCH 113/129] Fix a potential memory leak Bug: 65648324 Test: Built without seeing the warnings Change-Id: I934509c78482af9ef7dc447c807f6450484b4b38 (cherry picked from commit f26cf6d52095a63f822ffc02d3b263543bdec0d9) --- adb/services.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/adb/services.cpp b/adb/services.cpp index 378074741..cc840b875 100644 --- a/adb/services.cpp +++ b/adb/services.cpp @@ -481,11 +481,17 @@ asocket* host_service_to_socket(const char* name, const char* serial, TransportI return nullptr; } - int fd = create_service_thread(wait_for_state, sinfo.release()); + int fd = create_service_thread(wait_for_state, sinfo.get()); + if (fd != -1) { + sinfo.release(); + } return create_local_socket(fd); } else if (!strncmp(name, "connect:", 8)) { char* host = strdup(name + 8); int fd = create_service_thread(connect_service, host); + if (fd == -1) { + free(host); + } return create_local_socket(fd); } return NULL; From 3f526fe1e33b3ebd240ff7bee9c4da44621608a3 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Thu, 28 Sep 2017 16:29:53 -0700 Subject: [PATCH 114/129] adbd: improve thread names. Name each service thread specifically to improve debuggability. Bug: http://b/65648324 Bug: 64709603 (presubmit balking at the line above) Test: adb shell debuggerd -b `adb shell pidof adbd` during a sync Change-Id: I644e25fc2f14a26eafd19f596e4e8f3c2bb79967 (cherry picked from commit bcadc77550d22d866b179f745450b797e2d2bfe6) --- adb/services.cpp | 39 +++++++++++++++++++++------------------ adb/shell_service.cpp | 3 +-- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/adb/services.cpp b/adb/services.cpp index cc840b875..1660846be 100644 --- a/adb/services.cpp +++ b/adb/services.cpp @@ -58,6 +58,7 @@ #include "transport.h" struct stinfo { + const char* service_name; void (*func)(int fd, void *cookie); int fd; void *cookie; @@ -65,7 +66,7 @@ struct stinfo { static void service_bootstrap_func(void* x) { stinfo* sti = reinterpret_cast(x); - adb_thread_setname(android::base::StringPrintf("service %d", sti->fd)); + adb_thread_setname(android::base::StringPrintf("%s svc %d", sti->service_name, sti->fd)); sti->func(sti->fd, sti->cookie); free(sti); } @@ -159,8 +160,7 @@ static bool reboot_service_impl(int fd, const char* arg) { return true; } -void reboot_service(int fd, void* arg) -{ +void reboot_service(int fd, void* arg) { if (reboot_service_impl(fd, static_cast(arg))) { // Don't return early. Give the reboot command time to take effect // to avoid messing up scripts which do "adb reboot && adb wait-for-device" @@ -235,8 +235,7 @@ static int ShellService(const std::string& args, const atransport* transport) { #endif // !ADB_HOST -static int create_service_thread(void (*func)(int, void *), void *cookie) -{ +static int create_service_thread(const char* service_name, void (*func)(int, void*), void* cookie) { int s[2]; if (adb_socketpair(s)) { printf("cannot create service socket pair\n"); @@ -257,6 +256,7 @@ static int create_service_thread(void (*func)(int, void *), void *cookie) if (sti == nullptr) { fatal("cannot allocate stinfo"); } + sti->service_name = service_name; sti->func = func; sti->cookie = cookie; sti->fd = s[1]; @@ -280,7 +280,7 @@ int service_to_fd(const char* name, const atransport* transport) { } else if(!strncmp("dev:", name, 4)) { ret = unix_open(name + 4, O_RDWR | O_CLOEXEC); } else if(!strncmp(name, "framebuffer:", 12)) { - ret = create_service_thread(framebuffer_service, 0); + ret = create_service_thread("fb", framebuffer_service, nullptr); } else if (!strncmp(name, "jdwp:", 5)) { ret = create_jdwp_connection_fd(atoi(name+5)); } else if(!strncmp(name, "shell", 5)) { @@ -288,17 +288,17 @@ int service_to_fd(const char* name, const atransport* transport) { } else if(!strncmp(name, "exec:", 5)) { ret = StartSubprocess(name + 5, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); } else if(!strncmp(name, "sync:", 5)) { - ret = create_service_thread(file_sync_service, NULL); + ret = create_service_thread("sync", file_sync_service, nullptr); } else if(!strncmp(name, "remount:", 8)) { - ret = create_service_thread(remount_service, NULL); + ret = create_service_thread("remount", remount_service, nullptr); } else if(!strncmp(name, "reboot:", 7)) { void* arg = strdup(name + 7); if (arg == NULL) return -1; - ret = create_service_thread(reboot_service, arg); + ret = create_service_thread("reboot", reboot_service, arg); } else if(!strncmp(name, "root:", 5)) { - ret = create_service_thread(restart_root_service, NULL); + ret = create_service_thread("root", restart_root_service, nullptr); } else if(!strncmp(name, "unroot:", 7)) { - ret = create_service_thread(restart_unroot_service, NULL); + ret = create_service_thread("unroot", restart_unroot_service, nullptr); } else if(!strncmp(name, "backup:", 7)) { ret = StartSubprocess(android::base::StringPrintf("/system/bin/bu backup %s", (name + 7)).c_str(), @@ -311,17 +311,20 @@ int service_to_fd(const char* name, const atransport* transport) { if (sscanf(name + 6, "%d", &port) != 1) { return -1; } - ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port); + ret = create_service_thread("tcp", restart_tcp_service, reinterpret_cast(port)); } else if(!strncmp(name, "usb:", 4)) { - ret = create_service_thread(restart_usb_service, NULL); + ret = create_service_thread("usb", restart_usb_service, nullptr); } else if (!strncmp(name, "reverse:", 8)) { ret = reverse_service(name + 8); } else if(!strncmp(name, "disable-verity:", 15)) { - ret = create_service_thread(set_verity_enabled_state_service, (void*)0); + ret = create_service_thread("verity-on", set_verity_enabled_state_service, + reinterpret_cast(0)); } else if(!strncmp(name, "enable-verity:", 15)) { - ret = create_service_thread(set_verity_enabled_state_service, (void*)1); + ret = create_service_thread("verity-off", set_verity_enabled_state_service, + reinterpret_cast(1)); } else if (!strcmp(name, "reconnect")) { - ret = create_service_thread(reconnect_service, const_cast(transport)); + ret = create_service_thread("reconnect", reconnect_service, + const_cast(transport)); #endif } if (ret >= 0) { @@ -481,14 +484,14 @@ asocket* host_service_to_socket(const char* name, const char* serial, TransportI return nullptr; } - int fd = create_service_thread(wait_for_state, sinfo.get()); + int fd = create_service_thread("wait", wait_for_state, sinfo.get()); if (fd != -1) { sinfo.release(); } return create_local_socket(fd); } else if (!strncmp(name, "connect:", 8)) { char* host = strdup(name + 8); - int fd = create_service_thread(connect_service, host); + int fd = create_service_thread("connect", connect_service, host); if (fd == -1) { free(host); } diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp index ee821f834..5b48da029 100644 --- a/adb/shell_service.cpp +++ b/adb/shell_service.cpp @@ -435,8 +435,7 @@ int Subprocess::OpenPtyChildFd(const char* pts_name, unique_fd* error_sfd) { void Subprocess::ThreadHandler(void* userdata) { Subprocess* subprocess = reinterpret_cast(userdata); - adb_thread_setname(android::base::StringPrintf( - "shell srvc %d", subprocess->pid())); + adb_thread_setname(android::base::StringPrintf("shell svc %d", subprocess->pid())); D("passing data streams for PID %d", subprocess->pid()); subprocess->PassDataStreams(); From bc76f0ea2f5475b6b58b1928c471927c58056b93 Mon Sep 17 00:00:00 2001 From: Jorge Lucangeli Obes Date: Fri, 29 Sep 2017 14:56:07 -0400 Subject: [PATCH 115/129] run-as: Keep supplementary groups. This broke TCP debugging because processes don't inherit the AID_INET group. Bug: 67058466 Test: adb shell run-as com.example.native_activity groups prints "inet". (cherry picked from commit 8c27e19c1c20f05db9e9e061dffb3aa56d8275b9) Change-Id: I30bc3152267a2b3ee099bc9f604c017ef33dd685 --- run-as/run-as.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/run-as/run-as.cpp b/run-as/run-as.cpp index e7b8cc2c8..b27cfad7c 100644 --- a/run-as/run-as.cpp +++ b/run-as/run-as.cpp @@ -194,6 +194,7 @@ int main(int argc, char* argv[]) { ScopedMinijail j(minijail_new()); minijail_change_uid(j.get(), uid); minijail_change_gid(j.get(), gid); + minijail_keep_supplementary_gids(j.get()); minijail_enter(j.get()); if (selinux_android_setcontext(uid, 0, info.seinfo, pkgname) < 0) { From 2740bb09e3cee99032a86a1700cb0a6f14f3a51f Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Wed, 9 Aug 2017 18:32:09 +0100 Subject: [PATCH 116/129] zip_archive: reject files that don't start with an LFH signature. Bug: 64211847 Test: zip_archive_test Merged-In: Ib89f0def696206ff427be27764c158fab88e4b5d Merged-In: I275e7c4da05ceeb20401b560c72294f29ef63642 Change-Id: I38705f4e9688326a140aa59a1333b0878ed39c14 --- libziparchive/zip_archive.cc | 18 ++++++++++++ libziparchive/zip_archive_test.cc | 49 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc index 49097ce9b..89cfe77bc 100644 --- a/libziparchive/zip_archive.cc +++ b/libziparchive/zip_archive.cc @@ -358,6 +358,8 @@ static int32_t MapCentralDirectory(int fd, const char* debug_file_name, return result; } +static inline bool ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off); + /* * Parses the Zip archive's Central Directory. Allocates and populates the * hash table. @@ -436,6 +438,22 @@ static int32_t ParseZipArchive(ZipArchive* archive) { return -1; } } + + uint32_t lfh_start_bytes; + if (!ReadAtOffset(archive->fd, reinterpret_cast(&lfh_start_bytes), + sizeof(uint32_t), 0)) { + ALOGW("Zip: Unable to read header for entry at offset == 0."); + return -1; + } + + if (lfh_start_bytes != LocalFileHeader::kSignature) { + ALOGW("Zip: Entry at offset zero has invalid LFH signature %" PRIx32, lfh_start_bytes); +#if defined(__ANDROID__) + android_errorWriteLog(0x534e4554, "64211847"); +#endif + return -1; + } + ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries); return 0; diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc index 6aee1bbdf..b8db6a4d3 100644 --- a/libziparchive/zip_archive_test.cc +++ b/libziparchive/zip_archive_test.cc @@ -603,6 +603,55 @@ TEST(ziparchive, StreamUncompressedBadCrc) { CloseArchive(handle); } +// A zip file whose local file header at offset zero is corrupted. +// +// --------------- +// cat foo > a.txt +// zip a.zip a.txt +// cat a.zip | xxd -i +// +// Manual changes : +// [2] = 0xff // Corrupt the LFH signature of entry 0. +// [3] = 0xff // Corrupt the LFH signature of entry 0. +static const std::vector kZipFileWithBrokenLfhSignature{ + //[lfh-sig-----------], [lfh contents--------------------------------- + 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, + //-------------------------------------------------------------------- + 0x09, 0x4b, 0xa8, 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, + //-------------------------------] [file-name-----------------], [--- + 0x00, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, + // entry-contents------------------------------------------------------ + 0x54, 0x09, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x51, 0x24, 0x8b, 0x59, + //-------------------------------------------------------------------- + 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, + //-------------------------------------], [cd-record-sig-------], [--- + 0x13, 0x00, 0x00, 0x66, 0x6f, 0x6f, 0x0a, 0x50, 0x4b, 0x01, 0x02, 0x1e, + // cd-record----------------------------------------------------------- + 0x03, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, 0x09, 0x4b, 0xa8, + //-------------------------------------------------------------------- + 0x65, 0x32, 0x7e, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, + //-------------------------------------------------------------------- + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xa0, + //-] [lfh-file-header-off-], [file-name-----------------], [extra---- + 0x81, 0x00, 0x00, 0x00, 0x00, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54, + //-------------------------------------------------------------------- + 0x05, 0x00, 0x03, 0x51, 0x24, 0x8b, 0x59, 0x75, 0x78, 0x0b, 0x00, 0x01, + //-------------------------------------------------------], [eocd-sig- + 0x04, 0x89, 0x42, 0x00, 0x00, 0x04, 0x88, 0x13, 0x00, 0x00, 0x50, 0x4b, + //-------], [--------------------------------------------------------- + 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x4b, 0x00, + //-------------------------------------------] + 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; + +TEST(ziparchive, BrokenLfhSignature) { + TemporaryFile tmp_file; + ASSERT_NE(-1, tmp_file.fd); + ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0], + kZipFileWithBrokenLfhSignature.size())); + ZipArchiveHandle handle; + ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle)); +} + int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); From c75c59bc1b5d3ec99a8eeae0b4ed2668287bc6ee Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 2 Oct 2017 10:20:29 -0700 Subject: [PATCH 117/129] CtsLogdTestCases#sepolicy_rate_limiter failure (cherry pick from commit b825faeed78dec677223b8969626b6563ee7aaca) Cts tests can run in appdomain, which have access to /data/backup/ which leads to zero injection of sepolicy signal to check the logd and kernel rate limiter. Switch to /data/drm/ as a better choice to inject a sepolicy denial either due to dac_override or dac_read_search because owned by the drm uid and gid, or due to create sepolicy denial to u:object_r:drm_data_file:s0 to all but select services. Test: gTest Bug: 65843095 Change-Id: I2d72b1407a930c270636a206066d2d15fdec2f77 --- logd/tests/logd_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp index 4397b144c..d242f9b00 100644 --- a/logd/tests/logd_test.cpp +++ b/logd/tests/logd_test.cpp @@ -1091,7 +1091,7 @@ static pid_t sepolicy_rate(unsigned rate, unsigned num) { // and dac_read_search on every try to get past the message // de-duper. We will also rotate the file name in the directory // as another measure. - static const char file[] = "/data/backup/cannot_access_directory_%u"; + static const char file[] = "/data/drm/cannot_access_directory_%u"; static const unsigned avc_requests_per_access = 2; rate /= avc_requests_per_access; From 0617eb7d83cbce9f577c76a2fbb291d53882cdca Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Wed, 2 Aug 2017 13:22:38 -0700 Subject: [PATCH 118/129] Fix reference to out of scope local in adb_thread_setname. Bug: 67320882 Bug: https://android-review.googlesource.com/#/c/168725/5/adb/sysdeps.h@639 Test: boots, adbd thread names look sane Signed-off-by: Ivan Maidanski Change-Id: Ib3bdf53658f3903de8f0a5688f7d77745e677c77 (cherry picked from commit 7462f1858ce696c651442f74e2fb0e1b664b29b5) --- adb/sysdeps.h | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/adb/sysdeps.h b/adb/sysdeps.h index 49c784779..0abb680d3 100644 --- a/adb/sysdeps.h +++ b/adb/sysdeps.h @@ -582,18 +582,12 @@ static __inline__ int adb_thread_setname(const std::string& name) { #ifdef __APPLE__ return pthread_setname_np(name.c_str()); #else - const char *s = name.c_str(); - - // pthread_setname_np fails rather than truncating long strings. - const int max_task_comm_len = 16; // including the null terminator - if (name.length() > (max_task_comm_len - 1)) { - char buf[max_task_comm_len]; - strncpy(buf, name.c_str(), sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - s = buf; - } - - return pthread_setname_np(pthread_self(), s) ; + // Both bionic and glibc's pthread_setname_np fails rather than truncating long strings. + // glibc doesn't have strlcpy, so we have to fake it. + char buf[16]; // MAX_TASK_COMM_LEN, but that's not exported by the kernel headers. + strncpy(buf, name.c_str(), sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + return pthread_setname_np(pthread_self(), buf); #endif } From ec92e5f194fcad0e847df30497e8b70146c6e5ce Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Tue, 15 Aug 2017 18:09:54 -0700 Subject: [PATCH 119/129] Don't preserve file attributes when pulling bugreport file... ...otherwise it could have weird dates when the device clock is wrong. Bug: 67320882 Test: m -j32 adb && ./out/host/linux-x86/bin/adb bugreport test.zip && ls -l test.zip Test: m -j32 adb_test && ./out/host/linux-x86/nativetest64/adb_test/adb_test Fixes: 63927360 Change-Id: I3f87277f1acb97212a87b89639e42b6d7d300faa (cherry picked from commit 4bfddbd20e3bf11ffc31c8c4177a13ed14ab1a11) --- adb/bugreport.cpp | 2 +- adb/bugreport_test.cpp | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp index f63ac08a6..abef86a68 100644 --- a/adb/bugreport.cpp +++ b/adb/bugreport.cpp @@ -102,7 +102,7 @@ class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface std::vector srcs{src_file_.c_str()}; SetLineMessage("pulling"); status_ = - br_->DoSyncPull(srcs, destination.c_str(), true, line_message_.c_str()) ? 0 : 1; + br_->DoSyncPull(srcs, destination.c_str(), false, line_message_.c_str()) ? 0 : 1; if (status_ != 0) { fprintf(stderr, "Bug report finished but could not be copied to '%s'.\n" diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp index 758f24a06..72ca59aa7 100644 --- a/adb/bugreport_test.cpp +++ b/adb/bugreport_test.cpp @@ -185,7 +185,7 @@ TEST_F(BugreportTest, NoArgumentsNDevice) { .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")), WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), - true, StrEq("pulling da_bugreport.zip"))) + false, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport"}; @@ -205,7 +205,7 @@ TEST_F(BugreportTest, NoArgumentsPostNDevice) { WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip\n")), WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), - true, StrEq("pulling da_bugreport.zip"))) + false, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport"}; @@ -219,7 +219,7 @@ TEST_F(BugreportTest, OkNDevice) { .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")), WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; @@ -235,7 +235,7 @@ TEST_F(BugreportTest, OkNDeviceSplitBuffer) { WithArg<2>(WriteOnStdout("/bugreport.zip")), WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; @@ -271,7 +271,7 @@ TEST_F(BugreportTest, OkProgress) { WithArg<2>(ReturnCallbackDone()))); // clang-format on EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; @@ -302,7 +302,7 @@ TEST_F(BugreportTest, OkProgressAlwaysForward) { WithArg<2>(ReturnCallbackDone()))); // clang-format on EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; @@ -325,7 +325,7 @@ TEST_F(BugreportTest, OkProgressZeroPercentIsNotIgnored) { WithArg<2>(ReturnCallbackDone()))); // clang-format on EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file.zip"}; @@ -344,7 +344,7 @@ TEST_F(BugreportTest, OkDirectory) { WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")), WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), - true, StrEq("pulling da_bugreport.zip"))) + false, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", td.path}; @@ -358,7 +358,7 @@ TEST_F(BugreportTest, OkNoExtension) { .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip\n")), WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, StrEq("pulling file.zip"))) + false, StrEq("pulling file.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", "file"}; @@ -377,7 +377,7 @@ TEST_F(BugreportTest, OkNDeviceDirectory) { WithArg<2>(WriteOnStdout("OK:/device/da_bugreport.zip")), WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file), - true, StrEq("pulling da_bugreport.zip"))) + false, StrEq("pulling da_bugreport.zip"))) .WillOnce(Return(true)); const char* args[] = {"bugreport", td.path}; @@ -458,7 +458,7 @@ TEST_F(BugreportTest, PullFails) { .WillOnce(DoAll(WithArg<2>(WriteOnStdout("OK:/device/bugreport.zip")), WithArg<2>(ReturnCallbackDone()))); EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"), - true, HasSubstr("file.zip"))) + false, HasSubstr("file.zip"))) .WillOnce(Return(false)); const char* args[] = {"bugreport", "file.zip"}; From f0a4fb6ea516e895ee6740cb192e7fa16f539892 Mon Sep 17 00:00:00 2001 From: Huihong Luo Date: Thu, 17 Aug 2017 15:23:08 -0700 Subject: [PATCH 120/129] Fix bug #37284906, adb shell crashes on windows with invalid options. For example, "adb.exe shell -list" crashes without this fix. Test: adb.exe shell -list-packages Bug: 67320882 Change-Id: I96be44128ff3ecab7804b70074cbde630b3fc3d1 (cherry picked from commit af39885c9fec7faeca393e2dc54ff8b4bba3ca6c) --- adb/commandline.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/adb/commandline.cpp b/adb/commandline.cpp index 9fac61cdd..9f234737b 100644 --- a/adb/commandline.cpp +++ b/adb/commandline.cpp @@ -686,6 +686,10 @@ static int adb_shell(int argc, const char** argv) { // Parse shell-specific command-line options. argv[0] = "adb shell"; // So getopt(3) error messages start "adb shell". +#ifdef _WIN32 + // fixes "adb shell -l" crash on Windows, b/37284906 + __argv = const_cast(argv); +#endif optind = 1; // argv[0] is always "shell", so set `optind` appropriately. int opt; while ((opt = getopt(argc, const_cast(argv), "+e:ntTx")) != -1) { From e3585684d93710cefb59dd410de0c6c07f804c60 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Tue, 12 Sep 2017 13:23:33 -0700 Subject: [PATCH 121/129] adb: reformat comments. Bug: 67320882 Test: none Change-Id: Ib484f701f66cdb57f303dbd6d5eb2e5a15abdc0e (cherry picked from commit 55c8b34f144ab37f0e8a9df4b2399b74f155408f) --- adb/socket.h | 105 +++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 53 deletions(-) diff --git a/adb/socket.h b/adb/socket.h index 4acdf4a6d..64d05a92a 100644 --- a/adb/socket.h +++ b/adb/socket.h @@ -19,84 +19,83 @@ #include +#include + #include "fdevent.h" struct apacket; class atransport; /* An asocket represents one half of a connection between a local and -** remote entity. A local asocket is bound to a file descriptor. A -** remote asocket is bound to the protocol engine. -*/ + * remote entity. A local asocket is bound to a file descriptor. A + * remote asocket is bound to the protocol engine. + */ struct asocket { - /* chain pointers for the local/remote list of - ** asockets that this asocket lives in - */ - asocket *next; - asocket *prev; + /* chain pointers for the local/remote list of + * asockets that this asocket lives in + */ + asocket* next; + asocket* prev; - /* the unique identifier for this asocket - */ + /* the unique identifier for this asocket + */ unsigned id; - /* flag: set when the socket's peer has closed - ** but packets are still queued for delivery - */ - int closing; + /* flag: set when the socket's peer has closed + * but packets are still queued for delivery + */ + int closing; // flag: set when the socket failed to write, so the socket will not wait to // write packets and close directly. bool has_write_error; - /* flag: quit adbd when both ends close the - ** local service socket - */ - int exit_on_close; + /* flag: quit adbd when both ends close the + * local service socket + */ + int exit_on_close; - /* the asocket we are connected to - */ + // the asocket we are connected to + asocket* peer; - asocket *peer; - - /* For local asockets, the fde is used to bind - ** us to our fd event system. For remote asockets - ** these fields are not used. - */ + /* For local asockets, the fde is used to bind + * us to our fd event system. For remote asockets + * these fields are not used. + */ fdevent fde; int fd; - /* queue of apackets waiting to be written - */ - apacket *pkt_first; - apacket *pkt_last; + // queue of apackets waiting to be written + apacket* pkt_first; + apacket* pkt_last; - /* enqueue is called by our peer when it has data - ** for us. It should return 0 if we can accept more - ** data or 1 if not. If we return 1, we must call - ** peer->ready() when we once again are ready to - ** receive data. - */ - int (*enqueue)(asocket *s, apacket *pkt); + /* enqueue is called by our peer when it has data + * for us. It should return 0 if we can accept more + * data or 1 if not. If we return 1, we must call + * peer->ready() when we once again are ready to + * receive data. + */ + int (*enqueue)(asocket* s, apacket* pkt); - /* ready is called by the peer when it is ready for - ** us to send data via enqueue again - */ - void (*ready)(asocket *s); + /* ready is called by the peer when it is ready for + * us to send data via enqueue again + */ + void (*ready)(asocket* s); - /* shutdown is called by the peer before it goes away. - ** the socket should not do any further calls on its peer. - ** Always followed by a call to close. Optional, i.e. can be NULL. - */ - void (*shutdown)(asocket *s); + /* shutdown is called by the peer before it goes away. + * the socket should not do any further calls on its peer. + * Always followed by a call to close. Optional, i.e. can be NULL. + */ + void (*shutdown)(asocket* s); - /* close is called by the peer when it has gone away. - ** we are not allowed to make any further calls on the - ** peer once our close method is called. - */ - void (*close)(asocket *s); + /* close is called by the peer when it has gone away. + * we are not allowed to make any further calls on the + * peer once our close method is called. + */ + void (*close)(asocket* s); - /* A socket is bound to atransport */ - atransport *transport; + /* A socket is bound to atransport */ + atransport* transport; size_t get_max_payload() const; }; From 59dc0ecaaa3409e1b5510d15a0b753289880613d Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 13 Sep 2017 14:51:23 -0700 Subject: [PATCH 122/129] adb: partially revert b5e11415. Revert the write_msg_lock part of commit b5e11415. A write which hangs will hold onto the mutex, preventing the device kick from ever happening, which also causes lots of other stuff to hang, due to Kick being called with the transport lock taken. Bug: 67320882 Test: python test_devices.py Change-Id: Ie7c958799c93cad287c32d6bbef30c07f40c2d51 (cherry picked from commit 33d14b874844b21b4f14e25c5234c96fab7baeb3) --- adb/test_device.py | 4 ++-- adb/transport.cpp | 8 -------- adb/transport.h | 1 - 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/adb/test_device.py b/adb/test_device.py index 9e1a2ec2d..ddceda9d9 100644 --- a/adb/test_device.py +++ b/adb/test_device.py @@ -1237,7 +1237,7 @@ class DeviceOfflineTest(DeviceTest): return m.group(2) return None - def test_killed_when_pushing_a_large_file(self): + def disabled_test_killed_when_pushing_a_large_file(self): """ While running adb push with a large file, kill adb server. Occasionally the device becomes offline. Because the device is still @@ -1268,7 +1268,7 @@ class DeviceOfflineTest(DeviceTest): # 4. The device should be online self.assertEqual(self._get_device_state(serialno), 'device') - def test_killed_when_pulling_a_large_file(self): + def disabled_test_killed_when_pulling_a_large_file(self): """ While running adb pull with a large file, kill adb server. Occasionally the device can't be connected. Because the device is trying to diff --git a/adb/transport.cpp b/adb/transport.cpp index 3cfb3f330..c39756130 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -746,9 +746,6 @@ atransport* acquire_one_transport(TransportType type, const char* serial, Transp } int atransport::Write(apacket* p) { -#if ADB_HOST - std::lock_guard lock(write_msg_lock_); -#endif return write_func_(p, this); } @@ -756,11 +753,6 @@ void atransport::Kick() { if (!kicked_) { kicked_ = true; CHECK(kick_func_ != nullptr); -#if ADB_HOST - // On host, adb server should avoid writing part of a packet, so don't - // kick a transport whiling writing a packet. - std::lock_guard lock(write_msg_lock_); -#endif kick_func_(this); } } diff --git a/adb/transport.h b/adb/transport.h index dee27e16f..e7062da5f 100644 --- a/adb/transport.h +++ b/adb/transport.h @@ -181,7 +181,6 @@ private: std::atomic connection_state_; #if ADB_HOST std::deque> keys_; - std::mutex write_msg_lock_; bool has_send_connect_on_error_ = false; #endif From 85366c15d4e45f453835f2261020acedf6b51bab Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 7 Jun 2017 12:11:19 -0700 Subject: [PATCH 123/129] adb: remove SendConnectOnHost. This logic appears to be racy, and it shouldn't actually be needed, if our devices follow the USB spec. Use libusb_set_interface_alt_setting on device initialization as well, to add one more thing that should reset the data toggles. Bug: 67320882 Bug: http://b/32952319 Test: python test_device.py Change-Id: I392198af3d72c524b893e5056afa2b4617cea49c (cherry picked from commit 4b5d4da6f6a863638c8100cde5af834a83ac8956) --- adb/adb.cpp | 15 +-------------- adb/adb.h | 3 --- adb/client/usb_libusb.cpp | 7 +++++++ adb/transport.cpp | 7 ------- adb/transport.h | 2 -- adb/transport_usb.cpp | 10 +--------- 6 files changed, 9 insertions(+), 35 deletions(-) diff --git a/adb/adb.cpp b/adb/adb.cpp index 8c24bbba3..6b30be884 100644 --- a/adb/adb.cpp +++ b/adb/adb.cpp @@ -257,19 +257,6 @@ void send_connect(atransport* t) { send_packet(cp, t); } -#if ADB_HOST - -void SendConnectOnHost(atransport* t) { - // Send an empty message before A_CNXN message. This is because the data toggle of the ep_out on - // host and ep_in on device may not be the same. - apacket* p = get_apacket(); - CHECK(p); - send_packet(p, t); - send_connect(t); -} - -#endif - // qual_overwrite is used to overwrite a qualifier string. dst is a // pointer to a char pointer. It is assumed that if *dst is non-NULL, it // was malloc'ed and needs to freed. *dst will be set to a dup of src. @@ -370,7 +357,7 @@ void handle_packet(apacket *p, atransport *t) if (p->msg.arg0){ send_packet(p, t); #if ADB_HOST - SendConnectOnHost(t); + send_connect(t); #endif } else { t->SetConnectionState(kCsOffline); diff --git a/adb/adb.h b/adb/adb.h index 88e13b69b..98e26046c 100644 --- a/adb/adb.h +++ b/adb/adb.h @@ -225,9 +225,6 @@ void handle_online(atransport *t); void handle_offline(atransport *t); void send_connect(atransport *t); -#if ADB_HOST -void SendConnectOnHost(atransport* t); -#endif void parse_banner(const std::string&, atransport* t); diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp index 7025f283c..81201995a 100644 --- a/adb/client/usb_libusb.cpp +++ b/adb/client/usb_libusb.cpp @@ -333,6 +333,13 @@ static void process_device(libusb_device* device) { return; } + rc = libusb_set_interface_alt_setting(handle.get(), interface_num, 0); + if (rc != 0) { + LOG(WARNING) << "failed to set interface alt setting for device '" << device_serial + << "'" << libusb_error_name(rc); + return; + } + for (uint8_t endpoint : {bulk_in, bulk_out}) { rc = libusb_clear_halt(handle.get(), endpoint); if (rc != 0) { diff --git a/adb/transport.cpp b/adb/transport.cpp index c39756130..c6448931c 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -1099,11 +1099,4 @@ std::shared_ptr atransport::NextKey() { keys_.pop_front(); return result; } -bool atransport::SetSendConnectOnError() { - if (has_send_connect_on_error_) { - return false; - } - has_send_connect_on_error_ = true; - return true; -} #endif diff --git a/adb/transport.h b/adb/transport.h index e7062da5f..0f1a1d4be 100644 --- a/adb/transport.h +++ b/adb/transport.h @@ -122,7 +122,6 @@ class atransport { #if ADB_HOST std::shared_ptr NextKey(); - bool SetSendConnectOnError(); #endif char token[TOKEN_SIZE] = {}; @@ -181,7 +180,6 @@ private: std::atomic connection_state_; #if ADB_HOST std::deque> keys_; - bool has_send_connect_on_error_ = false; #endif DISALLOW_COPY_AND_ASSIGN(atransport); diff --git a/adb/transport_usb.cpp b/adb/transport_usb.cpp index 7e8ae67c4..e5845f018 100644 --- a/adb/transport_usb.cpp +++ b/adb/transport_usb.cpp @@ -103,13 +103,6 @@ static int remote_read(apacket* p, atransport* t) { err_msg: p->msg.command = 0; - if (t->GetConnectionState() == kCsOffline) { - // If the data toggle of ep_out on device and ep_in on host are not the same, we may receive - // an error message. In this case, resend one A_CNXN message to connect the device. - if (t->SetSendConnectOnError()) { - SendConnectOnHost(t); - } - } return 0; } @@ -162,8 +155,7 @@ static int remote_write(apacket *p, atransport *t) return 0; } -static void remote_close(atransport *t) -{ +static void remote_close(atransport* t) { usb_close(t->usb); t->usb = 0; } From 6e39c88b1e4ea00e76e0d66e764a63b5d8c883fc Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Thu, 14 Sep 2017 10:41:28 +0100 Subject: [PATCH 124/129] Fix full-eng build breakage due to dbacd826a100f2c. This wasn't caught by treehugger since it doesn't build this target. Test: make Test: zip_archive_test Bug: 64211847 Change-Id: Iee6e133e236ed639f944e4b8c3c8102cf22e46bb Merged-In: I275e7c4da05ceeb20401b560c72294f29ef63642 --- libziparchive/zip_archive_test.cc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc index 89eb496cc..1cb4a8a8d 100644 --- a/libziparchive/zip_archive_test.cc +++ b/libziparchive/zip_archive_test.cc @@ -540,7 +540,7 @@ TEST(ziparchive, ExtractToFile) { // Manual changes : // [2] = 0xff // Corrupt the LFH signature of entry 0. // [3] = 0xff // Corrupt the LFH signature of entry 0. -static const std::vector kZipFileWithBrokenLfhSignature{ +static const uint8_t kZipFileWithBrokenLfhSignature[] = { //[lfh-sig-----------], [lfh contents--------------------------------- 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, //-------------------------------------------------------------------- @@ -571,12 +571,16 @@ static const std::vector kZipFileWithBrokenLfhSignature{ 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; TEST(ziparchive, BrokenLfhSignature) { - TemporaryFile tmp_file; - ASSERT_NE(-1, tmp_file.fd); - ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0], - kZipFileWithBrokenLfhSignature.size())); + char kTempFilePattern[] = "zip_archive_input_XXXXXX"; + int fd = make_temporary_file(kTempFilePattern); + ASSERT_NE(-1, fd); + + ASSERT_EQ(static_cast(sizeof(kZipFileWithBrokenLfhSignature)), + TEMP_FAILURE_RETRY(write(fd, kZipFileWithBrokenLfhSignature, + sizeof(kZipFileWithBrokenLfhSignature)))); ZipArchiveHandle handle; - ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle)); + ASSERT_EQ(-1, OpenArchiveFd(fd, "LeadingNonZipBytes", &handle)); + close(fd); } int main(int argc, char** argv) { From d5715c5d2de0a92e1b5c1feb9f19ecfe361e291f Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Wed, 4 Oct 2017 18:23:09 +0100 Subject: [PATCH 125/129] Revert "Fix full-eng build breakage due to dbacd826a100f2c." This reverts commit 6e39c88b1e4ea00e76e0d66e764a63b5d8c883fc. This change should not have automerged to nyc-dev. Still investigating why that's the case. Test: make --- libziparchive/zip_archive_test.cc | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc index 46ca67ec5..b8db6a4d3 100644 --- a/libziparchive/zip_archive_test.cc +++ b/libziparchive/zip_archive_test.cc @@ -613,7 +613,7 @@ TEST(ziparchive, StreamUncompressedBadCrc) { // Manual changes : // [2] = 0xff // Corrupt the LFH signature of entry 0. // [3] = 0xff // Corrupt the LFH signature of entry 0. -static const uint8_t kZipFileWithBrokenLfhSignature[] = { +static const std::vector kZipFileWithBrokenLfhSignature{ //[lfh-sig-----------], [lfh contents--------------------------------- 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, //-------------------------------------------------------------------- @@ -644,16 +644,12 @@ static const uint8_t kZipFileWithBrokenLfhSignature[] = { 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; TEST(ziparchive, BrokenLfhSignature) { - char kTempFilePattern[] = "zip_archive_input_XXXXXX"; - int fd = make_temporary_file(kTempFilePattern); - ASSERT_NE(-1, fd); - - ASSERT_EQ(static_cast(sizeof(kZipFileWithBrokenLfhSignature)), - TEMP_FAILURE_RETRY(write(fd, kZipFileWithBrokenLfhSignature, - sizeof(kZipFileWithBrokenLfhSignature)))); + TemporaryFile tmp_file; + ASSERT_NE(-1, tmp_file.fd); + ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0], + kZipFileWithBrokenLfhSignature.size())); ZipArchiveHandle handle; - ASSERT_EQ(-1, OpenArchiveFd(fd, "LeadingNonZipBytes", &handle)); - close(fd); + ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle)); } int main(int argc, char** argv) { From bf141af6bee50fdb577bd6e238fb4a2f7ae8e5d1 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 25 Sep 2017 10:55:39 -0700 Subject: [PATCH 126/129] init/reboot: call MNT_FORCE at the last umount(2) The last one will avoid errors=panic in ext4. Bug: 63981945 Bug: 65481582 Change-Id: I9c86afcce441767e24fc43668ab1ff6230155a9f Merged-In: I9c86afcce441767e24fc43668ab1ff6230155a9f Signed-off-by: Jaegeuk Kim (cherry picked from commit 0f04f72c2de2f5c42e62f23306bc106dddcdabb1) --- init/reboot.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/init/reboot.cpp b/init/reboot.cpp index 17e3576a7..5c7ddf185 100644 --- a/init/reboot.cpp +++ b/init/reboot.cpp @@ -84,8 +84,8 @@ class MountEntry { mnt_type_(entry.mnt_type), mnt_opts_(entry.mnt_opts) {} - bool Umount() { - int r = umount2(mnt_dir_.c_str(), 0); + bool Umount(bool force) { + int r = umount2(mnt_dir_.c_str(), force ? MNT_FORCE : 0); if (r == 0) { LOG(INFO) << "umounted " << mnt_fsname_ << ":" << mnt_dir_ << " opts " << mnt_opts_; return true; @@ -287,11 +287,11 @@ static UmountStat UmountPartitions(std::chrono::milliseconds timeout) { } if (emulated_devices.size() > 0 && std::all_of(emulated_devices.begin(), emulated_devices.end(), - [](auto& entry) { return entry.Umount(); })) { + [](auto& entry) { return entry.Umount(false); })) { sync(); } for (auto& entry : block_devices) { - entry.Umount(); + entry.Umount(timeout == 0ms); } retry++; std::this_thread::sleep_for(100ms); From 56a336136dc336c13f917c94acd75570d77d0e2a Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Fri, 6 Oct 2017 14:30:08 -0700 Subject: [PATCH 127/129] libmetricslogger: Fix the out-of-sync proto IDs for boot reason. Long-term fix is to generate from proto directly. b/65625014 Bug: 67508816 Test: None Change-Id: Ifa671fa5d3816807836fd18cd66a12a7caebb5a1 (cherry picked from commit f01dbc30ef94a63eed7069fb6fdd0571c540805f) --- libmetricslogger/include/metricslogger/metrics_logger.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libmetricslogger/include/metricslogger/metrics_logger.h b/libmetricslogger/include/metricslogger/metrics_logger.h index fcabcc941..189bc4b63 100644 --- a/libmetricslogger/include/metricslogger/metrics_logger.h +++ b/libmetricslogger/include/metricslogger/metrics_logger.h @@ -42,8 +42,8 @@ enum { LOGBUILDER_COUNTER = 803, LOGBUILDER_HISTOGRAM = 804, - ACTION_BOOT = 1092, - FIELD_PLATFORM_REASON = 1093, + ACTION_BOOT = 1098, + FIELD_PLATFORM_REASON = 1099, }; enum { From c956b182e5c977103565a05543e549a03b3e40f1 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Mon, 26 Jun 2017 13:52:06 -0700 Subject: [PATCH 128/129] libutils: liblog export headers - make liblog dependency for all library builds (this is required for files like String8.cpp) - export liblog headers (because they are used in many header files). Test: less libraries fail with BOARD_VNDK_VERSION := current Merged-In: Iecb9cd00deb3a9056ea63c4a087afdb80a51a2b8 Change-Id: Iecb9cd00deb3a9056ea63c4a087afdb80a51a2b8 (cherry picked from commit 43e20cac7b0f0fac603999cdb9516929b3f758dd) --- libutils/Android.bp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libutils/Android.bp b/libutils/Android.bp index b7e397e43..540c445d0 100644 --- a/libutils/Android.bp +++ b/libutils/Android.bp @@ -82,6 +82,13 @@ cc_library { "libutils_headers", ], + shared_libs: [ + "liblog", + ], + export_shared_lib_headers: [ + "liblog", + ], + arch: { mips: { cflags: ["-DALIGN_DOUBLE"], @@ -102,7 +109,6 @@ cc_library { "libbacktrace", "libcutils", "libdl", - "liblog", "libvndksupport", ], From 0567c0e386cfdd5eb0de0594ac27c19f33bd9ec2 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Mon, 10 Jul 2017 16:40:36 -0700 Subject: [PATCH 129/129] Add vendor_available to liblog_headers. Renamed NDK headers to "liblog_ndk_headers" (these names aren't used anywhere). libutils_headers now properly export liblog_headers. Test: with BOARD_VNDK_VERSION=current Merged-In: I3a85385f588b84393c57fd6d1bcac620f708f0f1 Change-Id: I3a85385f588b84393c57fd6d1bcac620f708f0f1 (cherry picked from commit 42b485cc538217fa127996a340229f76b7c4031b) --- liblog/Android.bp | 23 +++++++++++++++++++++-- libutils/Android.bp | 5 ++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/liblog/Android.bp b/liblog/Android.bp index 6584c952d..d5bb29ed0 100644 --- a/liblog/Android.bp +++ b/liblog/Android.bp @@ -42,6 +42,24 @@ liblog_target_sources = [ "logd_writer.c", ] +cc_library_headers { + name: "liblog_headers", + host_supported: true, + vendor_available: true, + export_include_dirs: ["include"], + target: { + windows: { + enabled: true, + }, + linux_bionic: { + enabled: true, + }, + vendor: { + export_include_dirs: ["include_vndk"], + }, + }, +} + // Shared and static library for host and device // ======================================================== cc_library { @@ -78,7 +96,8 @@ cc_library { }, }, - export_include_dirs: ["include"], + header_libs: ["liblog_headers"], + export_header_lib_headers: ["liblog_headers"], cflags: [ "-Werror", @@ -97,7 +116,7 @@ cc_library { } ndk_headers { - name: "liblog_headers", + name: "liblog_ndk_headers", from: "include/android", to: "android", srcs: ["include/android/log.h"], diff --git a/libutils/Android.bp b/libutils/Android.bp index 540c445d0..1bf5a64ff 100644 --- a/libutils/Android.bp +++ b/libutils/Android.bp @@ -18,10 +18,12 @@ cc_library_headers { host_supported: true, header_libs: [ + "liblog_headers", "libsystem_headers", "libcutils_headers" ], export_header_lib_headers: [ + "liblog_headers", "libsystem_headers", "libcutils_headers" ], @@ -85,9 +87,6 @@ cc_library { shared_libs: [ "liblog", ], - export_shared_lib_headers: [ - "liblog", - ], arch: { mips: {