diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-02-14 22:45:31 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-02-14 22:45:31 +0000 |
commit | e5005b3ab90dd61f6c9a59b7e93406e838edfe4a (patch) | |
tree | 0fe5012e262a64b731e9ad784daacb6ba3c72761 | |
parent | f992cf1cfb893a39fe7b4455b136ff2fe655dd0d (diff) | |
parent | c0c59c6244381f2ed369e47c18a94d4a43d0c0b2 (diff) | |
download | core-android12-mainline-adbd-release.tar.gz |
Snap for 8183220 from c0c59c6244381f2ed369e47c18a94d4a43d0c0b2 to mainline-adbd-releaseandroid-mainline-12.0.0_r97android-mainline-12.0.0_r85android12-mainline-adbd-release
Change-Id: Ibfb4bfddc2708a469715ddf06fda3e82bc748975
-rw-r--r-- | init/init.cpp | 15 | ||||
-rw-r--r-- | libcutils/Android.bp | 3 | ||||
-rw-r--r-- | libcutils/canned_fs_config.cpp | 165 | ||||
-rw-r--r-- | rootdir/init.rc | 16 |
4 files changed, 117 insertions, 82 deletions
diff --git a/init/init.cpp b/init/init.cpp index a7325cad9..942feb939 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -27,6 +27,7 @@ #include <sys/mount.h> #include <sys/signalfd.h> #include <sys/types.h> +#include <sys/utsname.h> #include <unistd.h> #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ @@ -554,6 +555,19 @@ static void SetUsbController() { } } +/// Set ro.kernel.version property to contain the major.minor pair as returned +/// by uname(2). +static void SetKernelVersion() { + struct utsname uts; + unsigned int major, minor; + + if ((uname(&uts) != 0) || (sscanf(uts.release, "%u.%u", &major, &minor) != 2)) { + LOG(ERROR) << "Could not parse the kernel version from uname"; + return; + } + SetProperty("ro.kernel.version", android::base::StringPrintf("%u.%u", major, minor)); +} + static void HandleSigtermSignal(const signalfd_siginfo& siginfo) { if (siginfo.ssi_pid != 0) { // Drop any userspace SIGTERM requests. @@ -824,6 +838,7 @@ int SecondStageMain(int argc, char** argv) { export_oem_lock_status(); MountHandler mount_handler(&epoll); SetUsbController(); + SetKernelVersion(); const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap(); Action::set_function_map(&function_map); diff --git a/libcutils/Android.bp b/libcutils/Android.bp index 68b21c6a0..f1333ddd1 100644 --- a/libcutils/Android.bp +++ b/libcutils/Android.bp @@ -156,7 +156,6 @@ cc_library { }, srcs: [ "config_utils.cpp", - "canned_fs_config.cpp", "iosched_policy.cpp", "load_file.cpp", "native_handle.cpp", @@ -173,6 +172,7 @@ cc_library { not_windows: { srcs: libcutils_nonwindows_sources + [ "ashmem-host.cpp", + "canned_fs_config.cpp", "fs_config.cpp", "trace-host.cpp", ], @@ -193,6 +193,7 @@ cc_library { srcs: libcutils_nonwindows_sources + [ "android_reboot.cpp", "ashmem-dev.cpp", + "canned_fs_config.cpp", "fs_config.cpp", "klog.cpp", "partition_utils.cpp", diff --git a/libcutils/canned_fs_config.cpp b/libcutils/canned_fs_config.cpp index 2772ef0e9..b677949ad 100644 --- a/libcutils/canned_fs_config.cpp +++ b/libcutils/canned_fs_config.cpp @@ -18,6 +18,8 @@ #include <private/canned_fs_config.h> #include <private/fs_config.h> +#include <android-base/strings.h> + #include <errno.h> #include <inttypes.h> #include <limits.h> @@ -25,104 +27,107 @@ #include <stdlib.h> #include <string.h> -typedef struct { - const char* path; +#include <algorithm> +#include <fstream> +#include <iostream> +#include <string> +#include <vector> + +using android::base::ConsumePrefix; +using android::base::StartsWith; +using android::base::Tokenize; + +struct Entry { + std::string path; unsigned uid; unsigned gid; unsigned mode; uint64_t capabilities; -} Path; +}; -static Path* canned_data = NULL; -static int canned_alloc = 0; -static int canned_used = 0; - -static int path_compare(const void* a, const void* b) { - return strcmp(((Path*)a)->path, ((Path*)b)->path); -} +static std::vector<Entry> canned_data; int load_canned_fs_config(const char* fn) { - char buf[PATH_MAX + 200]; - FILE* f; - - f = fopen(fn, "r"); - if (f == NULL) { - fprintf(stderr, "failed to open %s: %s\n", fn, strerror(errno)); - return -1; - } - - while (fgets(buf, sizeof(buf), f)) { - Path* p; - char* token; - char* line = buf; - bool rootdir; + std::ifstream input(fn); + for (std::string line; std::getline(input, line);) { + // Historical: the root dir can be represented as a space character. + // e.g. " 1000 1000 0755" is parsed as + // path = " ", uid = 1000, gid = 1000, mode = 0755. + // But at the same time, we also have accepted + // "/ 1000 1000 0755". + if (StartsWith(line, " ")) { + line.insert(line.begin(), '/'); + } - while (canned_used >= canned_alloc) { - canned_alloc = (canned_alloc+1) * 2; - canned_data = (Path*) realloc(canned_data, canned_alloc * sizeof(Path)); + std::vector<std::string> tokens = Tokenize(line, " "); + if (tokens.size() < 4) { + std::cerr << "Ill-formed line: " << line << " in " << fn << std::endl; + return -1; } - p = canned_data + canned_used; - if (line[0] == '/') line++; - rootdir = line[0] == ' '; - p->path = strdup(rootdir ? "" : strtok(line, " ")); - p->uid = atoi(strtok(rootdir ? line : NULL, " ")); - p->gid = atoi(strtok(NULL, " ")); - p->mode = strtol(strtok(NULL, " "), NULL, 8); // mode is in octal - p->capabilities = 0; - - do { - token = strtok(NULL, " "); - if (token && strncmp(token, "capabilities=", 13) == 0) { - p->capabilities = strtoll(token+13, NULL, 0); + + // Historical: remove the leading '/' if exists. + std::string path(tokens[0].front() == '/' ? std::string(tokens[0], 1) : tokens[0]); + + Entry e{ + .path = std::move(path), + .uid = static_cast<unsigned int>(atoi(tokens[1].c_str())), + .gid = static_cast<unsigned int>(atoi(tokens[2].c_str())), + // mode is in octal + .mode = static_cast<unsigned int>(strtol(tokens[3].c_str(), nullptr, 8)), + .capabilities = 0, + }; + + for (size_t i = 4; i < tokens.size(); i++) { + std::string_view sv = tokens[i]; + if (ConsumePrefix(&sv, "capabilities=")) { + e.capabilities = strtoll(std::string(sv).c_str(), nullptr, 0); break; } - } while (token); + // Historical: there can be tokens like "selabel=..." here. They have been ignored. + // It's not an error because selabels are applied separately in e2fsdroid using the + // file_contexts files set via -S option. + std::cerr << "info: ignored token \"" << sv << "\" in " << fn << std::endl; + } - canned_used++; + canned_data.emplace_back(std::move(e)); } - fclose(f); - - qsort(canned_data, canned_used, sizeof(Path), path_compare); - printf("loaded %d fs_config entries\n", canned_used); - + // Note: we used to sort the entries by path names. This was to improve the lookup performance + // by doing binary search. However, this is no longer the case. The lookup performance is not + // critical because this tool runs on the host, not on the device. Now, there can be multiple + // entries for the same path. Then the one that comes the last wins. This is to allow overriding + // platform provided fs_config with a user provided fs_config by appending the latter to the + // former. + // + // To implement the strategy, reverse the entries order, and search from the top. + std::reverse(canned_data.begin(), canned_data.end()); + + std::cout << "loaded " << canned_data.size() << " fs_config entries" << std::endl; return 0; } -static const int kDebugCannedFsConfig = 0; - -void canned_fs_config(const char* path, int dir, const char* target_out_path, - unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities) { - Path key, *p; +void canned_fs_config(const char* path, [[maybe_unused]] int dir, + [[maybe_unused]] const char* target_out_path, unsigned* uid, unsigned* gid, + unsigned* mode, uint64_t* capabilities) { + if (path != nullptr && path[0] == '/') path++; // canned paths lack the leading '/' + + const Entry* found = nullptr; + // canned_data is already reversed. First match wins. + for (const auto& entry : canned_data) { + if (path == entry.path) { + found = &entry; + break; + } + continue; + } - key.path = path; - if (path[0] == '/') key.path++; // canned paths lack the leading '/' - p = (Path*) bsearch(&key, canned_data, canned_used, sizeof(Path), path_compare); - if (p == NULL) { - fprintf(stderr, "failed to find [%s] in canned fs_config\n", path); + if (found == nullptr) { + std::cerr << "failed to find " << path << " in canned fs_config" << std::endl; exit(1); } - *uid = p->uid; - *gid = p->gid; - *mode = p->mode; - *capabilities = p->capabilities; - - if (kDebugCannedFsConfig) { - // for debugging, run the built-in fs_config and compare the results. - - unsigned c_uid, c_gid, c_mode; - uint64_t c_capabilities; - - fs_config(path, dir, target_out_path, &c_uid, &c_gid, &c_mode, &c_capabilities); - - if (c_uid != *uid) printf("%s uid %d %d\n", path, *uid, c_uid); - if (c_gid != *gid) printf("%s gid %d %d\n", path, *gid, c_gid); - if (c_mode != *mode) printf("%s mode 0%o 0%o\n", path, *mode, c_mode); - if (c_capabilities != *capabilities) { - printf("%s capabilities %" PRIx64 " %" PRIx64 "\n", - path, - *capabilities, - c_capabilities); - } - } + + *uid = found->uid; + *gid = found->gid; + *mode = found->mode; + *capabilities = found->capabilities; } diff --git a/rootdir/init.rc b/rootdir/init.rc index 376a678a8..451595092 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -590,9 +590,23 @@ on late-fs # Load trusted keys from dm-verity protected partitions exec -- /system/bin/fsverity_init --load-verified-keys +# Only enable the bootreceiver tracing instance for kernels 5.10 and above. +on late-fs && property:ro.kernel.version=4.9 + setprop bootreceiver.enable 0 +on late-fs && property:ro.kernel.version=4.14 + setprop bootreceiver.enable 0 +on late-fs && property:ro.kernel.version=4.19 + setprop bootreceiver.enable 0 +on late-fs && property:ro.kernel.version=5.4 + setprop bootreceiver.enable 0 +on late-fs + # Bootreceiver tracing instance is enabled by default. + setprop bootreceiver.enable ${bootreceiver.enable:-1} + +on property:ro.product.cpu.abilist64=* && property:bootreceiver.enable=1 # Set up a tracing instance for system_server to monitor error_report_end events. # These are sent by kernel tools like KASAN and KFENCE when a memory corruption - # is detected. + # is detected. This is only needed for 64-bit systems. mkdir /sys/kernel/tracing/instances/bootreceiver 0700 system system restorecon_recursive /sys/kernel/tracing/instances/bootreceiver write /sys/kernel/tracing/instances/bootreceiver/buffer_size_kb 1 |