diff --git a/Android.bp b/Android.bp index ac4eb59..dca801e 100644 --- a/Android.bp +++ b/Android.bp @@ -152,6 +152,9 @@ cc_library_static { shared_libs: [ "android.hardware.health.storage@1.0", ], + whole_static_libs: [ + "com.android.sysprop.apex", + ], } cc_binary { diff --git a/VolumeManager.cpp b/VolumeManager.cpp index ce2d935..51eec8a 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -33,6 +33,7 @@ #include +#include #include #include #include @@ -432,6 +433,8 @@ int VolumeManager::remountUid(uid_t uid, const std::string& mode) { struct stat sb; pid_t child; + static bool apexUpdatable = android::sysprop::ApexProperties::updatable().value_or(false); + if (!(dir = opendir("/proc"))) { PLOG(ERROR) << "Failed to opendir"; return -1; @@ -476,6 +479,26 @@ int VolumeManager::remountUid(uid_t uid, const std::string& mode) { goto next; } + if (apexUpdatable) { + std::string exeName; + // When ro.apex.bionic_updatable is set to true, + // some early native processes have mount namespaces that are different + // from that of the init. Therefore, above check can't filter them out. + // Since the propagation type of / is 'shared', unmounting /storage + // for the early native processes affects other processes including + // init. Filter out such processes by skipping if a process is a + // non-Java process whose UID is < AID_APP_START. (The UID condition + // is required to not filter out child processes spawned by apps.) + if (!android::vold::Readlinkat(pidFd, "exe", &exeName)) { + PLOG(WARNING) << "Failed to read exe name for " << de->d_name; + goto next; + } + if (!StartsWith(exeName, "/system/bin/app_process") && sb.st_uid < AID_APP_START) { + LOG(WARNING) << "Skipping due to native system process"; + goto next; + } + } + // We purposefully leave the namespace open across the fork nsFd = openat(pidFd, "ns/mnt", O_RDONLY); // not O_CLOEXEC if (nsFd < 0) {