From a8d8434c42b27f0186be7ecd78c2acc9d459b068 Mon Sep 17 00:00:00 2001 From: Paul Lawrence Date: Mon, 14 Nov 2016 15:40:18 -0800 Subject: [PATCH] Add flags to restorecon_recursive to traverse filesystems Use to solve the problem of tracefs conditionally being mounted under debugfs and needing restorecon'd without boot performance penalty. Also move skip-ce to a flag for consistency. Test: Check that trace_mount has correct attributes after boot Bug: 32849675 Change-Id: Ib6731f502b6afc393ea5ada96fa95b339f14da49 --- init/builtins.cpp | 53 ++++++++++++++++++++++++++++----------- init/devices.cpp | 2 +- init/init.cpp | 4 +-- init/property_service.cpp | 3 ++- init/util.cpp | 15 ++--------- init/util.h | 4 +-- rootdir/init.rc | 9 +++---- 7 files changed, 50 insertions(+), 40 deletions(-) diff --git a/init/builtins.cpp b/init/builtins.cpp index 08b591b5c..20d4d3ab8 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -40,6 +40,7 @@ #include +#include #include #include @@ -904,25 +905,49 @@ static int do_chmod(const std::vector& args) { static int do_restorecon(const std::vector& args) { int ret = 0; - for (auto it = std::next(args.begin()); it != args.end(); ++it) { - if (restorecon(it->c_str()) < 0) - ret = -errno; + struct flag_type {const char* name; int value;}; + static const flag_type flags[] = { + {"--recursive", SELINUX_ANDROID_RESTORECON_RECURSE}, + {"--skip-ce", SELINUX_ANDROID_RESTORECON_SKIPCE}, + {"--cross-filesystems", SELINUX_ANDROID_RESTORECON_CROSS_FILESYSTEMS}, + {0, 0} + }; + + int flag = 0; + + bool in_flags = true; + for (size_t i = 1; i < args.size(); ++i) { + if (android::base::StartsWith(args[i], "--")) { + if (!in_flags) { + LOG(ERROR) << "restorecon - flags must precede paths"; + return -1; + } + bool found = false; + for (size_t j = 0; flags[j].name; ++j) { + if (args[i] == flags[j].name) { + flag |= flags[j].value; + found = true; + break; + } + } + if (!found) { + LOG(ERROR) << "restorecon - bad flag " << args[i]; + return -1; + } + } else { + in_flags = false; + if (restorecon(args[i].c_str(), flag) < 0) { + ret = -errno; + } + } } return ret; } static int do_restorecon_recursive(const std::vector& args) { - int ret = 0; - - for (auto it = std::next(args.begin()); it != args.end(); ++it) { - /* The contents of CE paths are encrypted on FBE devices until user - * credentials are presented (filenames inside are mangled), so we need - * to delay restorecon of those until vold explicitly requests it. */ - if (restorecon_recursive_skipce(it->c_str()) < 0) { - ret = -errno; - } - } - return ret; + std::vector non_const_args(args); + non_const_args.insert(std::next(non_const_args.begin()), "--recursive"); + return do_restorecon(non_const_args); } static int do_loglevel(const std::vector& args) { diff --git a/init/devices.cpp b/init/devices.cpp index 2452c1d39..2db24b700 100644 --- a/init/devices.cpp +++ b/init/devices.cpp @@ -190,7 +190,7 @@ static void fixup_sys_perms(const char* upath, const char* subsystem) { if (access(path.c_str(), F_OK) == 0) { LOG(VERBOSE) << "restorecon_recursive: " << path; - restorecon_recursive(path.c_str()); + restorecon(path.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE); } } diff --git a/init/init.cpp b/init/init.cpp index cbd46bf07..4efcc34db 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -657,8 +657,8 @@ int main(int argc, char** argv) { restorecon("/dev/socket"); restorecon("/dev/__properties__"); restorecon("/property_contexts"); - restorecon_recursive("/sys"); - restorecon_recursive("/dev/block"); + restorecon("/sys", SELINUX_ANDROID_RESTORECON_RECURSE); + restorecon("/dev/block", SELINUX_ANDROID_RESTORECON_RECURSE); restorecon("/dev/device-mapper"); epoll_fd = epoll_create1(EPOLL_CLOEXEC); diff --git a/init/property_service.cpp b/init/property_service.cpp index e7176c628..e19829765 100644 --- a/init/property_service.cpp +++ b/init/property_service.cpp @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -175,7 +176,7 @@ static int property_set_impl(const char* name, const char* value) { if (valuelen >= PROP_VALUE_MAX) return -1; if (strcmp("selinux.restorecon_recursive", name) == 0 && valuelen > 0) { - if (restorecon_recursive(value) != 0) { + if (restorecon(value, SELINUX_ANDROID_RESTORECON_RECURSE) != 0) { LOG(ERROR) << "Failed to restorecon_recursive " << value; } } diff --git a/init/util.cpp b/init/util.cpp index 65b238b29..5205ea094 100644 --- a/init/util.cpp +++ b/init/util.cpp @@ -369,20 +369,9 @@ int make_dir(const char *path, mode_t mode) return rc; } -int restorecon(const char* pathname) +int restorecon(const char* pathname, int flags) { - return selinux_android_restorecon(pathname, 0); -} - -int restorecon_recursive(const char* pathname) -{ - return selinux_android_restorecon(pathname, SELINUX_ANDROID_RESTORECON_RECURSE); -} - -int restorecon_recursive_skipce(const char* pathname) -{ - return selinux_android_restorecon(pathname, - SELINUX_ANDROID_RESTORECON_RECURSE | SELINUX_ANDROID_RESTORECON_SKIPCE); + return selinux_android_restorecon(pathname, flags); } /* diff --git a/init/util.h b/init/util.h index ef40748cb..d56da39b5 100644 --- a/init/util.h +++ b/init/util.h @@ -68,9 +68,7 @@ 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); -int restorecon(const char *pathname); -int restorecon_recursive(const char *pathname); -int restorecon_recursive_skipce(const char *pathname); +int restorecon(const char *pathname, int flags = 0); 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/rootdir/init.rc b/rootdir/init.rc index 4e766bbde..fb531787c 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -293,11 +293,8 @@ on post-fs mount none /mnt/runtime/default /storage slave bind rec # Make sure /sys/kernel/debug (if present) is labeled properly - restorecon_recursive /sys/kernel/debug - - # On systems with tracefs, tracing is a separate mount, so make sure - # it too is correctly labeled - restorecon_recursive /sys/kernel/debug/tracing + # Note that tracefs may be mounted under debug, so we need to cross filesystems + restorecon --recursive --cross-filesystems /sys/kernel/debug # We chown/chmod /cache again so because mount is run as root + defaults chown system cache /cache @@ -462,7 +459,7 @@ on post-fs-data init_user0 # Set SELinux security contexts on upgrade or policy update. - restorecon_recursive /data + restorecon --recursive --skip-ce /data # Check any timezone data in /data is newer than the copy in /system, delete if not. exec - system system -- /system/bin/tzdatacheck /system/usr/share/zoneinfo /data/misc/zoneinfo