diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2018-03-11 06:34:41 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2018-04-02 14:15:50 -0400 |
commit | a16fe33ab5572e52ef4cb9719d6eb49623b2528a (patch) | |
tree | 3a917bd107f2da721eaa190dfb270c18ec7338df | |
parent | c7248321a3d42ffba78db0dde88d1c49ca1c045f (diff) |
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 <viro@zeniv.linux.org.uk>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r-- | drivers/base/devtmpfs.c | 2 | ||||
-rw-r--r-- | fs/open.c | 7 | ||||
-rw-r--r-- | include/linux/syscalls.h | 1 | ||||
-rw-r--r-- | init/do_mounts.c | 2 | ||||
-rw-r--r-- | init/do_mounts_initrd.c | 4 |
5 files changed, 11 insertions, 5 deletions
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) | |||
387 | if (*err) | 387 | if (*err) |
388 | goto out; | 388 | goto out; |
389 | sys_chdir("/.."); /* will traverse into overmounted root */ | 389 | sys_chdir("/.."); /* will traverse into overmounted root */ |
390 | sys_chroot("."); | 390 | ksys_chroot("."); |
391 | complete(&setup_done); | 391 | complete(&setup_done); |
392 | while (1) { | 392 | while (1) { |
393 | spin_lock(&req_lock); | 393 | spin_lock(&req_lock); |
@@ -479,7 +479,7 @@ out: | |||
479 | return error; | 479 | return error; |
480 | } | 480 | } |
481 | 481 | ||
482 | SYSCALL_DEFINE1(chroot, const char __user *, filename) | 482 | int ksys_chroot(const char __user *filename) |
483 | { | 483 | { |
484 | struct path path; | 484 | struct path path; |
485 | int error; | 485 | int error; |
@@ -512,6 +512,11 @@ out: | |||
512 | return error; | 512 | return error; |
513 | } | 513 | } |
514 | 514 | ||
515 | SYSCALL_DEFINE1(chroot, const char __user *, filename) | ||
516 | { | ||
517 | return ksys_chroot(filename); | ||
518 | } | ||
519 | |||
515 | static int chmod_common(const struct path *path, umode_t mode) | 520 | static int chmod_common(const struct path *path, umode_t mode) |
516 | { | 521 | { |
517 | struct inode *inode = path->dentry->d_inode; | 522 | 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, | |||
950 | unsigned long flags, void __user *data); | 950 | unsigned long flags, void __user *data); |
951 | int ksys_umount(char __user *name, int flags); | 951 | int ksys_umount(char __user *name, int flags); |
952 | int ksys_dup(unsigned int fildes); | 952 | int ksys_dup(unsigned int fildes); |
953 | int ksys_chroot(const char __user *filename); | ||
953 | 954 | ||
954 | #endif | 955 | #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) | |||
600 | out: | 600 | out: |
601 | devtmpfs_mount("dev"); | 601 | devtmpfs_mount("dev"); |
602 | ksys_mount(".", "/", NULL, MS_MOVE, NULL); | 602 | ksys_mount(".", "/", NULL, MS_MOVE, NULL); |
603 | sys_chroot("."); | 603 | ksys_chroot("."); |
604 | } | 604 | } |
605 | 605 | ||
606 | static bool is_tmpfs; | 606 | 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) | |||
44 | /* move initrd over / and chdir/chroot in initrd root */ | 44 | /* move initrd over / and chdir/chroot in initrd root */ |
45 | sys_chdir("/root"); | 45 | sys_chdir("/root"); |
46 | ksys_mount(".", "/", NULL, MS_MOVE, NULL); | 46 | ksys_mount(".", "/", NULL, MS_MOVE, NULL); |
47 | sys_chroot("."); | 47 | ksys_chroot("."); |
48 | sys_setsid(); | 48 | sys_setsid(); |
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
@@ -83,7 +83,7 @@ static void __init handle_initrd(void) | |||
83 | /* move initrd to rootfs' /old */ | 83 | /* move initrd to rootfs' /old */ |
84 | ksys_mount("..", ".", NULL, MS_MOVE, NULL); | 84 | ksys_mount("..", ".", NULL, MS_MOVE, NULL); |
85 | /* switch root and cwd back to / of rootfs */ | 85 | /* switch root and cwd back to / of rootfs */ |
86 | sys_chroot(".."); | 86 | ksys_chroot(".."); |
87 | 87 | ||
88 | if (new_decode_dev(real_root_dev) == Root_RAM0) { | 88 | if (new_decode_dev(real_root_dev) == Root_RAM0) { |
89 | sys_chdir("/old"); | 89 | sys_chdir("/old"); |