diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/init.c | 24 | ||||
-rw-r--r-- | fs/open.c | 7 |
2 files changed, 25 insertions, 6 deletions
diff --git a/fs/init.c b/fs/init.c index 64d4e12eba93..2c78f24814dd 100644 --- a/fs/init.c +++ b/fs/init.c @@ -9,6 +9,7 @@ #include <linux/fs.h> #include <linux/fs_struct.h> #include <linux/init_syscalls.h> +#include <linux/security.h> #include "internal.h" int __init init_mount(const char *dev_name, const char *dir_name, @@ -54,6 +55,29 @@ int __init init_chdir(const char *filename) return error; } +int __init init_chroot(const char *filename) +{ + struct path path; + int error; + + error = kern_path(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); + if (error) + return error; + error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); + if (error) + goto dput_and_out; + error = -EPERM; + if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT)) + goto dput_and_out; + error = security_path_chroot(&path); + if (error) + goto dput_and_out; + set_fs_root(current->fs, &path); +dput_and_out: + path_put(&path); + return error; +} + int __init init_unlink(const char *pathname) { return do_unlinkat(AT_FDCWD, getname_kernel(pathname)); diff --git a/fs/open.c b/fs/open.c index 723e0ac89893..f62f4752bb43 100644 --- a/fs/open.c +++ b/fs/open.c @@ -530,7 +530,7 @@ out: return error; } -int ksys_chroot(const char __user *filename) +SYSCALL_DEFINE1(chroot, const char __user *, filename) { struct path path; int error; @@ -563,11 +563,6 @@ 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; |