From 312db1aa1dc7bff133d95c92efcc5e42b57cefa6 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:39 +0100 Subject: fs: add ksys_mount() helper; remove in-kernel calls to sys_mount() Using this helper allows us to avoid the in-kernel calls to the sys_mount() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_mount(). In the near future, all callers of ksys_mount() should be converted to call do_mount() directly. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: Alexander Viro Signed-off-by: Dominik Brodowski --- drivers/base/devtmpfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/base/devtmpfs.c') diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 50025d7959cb..4afb04686c8e 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -356,7 +356,8 @@ int devtmpfs_mount(const char *mntdir) if (!thread) return 0; - err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL); + err = ksys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, + NULL); if (err) printk(KERN_INFO "devtmpfs: error mounting %i\n", err); else @@ -382,7 +383,7 @@ static int devtmpfsd(void *p) *err = sys_unshare(CLONE_NEWNS); if (*err) goto out; - *err = sys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); + *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); if (*err) goto out; sys_chdir("/.."); /* will traverse into overmounted root */ -- cgit v1.2.3 From a16fe33ab5572e52ef4cb9719d6eb49623b2528a Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:41 +0100 Subject: fs: add ksys_chroot() helper; remove-in kernel calls to sys_chroot() Using this helper allows us to avoid the in-kernel calls to the sys_chroot() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_chroot(). In the near future, the fs-external callers of ksys_chroot() should be converted to use kern_path()/set_fs_root() directly. Then ksys_chroot() can be moved within sys_chroot() again. This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: Alexander Viro Signed-off-by: Dominik Brodowski --- drivers/base/devtmpfs.c | 2 +- fs/open.c | 7 ++++++- include/linux/syscalls.h | 1 + init/do_mounts.c | 2 +- init/do_mounts_initrd.c | 4 ++-- 5 files changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers/base/devtmpfs.c') diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 4afb04686c8e..5743f04014ca 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -387,7 +387,7 @@ static int devtmpfsd(void *p) if (*err) goto out; sys_chdir("/.."); /* will traverse into overmounted root */ - sys_chroot("."); + ksys_chroot("."); complete(&setup_done); while (1) { spin_lock(&req_lock); diff --git a/fs/open.c b/fs/open.c index 7ea118471dce..7a475e8a2e41 100644 --- a/fs/open.c +++ b/fs/open.c @@ -479,7 +479,7 @@ out: return error; } -SYSCALL_DEFINE1(chroot, const char __user *, filename) +int ksys_chroot(const char __user *filename) { struct path path; int error; @@ -512,6 +512,11 @@ out: return error; } +SYSCALL_DEFINE1(chroot, const char __user *, filename) +{ + return ksys_chroot(filename); +} + static int chmod_common(const struct path *path, umode_t mode) { struct inode *inode = path->dentry->d_inode; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 50876ae1d17b..920a0db1871d 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -950,5 +950,6 @@ int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, unsigned long flags, void __user *data); int ksys_umount(char __user *name, int flags); int ksys_dup(unsigned int fildes); +int ksys_chroot(const char __user *filename); #endif diff --git a/init/do_mounts.c b/init/do_mounts.c index eb768de43d84..2f06f7827b0c 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -600,7 +600,7 @@ void __init prepare_namespace(void) out: devtmpfs_mount("dev"); ksys_mount(".", "/", NULL, MS_MOVE, NULL); - sys_chroot("."); + ksys_chroot("."); } static bool is_tmpfs; diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index e8573e1776f6..71293265ac4b 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -44,7 +44,7 @@ static int init_linuxrc(struct subprocess_info *info, struct cred *new) /* move initrd over / and chdir/chroot in initrd root */ sys_chdir("/root"); ksys_mount(".", "/", NULL, MS_MOVE, NULL); - sys_chroot("."); + ksys_chroot("."); sys_setsid(); return 0; } @@ -83,7 +83,7 @@ static void __init handle_initrd(void) /* move initrd to rootfs' /old */ ksys_mount("..", ".", NULL, MS_MOVE, NULL); /* switch root and cwd back to / of rootfs */ - sys_chroot(".."); + ksys_chroot(".."); if (new_decode_dev(real_root_dev) == Root_RAM0) { sys_chdir("/old"); -- cgit v1.2.3 From 447016e9681965fda8dcd9e4fd3c55308a6fd166 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:46 +0100 Subject: fs: add ksys_chdir() helper; remove in-kernel calls to sys_chdir() Using this helper allows us to avoid the in-kernel calls to the sys_chdir() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_chdir(). This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: Al Viro Cc: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/base/devtmpfs.c | 2 +- fs/open.c | 7 ++++++- include/linux/syscalls.h | 1 + init/do_mounts.c | 2 +- init/do_mounts_initrd.c | 8 ++++---- 5 files changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers/base/devtmpfs.c') diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 5743f04014ca..3f7ee954fd2c 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -386,7 +386,7 @@ static int devtmpfsd(void *p) *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); if (*err) goto out; - sys_chdir("/.."); /* will traverse into overmounted root */ + ksys_chdir("/.."); /* will traverse into overmounted root */ ksys_chroot("."); complete(&setup_done); while (1) { diff --git a/fs/open.c b/fs/open.c index 7a475e8a2e41..a19b8277c439 100644 --- a/fs/open.c +++ b/fs/open.c @@ -431,7 +431,7 @@ SYSCALL_DEFINE2(access, const char __user *, filename, int, mode) return sys_faccessat(AT_FDCWD, filename, mode); } -SYSCALL_DEFINE1(chdir, const char __user *, filename) +int ksys_chdir(const char __user *filename) { struct path path; int error; @@ -457,6 +457,11 @@ out: return error; } +SYSCALL_DEFINE1(chdir, const char __user *, filename) +{ + return ksys_chdir(filename); +} + SYSCALL_DEFINE1(fchdir, unsigned int, fd) { struct fd f = fdget_raw(fd); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 80524faa9664..090645b48447 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -952,5 +952,6 @@ int ksys_umount(char __user *name, int flags); int ksys_dup(unsigned int fildes); int ksys_chroot(const char __user *filename); ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count); +int ksys_chdir(const char __user *filename); #endif diff --git a/init/do_mounts.c b/init/do_mounts.c index 2f06f7827b0c..89f18985fa90 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -367,7 +367,7 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data) if (err) return err; - sys_chdir("/root"); + ksys_chdir("/root"); s = current->fs->pwd.dentry->d_sb; ROOT_DEV = s->s_dev; printk(KERN_INFO diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 71293265ac4b..83f396d30b9a 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -42,7 +42,7 @@ static int init_linuxrc(struct subprocess_info *info, struct cred *new) ksys_dup(0); ksys_dup(0); /* move initrd over / and chdir/chroot in initrd root */ - sys_chdir("/root"); + ksys_chdir("/root"); ksys_mount(".", "/", NULL, MS_MOVE, NULL); ksys_chroot("."); sys_setsid(); @@ -61,7 +61,7 @@ static void __init handle_initrd(void) /* mount initrd on rootfs' /root */ mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY); sys_mkdir("/old", 0700); - sys_chdir("/old"); + ksys_chdir("/old"); /* try loading default modules from initrd */ load_default_modules(); @@ -86,11 +86,11 @@ static void __init handle_initrd(void) ksys_chroot(".."); if (new_decode_dev(real_root_dev) == Root_RAM0) { - sys_chdir("/old"); + ksys_chdir("/old"); return; } - sys_chdir("/"); + ksys_chdir("/"); ROOT_DEV = new_decode_dev(real_root_dev); mount_root(); -- cgit v1.2.3 From 9b32105ec6b13d32d5db6a6e7992c97ce54b5ea7 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 11 Mar 2018 11:34:42 +0100 Subject: kernel: add ksys_unshare() helper; remove in-kernel calls to sys_unshare() Using this helper allows us to avoid the in-kernel calls to the sys_unshare() syscall. The ksys_ prefix denotes that this function is meant as a drop-in replacement for the syscall. In particular, it uses the same calling convention as sys_unshare(). This patch is part of a series which removes in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. For details, see http://lkml.kernel.org/r/20180325162527.GA17492@light.dominikbrodowski.net Cc: Al Viro Cc: Andrew Morton Cc: Ingo Molnar Signed-off-by: Dominik Brodowski --- drivers/base/devtmpfs.c | 2 +- include/linux/syscalls.h | 1 + init/do_mounts_initrd.c | 2 +- kernel/fork.c | 7 ++++++- 4 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers/base/devtmpfs.c') diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 3f7ee954fd2c..f7768077e817 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -380,7 +380,7 @@ static int devtmpfsd(void *p) { char options[] = "mode=0755"; int *err = p; - *err = sys_unshare(CLONE_NEWNS); + *err = ksys_unshare(CLONE_NEWNS); if (*err) goto out; *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 0a9942b3e718..e724dda509e0 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -961,6 +961,7 @@ int ksys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); off_t ksys_lseek(unsigned int fd, off_t offset, unsigned int whence); ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count); void ksys_sync(void); +int ksys_unshare(unsigned long unshare_flags); /* * The following kernel syscall equivalents are just wrappers to fs-internal diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 03ec0c1b7553..d1d3e53bdeef 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -36,7 +36,7 @@ __setup("noinitrd", no_initrd); static int init_linuxrc(struct subprocess_info *info, struct cred *new) { - sys_unshare(CLONE_FS | CLONE_FILES); + ksys_unshare(CLONE_FS | CLONE_FILES); /* stdin/stdout/stderr for /linuxrc */ ksys_open("/dev/console", O_RDWR, 0); ksys_dup(0); diff --git a/kernel/fork.c b/kernel/fork.c index b1e031aac9db..f71b67dc156d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -2354,7 +2354,7 @@ static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp * constructed. Here we are modifying the current, active, * task_struct. */ -SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) +int ksys_unshare(unsigned long unshare_flags) { struct fs_struct *fs, *new_fs = NULL; struct files_struct *fd, *new_fd = NULL; @@ -2470,6 +2470,11 @@ bad_unshare_out: return err; } +SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) +{ + return ksys_unshare(unshare_flags); +} + /* * Helper to unshare the files of the current task. * We don't want to expose copy_files internals to -- cgit v1.2.3