From f72d88aedf164ef39e4af38a48d28dcfd5e51632 Mon Sep 17 00:00:00 2001 From: Yi-Yo Chiang Date: Mon, 22 Mar 2021 13:45:39 +0800 Subject: Make DSU metadata files globally readable libfstab (fs_mgr_fstab.cpp) could be statically linked into unpriviledged processes, and calling fs_mgr_fstab.cpp:ReadFstabFromFile() from an unpriviledged process while inside of a DSU system would return an incorrect Fstab, because ReadFstabFromFile() needs to read the DSU metadata files to return the correct result. To remedy this, we make DSU metadata files that are required by libfstab to be globally readable (0644). We also split the sepolicy label gsi_metadata_filea into two part, gsi_metadata_file and gsi_public_metadata_file, and make gsi_public_metadata_file:file readable by other domain (not banned by neverallow). Bug: 181110285 Test: Write a small utility program to validate the result of ReadFstabFromFile() in DSU. Change-Id: Ia7c8c584b23752195198cc43698c71a31cabc00e --- Android.bp | 1 + daemon.cpp | 3 +++ gsi_service.cpp | 13 +++++++++++++ gsid.rc | 3 +++ include/libgsi/libgsi.h | 8 ++++++++ 5 files changed, 28 insertions(+) diff --git a/Android.bp b/Android.bp index 6a7cf06..6b0f829 100644 --- a/Android.bp +++ b/Android.bp @@ -101,6 +101,7 @@ cc_binary { "libgsi", "libgsid", "liblp", + "libselinux", "libutils", "libc++fs", "libvold_binder", diff --git a/daemon.cpp b/daemon.cpp index ca2995d..a1ee809 100644 --- a/daemon.cpp +++ b/daemon.cpp @@ -49,6 +49,9 @@ static int DumpDeviceMapper() { int main(int argc, char** argv) { android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM)); + // Create globally readable files. + umask(0022); + if (argc > 1) { if (argv[1] == "run-startup-tasks"s) { android::gsi::GsiService::RunStartupTasks(); diff --git a/gsi_service.cpp b/gsi_service.cpp index 002c51f..939f603 100644 --- a/gsi_service.cpp +++ b/gsi_service.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include "file_paths.h" @@ -71,6 +72,16 @@ static constexpr int64_t kDefaultUserdataSize = int64_t(2) * 1024 * 1024 * 1024; static bool GetAvbPublicKeyFromFd(int fd, AvbPublicKey* dst); +// Fix the file contexts of dsu metadata files. +// By default, newly created files inherit the file contexts of their parent +// directory. Since globally readable public metadata files are labeled with a +// different context, gsi_public_metadata_file, we need to call this function to +// fix their contexts after creating them. +static void RestoreconMetadataFiles() { + auto flags = SELINUX_ANDROID_RESTORECON_RECURSE | SELINUX_ANDROID_RESTORECON_SKIP_SEHASH; + selinux_android_restorecon(DSU_METADATA_PREFIX, flags); +} + GsiService::GsiService() { progress_ = {}; } @@ -185,6 +196,7 @@ binder::Status GsiService::createPartition(const ::std::string& name, int64_t si *_aidl_return = INSTALL_ERROR_GENERIC; return binder::Status::ok(); } + RestoreconMetadataFiles(); } installer_ = std::make_unique(this, install_dir_, name, @@ -297,6 +309,7 @@ binder::Status GsiService::enableGsi(bool one_shot, const std::string& dsuSlot, *_aidl_return = INSTALL_ERROR_GENERIC; return binder::Status::ok(); } + RestoreconMetadataFiles(); if (installer_) { ENFORCE_SYSTEM; installer_ = {}; diff --git a/gsid.rc b/gsid.rc index a5d6dd3..2c1a10b 100644 --- a/gsid.rc +++ b/gsid.rc @@ -10,6 +10,9 @@ on post-fs mkdir /metadata/gsi/dsu 0771 root system mkdir /metadata/gsi/ota 0771 root system mkdir /metadata/gsi/remount 0771 root system + chmod 0664 /metadata/gsi/dsu/active + chmod 0664 /metadata/gsi/dsu/booted + chmod 0664 /metadata/gsi/dsu/lp_names on post-fs-data write /data/gsi_persistent_data 0 diff --git a/include/libgsi/libgsi.h b/include/libgsi/libgsi.h index 17066ff..41898df 100644 --- a/include/libgsi/libgsi.h +++ b/include/libgsi/libgsi.h @@ -28,6 +28,14 @@ static constexpr char kGsiServiceName[] = "gsiservice"; #define DSU_METADATA_PREFIX "/metadata/gsi/dsu/" +// These files need to be globally readable so that fs_mgr_fstab, which is +// statically linked into processes, can return consistent result for non-root +// processes: +// * kDsuActiveFile +// * kGsiBootedIndicatorFile +// * kGsiLpNamesFile +// * DsuMetadataKeyDirFile(slot) + static constexpr char kGsiBootedIndicatorFile[] = DSU_METADATA_PREFIX "booted"; static constexpr char kGsiLpNamesFile[] = DSU_METADATA_PREFIX "lp_names"; -- cgit v1.2.3