Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3be2c7a1 authored by Yifan Hong's avatar Yifan Hong
Browse files

fs_mgr: overlayfs_mount_scratch don't write to system_other

This change removes this denial:
avc: denied { write } for comm="init" name="sda6" dev="tmpfs" \
    ino=25715 scontext=u:r:init:s0 tcontext=u:object_r:system_block_device:s0 \
    tclass=blk_file permissive=0

The reason is that during any mount_all in init,
fs_mgr_overlayfs_mount_all() will mount a list of candidates for
scratch, which includes system_other. However, in order to probe
if /overlay directory exist in the partition, it only needs read
access to the block device, and mount the partition as readonly.
If the block device is a true candidate (i.e. it does have /overlay),
re-mount it as writable.

Test: flash, wipe, boot, denial goes away, cppreopt is successful
Test: boot the second time, no denials (no cppreopt this time)

Fixes: 122454600

Change-Id: I465b363eac755d79711e4f82955cd98450527122
parent e7bb1b3e
Loading
Loading
Loading
Loading
+18 −7
Original line number Original line Diff line number Diff line
@@ -575,8 +575,14 @@ std::vector<std::string> fs_mgr_candidate_list(Fstab* fstab, const char* mount_p
}
}


// Mount kScratchMountPoint
// Mount kScratchMountPoint
bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::string mnt_type) {
bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::string mnt_type,
                                    bool readonly = false) {
    if (readonly) {
        if (!fs_mgr_access(device_path)) return false;
    } else {
        if (!fs_mgr_rw_access(device_path)) return false;
        if (!fs_mgr_rw_access(device_path)) return false;
    }

    if (setfscreatecon(kOverlayfsFileContext)) {
    if (setfscreatecon(kOverlayfsFileContext)) {
        PERROR << "setfscreatecon " << kOverlayfsFileContext;
        PERROR << "setfscreatecon " << kOverlayfsFileContext;
    }
    }
@@ -589,6 +595,7 @@ bool fs_mgr_overlayfs_mount_scratch(const std::string& device_path, const std::s
    entry.mount_point = kScratchMountPoint;
    entry.mount_point = kScratchMountPoint;
    entry.fs_type = mnt_type;
    entry.fs_type = mnt_type;
    entry.flags = MS_RELATIME;
    entry.flags = MS_RELATIME;
    if (readonly) entry.flags |= MS_RDONLY;
    auto save_errno = errno;
    auto save_errno = errno;
    auto mounted = fs_mgr_do_mount_one(entry) == 0;
    auto mounted = fs_mgr_do_mount_one(entry) == 0;
    if (!mounted) {
    if (!mounted) {
@@ -800,11 +807,15 @@ bool fs_mgr_overlayfs_mount_all(Fstab* fstab) {
            scratch_can_be_mounted = false;
            scratch_can_be_mounted = false;
            auto scratch_device = fs_mgr_overlayfs_scratch_device();
            auto scratch_device = fs_mgr_overlayfs_scratch_device();
            if (fs_mgr_overlayfs_scratch_can_be_mounted(scratch_device) &&
            if (fs_mgr_overlayfs_scratch_can_be_mounted(scratch_device) &&
                fs_mgr_wait_for_file(scratch_device, 10s) &&
                fs_mgr_wait_for_file(scratch_device, 10s)) {
                fs_mgr_overlayfs_mount_scratch(scratch_device,
                const auto mount_type = fs_mgr_overlayfs_scratch_mount_type();
                                               fs_mgr_overlayfs_scratch_mount_type()) &&
                if (fs_mgr_overlayfs_mount_scratch(scratch_device, mount_type,
                !fs_mgr_access(kScratchMountPoint + kOverlayTopDir)) {
                                                   true /* readonly */)) {
                    auto has_overlayfs_dir = fs_mgr_access(kScratchMountPoint + kOverlayTopDir);
                    fs_mgr_overlayfs_umount_scratch();
                    fs_mgr_overlayfs_umount_scratch();
                    if (has_overlayfs_dir)
                        fs_mgr_overlayfs_mount_scratch(scratch_device, mount_type);
                }
            }
            }
        }
        }
        if (fs_mgr_overlayfs_mount(mount_point)) ret = true;
        if (fs_mgr_overlayfs_mount(mount_point)) ret = true;