Skip to content

Commit

Permalink
Fix mount permission issue
Browse files Browse the repository at this point in the history
Signed-off-by: Umer Saleem <[email protected]>
  • Loading branch information
usaleem-ix committed Sep 18, 2024
1 parent eecb1bc commit 6443426
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 3 deletions.
4 changes: 2 additions & 2 deletions contrib/initramfs/scripts/zfs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ mount_fs()

# Need the _original_ datasets mountpoint!
mountpoint=$(get_fs_value "$fs" mountpoint)
ZFS_CMD="mount -o zfsutil -t zfs"
ZFS_CMD="mount.zfs -o zfsutil"
if [ "$mountpoint" = "legacy" ] || [ "$mountpoint" = "none" ]; then
# Can't use the mountpoint property. Might be one of our
# clones. Check the 'org.zol:mountpoint' property set in
Expand All @@ -362,7 +362,7 @@ mount_fs()
fi
# Don't use mount.zfs -o zfsutils for legacy mountpoint
if [ "$mountpoint" = "legacy" ]; then
ZFS_CMD="mount -t zfs"
ZFS_CMD="mount.zfs"
fi
# Last hail-mary: Hope 'rootmnt' is set!
mountpoint=""
Expand Down
75 changes: 74 additions & 1 deletion module/os/linux/zfs/zfs_ctldir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,61 @@ exportfs_flush(void)
(void) call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
}

static int
get_current_root_path(char *buff, int len)
{
struct path path;
char *path_buffer, *path_ptr;
int path_len, error = 0;

get_fs_root(current->fs, &path);
path_get(&path);

path_buffer = kmem_zalloc(len, KM_SLEEP);

path_ptr = d_path(&path, path_buffer, len);
if (IS_ERR(path_ptr)) {
error = -PTR_ERR(path_ptr);
goto out;
}

path_len = path_buffer + len - 1 - path_ptr;
if (path_len > len) {
error = SET_ERROR(EFAULT);
goto out;
}

memcpy(buff, path_ptr, path_len);
buff[path_len] = '\0';
out:
kmem_free(path_buffer, len);
path_put(&path);
return (error);
}

static int
is_current_chrooted(void)
{
struct task_struct *curr = current, *global = &init_task;
struct path gl_root;
struct path cr_root;
int chrooted;

get_fs_root(global->fs, &gl_root);
path_get(&gl_root);
while (d_mountpoint(gl_root.dentry) && follow_down_one(&gl_root))
;

get_fs_root(curr->fs, &cr_root);
path_get(&cr_root);
chrooted = !path_equal(&cr_root, &gl_root);

path_put(&cr_root);
path_put(&gl_root);

return (chrooted);
}

/*
* Attempt to unmount a snapshot by making a call to user space.
* There is no assurance that this can or will succeed, is just a
Expand Down Expand Up @@ -1100,7 +1155,7 @@ zfsctl_snapshot_mount(struct path *path, int flags)
zfsvfs_t *zfsvfs;
zfsvfs_t *snap_zfsvfs;
zfs_snapentry_t *se;
char *full_name, *full_path;
char *full_name, *full_path, *root_path;
char *argv[] = { "/usr/bin/env", "mount", "-i", "-t", "zfs", "-n",
NULL, NULL, NULL };
char *envp[] = { NULL };
Expand All @@ -1116,12 +1171,30 @@ zfsctl_snapshot_mount(struct path *path, int flags)

full_name = kmem_zalloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
full_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
root_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);

error = zfsctl_snapshot_name(zfsvfs, dname(dentry),
ZFS_MAX_DATASET_NAME_LEN, full_name);
if (error)
goto error;

if (get_current_root_path(root_path, MAXPATHLEN) == 0) {
if (is_current_chrooted() == 0) {
zfs_dbgmsg("current process is not chrooted");
if (zfsvfs->z_vfs->vfs_mntpoint != NULL &&
strcmp(zfsvfs->z_vfs->vfs_mntpoint, "/root") == 0 &&
strcmp(root_path, "/") == 0) {
zfs_dbgmsg("zfsvfs->z_vfs->vfs_mntpoint is /root");

Check failure on line 1187 in module/os/linux/zfs/zfs_ctldir.c

View workflow job for this annotation

GitHub Actions / checkstyle

line > 80 characters
zfs_dbgmsg("d_path returns / for current fs root");

Check failure on line 1188 in module/os/linux/zfs/zfs_ctldir.c

View workflow job for this annotation

GitHub Actions / checkstyle

line > 80 characters
zfs_dbgmsg("this is propbably root filesystem");
zfs_dbgmsg("setting zfsvfs->z_vfs->vfs_mntpoint to /");

Check failure on line 1190 in module/os/linux/zfs/zfs_ctldir.c

View workflow job for this annotation

GitHub Actions / checkstyle

line > 80 characters
strcpy(zfsvfs->z_vfs->vfs_mntpoint, "");
}
} else if (is_current_chrooted()) {
zfs_dbgmsg("Current process is in chroot context");
}
}

/*
* Construct a mount point path from sb of the ctldir inode and dirent
* name, instead of from d_path(), so that chroot'd process doesn't fail
Expand Down

0 comments on commit 6443426

Please sign in to comment.