Respect namespace mnt

This fixes the regression of aosp/2153354.
SwitchToMountNamespaceIfNeeded() is supposed to switch between "default"
mount namespace and "bootstrap" mount namespace. But it shouldn't affect
services with its own mount namespace.

Bug: 239882455
Test: make a hal service start in a separate mount namespace
    using 'namespace mnt' in its definition.
    see the mount namespace of the service process
    $ cat /proc/$(pgrep -f myservice)/ns/mnt
Change-Id: I8c80eaec723241c405f48980b9e88640123c43ad
This commit is contained in:
Jooyung Han 2022-07-23 01:41:18 +09:00
parent 6a058f492c
commit 5eb441caca

View file

@ -190,15 +190,33 @@ bool SetupMountNamespaces() {
return success;
}
// Switch the mount namespace of the current process from bootstrap to default OR from default to
// bootstrap. If the current mount namespace is neither bootstrap nor default, keep it that way.
Result<void> SwitchToMountNamespaceIfNeeded(MountNamespace target_mount_namespace) {
if (IsRecoveryMode() || !IsApexUpdatable()) {
// we don't have multiple namespaces in recovery mode or if apex is not updatable
return {};
}
const auto& ns_id = target_mount_namespace == NS_BOOTSTRAP ? bootstrap_ns_id : default_ns_id;
const std::string current_namespace_id = GetMountNamespaceId();
MountNamespace current_mount_namespace;
if (current_namespace_id == bootstrap_ns_id) {
current_mount_namespace = NS_BOOTSTRAP;
} else if (current_namespace_id == default_ns_id) {
current_mount_namespace = NS_DEFAULT;
} else {
// services with `namespace mnt` start in its own mount namespace. So we need to keep it.
return {};
}
// We're already in the target mount namespace.
if (current_mount_namespace == target_mount_namespace) {
return {};
}
const auto& ns_fd = target_mount_namespace == NS_BOOTSTRAP ? bootstrap_ns_fd : default_ns_fd;
const auto& ns_name = target_mount_namespace == NS_BOOTSTRAP ? "bootstrap" : "default";
if (ns_id != GetMountNamespaceId() && ns_fd.get() != -1) {
if (ns_fd.get() != -1) {
if (setns(ns_fd.get(), CLONE_NEWNS) == -1) {
return ErrnoError() << "Failed to switch to " << ns_name << " mount namespace.";
}