Loading cmds/installd/InstalldNativeService.cpp +97 −3 Original line number Diff line number Diff line Loading @@ -756,8 +756,7 @@ binder::Status InstalldNativeService::createSdkSandboxDataPackageDirectory( const char* uuid_ = uuid ? uuid->c_str() : nullptr; constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; for (int i = 0; i < 2; i++) { int currentFlag = storageFlags[i]; for (int currentFlag : storageFlags) { if ((flags & currentFlag) == 0) { continue; } Loading Loading @@ -847,7 +846,6 @@ binder::Status InstalldNativeService::createAppDataBatched( binder::Status InstalldNativeService::reconcileSdkData( const android::os::ReconcileSdkDataArgs& args) { ENFORCE_UID(AID_SYSTEM); // Locking is performed depeer in the callstack. return reconcileSdkData(args.uuid, args.packageName, args.sdkPackageNames, args.randomSuffixes, Loading @@ -870,6 +868,7 @@ binder::Status InstalldNativeService::reconcileSdkData( const std::vector<std::string>& sdkPackageNames, const std::vector<std::string>& randomSuffixes, int userId, int appId, int previousAppId, const std::string& seInfo, int flags) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); for (const auto& sdkPackageName : sdkPackageNames) { Loading Loading @@ -1772,6 +1771,36 @@ binder::Status InstalldNativeService::moveCompleteApp(const std::optional<std::s } } // Copy sdk data for all known users for (auto userId : users) { LOCK_USER(); constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; for (int currentFlag : storageFlags) { const bool isCeData = currentFlag == FLAG_STORAGE_CE; const auto from = create_data_misc_sdk_sandbox_package_path(from_uuid, isCeData, userId, package_name); if (access(from.c_str(), F_OK) != 0) { LOG(INFO) << "Missing source " << from; continue; } const auto to = create_data_misc_sdk_sandbox_path(to_uuid, isCeData, userId); const int rc = copy_directory_recursive(from.c_str(), to.c_str()); if (rc != 0) { res = error(rc, "Failed copying " + from + " to " + to); goto fail; } } if (!restoreconSdkDataLocked(toUuid, packageName, userId, FLAG_STORAGE_CE | FLAG_STORAGE_DE, appId, seInfo) .isOk()) { res = error("Failed to restorecon"); goto fail; } } // We let the framework scan the new location and persist that before // deleting the data in the old location; this ordering ensures that // we can recover from things like battery pulls. Loading Loading @@ -1799,6 +1828,18 @@ fail: } } } for (auto userId : users) { LOCK_USER(); constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; for (int currentFlag : storageFlags) { const bool isCeData = currentFlag == FLAG_STORAGE_CE; const auto to = create_data_misc_sdk_sandbox_package_path(to_uuid, isCeData, userId, package_name); if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) { LOG(WARNING) << "Failed to rollback " << to; } } } return res; } Loading Loading @@ -1833,6 +1874,11 @@ binder::Status InstalldNativeService::destroyUserData(const std::optional<std::s if (delete_dir_contents_and_dir(path, true) != 0) { res = error("Failed to delete " + path); } auto sdk_sandbox_de_path = create_data_misc_sdk_sandbox_path(uuid_, /*isCeData=*/false, userId); if (delete_dir_contents_and_dir(sdk_sandbox_de_path, true) != 0) { res = error("Failed to delete " + sdk_sandbox_de_path); } if (uuid_ == nullptr) { path = create_data_misc_legacy_path(userId); if (delete_dir_contents_and_dir(path, true) != 0) { Loading @@ -1849,6 +1895,11 @@ binder::Status InstalldNativeService::destroyUserData(const std::optional<std::s if (delete_dir_contents_and_dir(path, true) != 0) { res = error("Failed to delete " + path); } auto sdk_sandbox_ce_path = create_data_misc_sdk_sandbox_path(uuid_, /*isCeData=*/true, userId); if (delete_dir_contents_and_dir(sdk_sandbox_ce_path, true) != 0) { res = error("Failed to delete " + sdk_sandbox_ce_path); } path = findDataMediaPath(uuid, userId); if (delete_dir_contents_and_dir(path, true) != 0) { res = error("Failed to delete " + path); Loading Loading @@ -3131,6 +3182,49 @@ binder::Status InstalldNativeService::restoreconAppDataLocked( return res; } binder::Status InstalldNativeService::restoreconSdkDataLocked( const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); binder::Status res = ok(); // SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here. unsigned int seflags = SELINUX_ANDROID_RESTORECON_RECURSE; const char* uuid_ = uuid ? uuid->c_str() : nullptr; const char* pkgName = packageName.c_str(); const char* seinfo = seInfo.c_str(); uid_t uid = multiuser_get_sdk_sandbox_uid(userId, appId); constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; for (int currentFlag : storageFlags) { if ((flags & currentFlag) == 0) { continue; } const bool isCeData = (currentFlag == FLAG_STORAGE_CE); const auto packagePath = create_data_misc_sdk_sandbox_package_path(uuid_, isCeData, userId, pkgName); if (access(packagePath.c_str(), F_OK) != 0) { LOG(INFO) << "Missing source " << packagePath; continue; } const auto subDirHandler = [&packagePath, &seinfo, &uid, &seflags, &res](const std::string& subDir) { const auto& fullpath = packagePath + "/" + subDir; if (selinux_android_restorecon_pkgdir(fullpath.c_str(), seinfo, uid, seflags) < 0) { res = error("restorecon failed for " + fullpath); } }; const auto ec = foreach_subdir(packagePath, subDirHandler); if (ec != 0) { res = error("Failed to restorecon for subdirs of " + packagePath); } } return res; } binder::Status InstalldNativeService::createOatDir(const std::string& packageName, const std::string& oatDir, const std::string& instructionSet) { Loading cmds/installd/InstalldNativeService.h +13 −9 Original line number Diff line number Diff line Loading @@ -63,9 +63,7 @@ public: binder::Status restoreconAppData(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo); binder::Status restoreconAppDataLocked(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo); binder::Status migrateAppData(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags); binder::Status clearAppData(const std::optional<std::string>& uuid, Loading Loading @@ -206,13 +204,10 @@ private: int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return); binder::Status restoreconAppDataLocked(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo); binder::Status reconcileSdkData(const std::optional<std::string>& uuid, const std::string& packageName, const std::vector<std::string>& sdkPackageNames, const std::vector<std::string>& randomSuffixes, int32_t userId, int32_t appId, int32_t previousAppId, const std::string& seInfo, int flags); binder::Status createSdkSandboxDataPackageDirectory(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t appId, Loading @@ -224,6 +219,15 @@ private: binder::Status destroySdkSandboxDataPackageDirectory(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags); binder::Status reconcileSdkData(const std::optional<std::string>& uuid, const std::string& packageName, const std::vector<std::string>& sdkPackageNames, const std::vector<std::string>& randomSuffixes, int32_t userId, int32_t appId, int32_t previousAppId, const std::string& seInfo, int flags); binder::Status restoreconSdkDataLocked(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo); }; } // namespace installd Loading cmds/installd/tests/installd_service_test.cpp +27 −12 Original line number Diff line number Diff line Loading @@ -987,7 +987,7 @@ public: args.userId = kTestUserId; args.appId = kTestAppId; args.seInfo = "default"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; return args; } Loading Loading @@ -1045,7 +1045,6 @@ private: TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); Loading Loading @@ -1082,7 +1081,6 @@ TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutSdkFlag) TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutSdkFlagDeletesExisting) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); ASSERT_TRUE(exists("/data/local/tmp/misc_ce/0/sdksandbox/com.foo")); Loading Loading @@ -1232,7 +1230,6 @@ TEST_F(DestroyAppDataTest, DestroySdkSandboxDataDirectories_WithCeAndDeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Destroy the app user data. Loading @@ -1246,7 +1243,6 @@ TEST_F(DestroyAppDataTest, DestroySdkSandboxDataDirectories_WithoutDeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Destroy the app user data. Loading @@ -1260,7 +1256,6 @@ TEST_F(DestroyAppDataTest, DestroySdkSandboxDataDirectories_WithoutCeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Destroy the app user data. Loading Loading @@ -1297,7 +1292,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndClearCacheFlag) android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1316,7 +1310,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndClearCodeCacheF android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1338,7 +1331,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndClearCacheFlag) android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1357,7 +1349,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndClearCodeCacheF android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1379,7 +1370,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndWithoutAnyCache android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1395,7 +1385,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndWithoutAnyCache android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1407,5 +1396,31 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndWithoutAnyCache ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_de/0/sdksandbox/com.foo/sdk2"))); } class DestroyUserDataTest : public SdkSandboxDataTest {}; TEST_F(DestroyUserDataTest, DestroySdkData_WithCeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Destroy user data ASSERT_BINDER_SUCCESS(service->destroyUserData(args.uuid, args.userId, FLAG_STORAGE_CE)); ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/sdksandbox")); ASSERT_TRUE(exists("/data/local/tmp/misc_de/0/sdksandbox")); } TEST_F(DestroyUserDataTest, DestroySdkData_WithDeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Destroy user data ASSERT_BINDER_SUCCESS(service->destroyUserData(args.uuid, args.userId, FLAG_STORAGE_DE)); ASSERT_TRUE(exists("/data/local/tmp/misc_ce/0/sdksandbox")); ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox")); } } // namespace installd } // namespace android libs/binder/ProcessState.cpp +25 −1 Original line number Diff line number Diff line Loading @@ -409,6 +409,28 @@ size_t ProcessState::getThreadPoolMaxThreadCount() const { return 0; } #define DRIVER_FEATURES_PATH "/dev/binderfs/features/" bool ProcessState::isDriverFeatureEnabled(const DriverFeature feature) { static const char* const names[] = { [static_cast<int>(DriverFeature::ONEWAY_SPAM_DETECTION)] = DRIVER_FEATURES_PATH "oneway_spam_detection", }; int fd = open(names[static_cast<int>(feature)], O_RDONLY | O_CLOEXEC); char on; if (fd == -1) { ALOGE_IF(errno != ENOENT, "%s: cannot open %s: %s", __func__, names[static_cast<int>(feature)], strerror(errno)); return false; } if (read(fd, &on, sizeof(on)) == -1) { ALOGE("%s: error reading to %s: %s", __func__, names[static_cast<int>(feature)], strerror(errno)); return false; } close(fd); return on == '1'; } status_t ProcessState::enableOnewaySpamDetection(bool enable) { uint32_t enableDetection = enable ? 1 : 0; if (ioctl(mDriverFD, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enableDetection) == -1) { Loading Loading @@ -452,7 +474,9 @@ static base::Result<int> open_driver(const char* driver) { uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION; result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable); if (result == -1) { ALOGV("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno)); ALOGE_IF(ProcessState::isDriverFeatureEnabled( ProcessState::DriverFeature::ONEWAY_SPAM_DETECTION), "Binder ioctl to enable oneway spam detection failed: %s", strerror(errno)); } return fd; } Loading libs/binder/include/binder/ProcessState.h +6 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,12 @@ public: */ size_t getThreadPoolMaxThreadCount() const; enum class DriverFeature { ONEWAY_SPAM_DETECTION, }; // Determine whether a feature is supported by the binder driver. static bool isDriverFeatureEnabled(const DriverFeature feature); private: static sp<ProcessState> init(const char* defaultDriver, bool requireDefault); Loading Loading
cmds/installd/InstalldNativeService.cpp +97 −3 Original line number Diff line number Diff line Loading @@ -756,8 +756,7 @@ binder::Status InstalldNativeService::createSdkSandboxDataPackageDirectory( const char* uuid_ = uuid ? uuid->c_str() : nullptr; constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; for (int i = 0; i < 2; i++) { int currentFlag = storageFlags[i]; for (int currentFlag : storageFlags) { if ((flags & currentFlag) == 0) { continue; } Loading Loading @@ -847,7 +846,6 @@ binder::Status InstalldNativeService::createAppDataBatched( binder::Status InstalldNativeService::reconcileSdkData( const android::os::ReconcileSdkDataArgs& args) { ENFORCE_UID(AID_SYSTEM); // Locking is performed depeer in the callstack. return reconcileSdkData(args.uuid, args.packageName, args.sdkPackageNames, args.randomSuffixes, Loading @@ -870,6 +868,7 @@ binder::Status InstalldNativeService::reconcileSdkData( const std::vector<std::string>& sdkPackageNames, const std::vector<std::string>& randomSuffixes, int userId, int appId, int previousAppId, const std::string& seInfo, int flags) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); for (const auto& sdkPackageName : sdkPackageNames) { Loading Loading @@ -1772,6 +1771,36 @@ binder::Status InstalldNativeService::moveCompleteApp(const std::optional<std::s } } // Copy sdk data for all known users for (auto userId : users) { LOCK_USER(); constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; for (int currentFlag : storageFlags) { const bool isCeData = currentFlag == FLAG_STORAGE_CE; const auto from = create_data_misc_sdk_sandbox_package_path(from_uuid, isCeData, userId, package_name); if (access(from.c_str(), F_OK) != 0) { LOG(INFO) << "Missing source " << from; continue; } const auto to = create_data_misc_sdk_sandbox_path(to_uuid, isCeData, userId); const int rc = copy_directory_recursive(from.c_str(), to.c_str()); if (rc != 0) { res = error(rc, "Failed copying " + from + " to " + to); goto fail; } } if (!restoreconSdkDataLocked(toUuid, packageName, userId, FLAG_STORAGE_CE | FLAG_STORAGE_DE, appId, seInfo) .isOk()) { res = error("Failed to restorecon"); goto fail; } } // We let the framework scan the new location and persist that before // deleting the data in the old location; this ordering ensures that // we can recover from things like battery pulls. Loading Loading @@ -1799,6 +1828,18 @@ fail: } } } for (auto userId : users) { LOCK_USER(); constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; for (int currentFlag : storageFlags) { const bool isCeData = currentFlag == FLAG_STORAGE_CE; const auto to = create_data_misc_sdk_sandbox_package_path(to_uuid, isCeData, userId, package_name); if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) { LOG(WARNING) << "Failed to rollback " << to; } } } return res; } Loading Loading @@ -1833,6 +1874,11 @@ binder::Status InstalldNativeService::destroyUserData(const std::optional<std::s if (delete_dir_contents_and_dir(path, true) != 0) { res = error("Failed to delete " + path); } auto sdk_sandbox_de_path = create_data_misc_sdk_sandbox_path(uuid_, /*isCeData=*/false, userId); if (delete_dir_contents_and_dir(sdk_sandbox_de_path, true) != 0) { res = error("Failed to delete " + sdk_sandbox_de_path); } if (uuid_ == nullptr) { path = create_data_misc_legacy_path(userId); if (delete_dir_contents_and_dir(path, true) != 0) { Loading @@ -1849,6 +1895,11 @@ binder::Status InstalldNativeService::destroyUserData(const std::optional<std::s if (delete_dir_contents_and_dir(path, true) != 0) { res = error("Failed to delete " + path); } auto sdk_sandbox_ce_path = create_data_misc_sdk_sandbox_path(uuid_, /*isCeData=*/true, userId); if (delete_dir_contents_and_dir(sdk_sandbox_ce_path, true) != 0) { res = error("Failed to delete " + sdk_sandbox_ce_path); } path = findDataMediaPath(uuid, userId); if (delete_dir_contents_and_dir(path, true) != 0) { res = error("Failed to delete " + path); Loading Loading @@ -3131,6 +3182,49 @@ binder::Status InstalldNativeService::restoreconAppDataLocked( return res; } binder::Status InstalldNativeService::restoreconSdkDataLocked( const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); binder::Status res = ok(); // SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here. unsigned int seflags = SELINUX_ANDROID_RESTORECON_RECURSE; const char* uuid_ = uuid ? uuid->c_str() : nullptr; const char* pkgName = packageName.c_str(); const char* seinfo = seInfo.c_str(); uid_t uid = multiuser_get_sdk_sandbox_uid(userId, appId); constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; for (int currentFlag : storageFlags) { if ((flags & currentFlag) == 0) { continue; } const bool isCeData = (currentFlag == FLAG_STORAGE_CE); const auto packagePath = create_data_misc_sdk_sandbox_package_path(uuid_, isCeData, userId, pkgName); if (access(packagePath.c_str(), F_OK) != 0) { LOG(INFO) << "Missing source " << packagePath; continue; } const auto subDirHandler = [&packagePath, &seinfo, &uid, &seflags, &res](const std::string& subDir) { const auto& fullpath = packagePath + "/" + subDir; if (selinux_android_restorecon_pkgdir(fullpath.c_str(), seinfo, uid, seflags) < 0) { res = error("restorecon failed for " + fullpath); } }; const auto ec = foreach_subdir(packagePath, subDirHandler); if (ec != 0) { res = error("Failed to restorecon for subdirs of " + packagePath); } } return res; } binder::Status InstalldNativeService::createOatDir(const std::string& packageName, const std::string& oatDir, const std::string& instructionSet) { Loading
cmds/installd/InstalldNativeService.h +13 −9 Original line number Diff line number Diff line Loading @@ -63,9 +63,7 @@ public: binder::Status restoreconAppData(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo); binder::Status restoreconAppDataLocked(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo); binder::Status migrateAppData(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags); binder::Status clearAppData(const std::optional<std::string>& uuid, Loading Loading @@ -206,13 +204,10 @@ private: int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return); binder::Status restoreconAppDataLocked(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo); binder::Status reconcileSdkData(const std::optional<std::string>& uuid, const std::string& packageName, const std::vector<std::string>& sdkPackageNames, const std::vector<std::string>& randomSuffixes, int32_t userId, int32_t appId, int32_t previousAppId, const std::string& seInfo, int flags); binder::Status createSdkSandboxDataPackageDirectory(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t appId, Loading @@ -224,6 +219,15 @@ private: binder::Status destroySdkSandboxDataPackageDirectory(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags); binder::Status reconcileSdkData(const std::optional<std::string>& uuid, const std::string& packageName, const std::vector<std::string>& sdkPackageNames, const std::vector<std::string>& randomSuffixes, int32_t userId, int32_t appId, int32_t previousAppId, const std::string& seInfo, int flags); binder::Status restoreconSdkDataLocked(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo); }; } // namespace installd Loading
cmds/installd/tests/installd_service_test.cpp +27 −12 Original line number Diff line number Diff line Loading @@ -987,7 +987,7 @@ public: args.userId = kTestUserId; args.appId = kTestAppId; args.seInfo = "default"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; return args; } Loading Loading @@ -1045,7 +1045,6 @@ private: TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkPackageData) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); Loading Loading @@ -1082,7 +1081,6 @@ TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutSdkFlag) TEST_F(SdkSandboxDataTest, CreateAppData_CreatesSdkAppLevelData_WithoutSdkFlagDeletesExisting) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); ASSERT_TRUE(exists("/data/local/tmp/misc_ce/0/sdksandbox/com.foo")); Loading Loading @@ -1232,7 +1230,6 @@ TEST_F(DestroyAppDataTest, DestroySdkSandboxDataDirectories_WithCeAndDeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Destroy the app user data. Loading @@ -1246,7 +1243,6 @@ TEST_F(DestroyAppDataTest, DestroySdkSandboxDataDirectories_WithoutDeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Destroy the app user data. Loading @@ -1260,7 +1256,6 @@ TEST_F(DestroyAppDataTest, DestroySdkSandboxDataDirectories_WithoutCeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Destroy the app user data. Loading Loading @@ -1297,7 +1292,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndClearCacheFlag) android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1316,7 +1310,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndClearCodeCacheF android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1338,7 +1331,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndClearCacheFlag) android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1357,7 +1349,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndClearCodeCacheF android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1379,7 +1370,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithCeAndWithoutAnyCache android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1395,7 +1385,6 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndWithoutAnyCache android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; args.flags = FLAG_STORAGE_CE | FLAG_STORAGE_DE | FLAG_STORAGE_SDK; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); createTestSdkData("com.foo", {"sdk1", "sdk2"}); Loading @@ -1407,5 +1396,31 @@ TEST_F(ClearAppDataTest, ClearSdkSandboxDataDirectories_WithDeAndWithoutAnyCache ASSERT_TRUE(fs::is_empty(fs::path("/data/local/tmp/misc_de/0/sdksandbox/com.foo/sdk2"))); } class DestroyUserDataTest : public SdkSandboxDataTest {}; TEST_F(DestroyUserDataTest, DestroySdkData_WithCeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Destroy user data ASSERT_BINDER_SUCCESS(service->destroyUserData(args.uuid, args.userId, FLAG_STORAGE_CE)); ASSERT_FALSE(exists("/data/local/tmp/misc_ce/0/sdksandbox")); ASSERT_TRUE(exists("/data/local/tmp/misc_de/0/sdksandbox")); } TEST_F(DestroyUserDataTest, DestroySdkData_WithDeFlag) { android::os::CreateAppDataResult result; android::os::CreateAppDataArgs args = createAppDataArgs("com.foo"); args.packageName = "com.foo"; // Create the app user data. ASSERT_BINDER_SUCCESS(service->createAppData(args, &result)); // Destroy user data ASSERT_BINDER_SUCCESS(service->destroyUserData(args.uuid, args.userId, FLAG_STORAGE_DE)); ASSERT_TRUE(exists("/data/local/tmp/misc_ce/0/sdksandbox")); ASSERT_FALSE(exists("/data/local/tmp/misc_de/0/sdksandbox")); } } // namespace installd } // namespace android
libs/binder/ProcessState.cpp +25 −1 Original line number Diff line number Diff line Loading @@ -409,6 +409,28 @@ size_t ProcessState::getThreadPoolMaxThreadCount() const { return 0; } #define DRIVER_FEATURES_PATH "/dev/binderfs/features/" bool ProcessState::isDriverFeatureEnabled(const DriverFeature feature) { static const char* const names[] = { [static_cast<int>(DriverFeature::ONEWAY_SPAM_DETECTION)] = DRIVER_FEATURES_PATH "oneway_spam_detection", }; int fd = open(names[static_cast<int>(feature)], O_RDONLY | O_CLOEXEC); char on; if (fd == -1) { ALOGE_IF(errno != ENOENT, "%s: cannot open %s: %s", __func__, names[static_cast<int>(feature)], strerror(errno)); return false; } if (read(fd, &on, sizeof(on)) == -1) { ALOGE("%s: error reading to %s: %s", __func__, names[static_cast<int>(feature)], strerror(errno)); return false; } close(fd); return on == '1'; } status_t ProcessState::enableOnewaySpamDetection(bool enable) { uint32_t enableDetection = enable ? 1 : 0; if (ioctl(mDriverFD, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enableDetection) == -1) { Loading Loading @@ -452,7 +474,9 @@ static base::Result<int> open_driver(const char* driver) { uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION; result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable); if (result == -1) { ALOGV("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno)); ALOGE_IF(ProcessState::isDriverFeatureEnabled( ProcessState::DriverFeature::ONEWAY_SPAM_DETECTION), "Binder ioctl to enable oneway spam detection failed: %s", strerror(errno)); } return fd; } Loading
libs/binder/include/binder/ProcessState.h +6 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,12 @@ public: */ size_t getThreadPoolMaxThreadCount() const; enum class DriverFeature { ONEWAY_SPAM_DETECTION, }; // Determine whether a feature is supported by the binder driver. static bool isDriverFeatureEnabled(const DriverFeature feature); private: static sp<ProcessState> init(const char* defaultDriver, bool requireDefault); Loading