Don't create separate mount namespaces for pre-apexd processes

It is causing problem to the sdcardfs. Specifically, re-mounting events
for /mnt/runtime/{runtime|write} done by the vold process (which is a
pre-apexd process) are not being propagated to other mount namespaces.
As a result, SDCard access isn't working.

The propagation problem is a bug in sdcardfs which is fixed by [1].
However, we can't make all Android devices to have the patch at the same
time. Therefore, by default the separate mount namespace is not created
and will be created only for the devices where the kernel patches are in and
ro.apex.bionic_updatable sysprop is set to true.

[1]
d73d07673edbdbe78e1a7d00e7827ba9bfd86a59 ("ANDROID: mnt: Fix next_descendent")
b5858221c1c4f4bdc9ef67eb75ecf22580368820 ("ANDROID: mnt: remount should propagate to slaves of slaves")

Bug: 122559956
Test: m
Test: device boots
Test: sdcard works (e.g. camera can take pictures)
Test: atest android.appsecurity.cts.ExternalStorageHostTest
Change-Id: I7a309bab46356ee5782f34c5963d1760963c0b14
This commit is contained in:
Jiyong Park 2019-01-09 13:40:25 +09:00
parent 3fa8415b37
commit 5ab1300481

View file

@ -990,7 +990,18 @@ Result<Success> Service::Start() {
LOG(FATAL) << "Service '" << name_ << "' could not enter namespaces: " << result.error();
}
if (pre_apexd_) {
// b/122559956: mount namespace is not cloned for the devices that don't support
// the update of bionic libraries via APEX. In that case, because the bionic
// libraries in the runtime APEX and the bootstrap bionic libraries are
// identical, it doesn't matter which libs are used. This is also to avoid the
// bug in sdcardfs which is triggered when we have multiple mount namespaces
// across vold and the others. BIONIC_UPDATABLE shall be true only for the
// devices where kernel has the fix for the sdcardfs bug (see the commit message
// for the fix).
static bool bionic_updatable =
android::base::GetBoolProperty("ro.apex.bionic_updatable", false);
if (bionic_updatable && pre_apexd_) {
// pre-apexd process gets a private copy of the mount namespace.
// However, this does not mean that mount/unmount events are not
// shared across pre-apexd processes and post-apexd processes.
@ -1017,7 +1028,8 @@ Result<Success> Service::Start() {
}
}
if (pre_apexd_ && ServiceList::GetInstance().IsRuntimeAvailable()) {
// b/122559956: same as above
if (bionic_updatable && pre_apexd_ && ServiceList::GetInstance().IsRuntimeAvailable()) {
if (auto result = SetUpPreApexdMounts(); !result) {
LOG(FATAL) << "Pre-apexd service '" << name_
<< "' could not setup the mount points: " << result.error();