Bind mount lower filesystem during FUSE mount

When mounting a FUSE device on /mnt/user/<userid>/<vol>,
bind mount the correspoinding lower filesystem path to
/mnt/pass_through/<userid>/<vol>. At Zygote fork time, an
app with the right privilege will have the pass_through path
bind mounted into /storage instead of the /mnt/user path.

This provides such an app direct access to the lower filesystem
without going through FUSE.

Bug: 140064376
Test: mount(8) shows /mnt/pass_through/0/emulated is a bind
mount of the lower fs

Change-Id: I32c3cad64138910fcec9fb8f66b206706b5fd139
gugelfrei
Zim 5 years ago
parent e94ef6b04d
commit 981222f500

@ -487,6 +487,9 @@ int VolumeManager::remountUid(uid_t uid, int32_t mountMode) {
case VoldNativeService::REMOUNT_MODE_FULL:
mode = "full";
break;
case VoldNativeService::REMOUNT_MODE_PASS_THROUGH:
mode = "pass_through";
break;
default:
PLOG(ERROR) << "Unknown mode " << std::to_string(mountMode);
return -1;

@ -157,6 +157,7 @@ interface IVold {
const int REMOUNT_MODE_LEGACY = 4;
const int REMOUNT_MODE_INSTALLER = 5;
const int REMOUNT_MODE_FULL = 6;
const int REMOUNT_MODE_PASS_THROUGH = 7;
const int VOLUME_STATE_UNMOUNTED = 0;
const int VOLUME_STATE_CHECKING = 1;

@ -89,13 +89,18 @@ status_t EmulatedVolume::doMount() {
if (isFuse) {
LOG(INFO) << "Mounting emulated fuse volume";
android::base::unique_fd fd;
int result = MountUserFuse(getMountUserId(), label, &fd);
int user_id = getMountUserId();
int result = MountUserFuse(user_id, label, &fd);
if (result != 0) {
PLOG(ERROR) << "Failed to mount emulated fuse volume";
return -result;
}
setFuseFd(std::move(fd));
return OK;
std::string pass_through_path(StringPrintf("/mnt/pass_through/%d/%s",
user_id, label.c_str()));
return BindMount(getInternalPath(), pass_through_path);
}
if (!(mFusePid = fork())) {

@ -174,13 +174,18 @@ status_t PublicVolume::doMount() {
if (isFuse) {
LOG(INFO) << "Mounting public fuse volume";
android::base::unique_fd fd;
int result = MountUserFuse(getMountUserId(), stableName, &fd);
int user_id = getMountUserId();
int result = MountUserFuse(user_id, stableName, &fd);
if (result != 0) {
LOG(ERROR) << "Failed to mount public fuse volume";
return -result;
}
setFuseFd(std::move(fd));
return OK;
std::string pass_through_path(StringPrintf("/mnt/pass_through/%d/%s",
user_id, stableName.c_str()));
return BindMount(getInternalPath(), pass_through_path);
}
if (!(mFusePid = fork())) {

Loading…
Cancel
Save