blob: 2c78f24814dde4ea0c18aa501f1076f476547590 [file] [log] [blame]
Christoph Hellwigc60166f2020-07-21 11:12:08 +02001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Routines that mimic syscalls, but don't use the user address space or file
4 * descriptors. Only for init/ and related early init code.
5 */
6#include <linux/init.h>
7#include <linux/mount.h>
8#include <linux/namei.h>
9#include <linux/fs.h>
Christoph Hellwigdb63f1e2020-07-22 11:25:21 +020010#include <linux/fs_struct.h>
Christoph Hellwigc60166f2020-07-21 11:12:08 +020011#include <linux/init_syscalls.h>
Christoph Hellwig4b7ca502020-07-22 11:26:13 +020012#include <linux/security.h>
Christoph Hellwigc60166f2020-07-21 11:12:08 +020013#include "internal.h"
14
15int __init init_mount(const char *dev_name, const char *dir_name,
16 const char *type_page, unsigned long flags, void *data_page)
17{
18 struct path path;
19 int ret;
20
21 ret = kern_path(dir_name, LOOKUP_FOLLOW, &path);
22 if (ret)
23 return ret;
24 ret = path_mount(dev_name, &path, type_page, flags, data_page);
25 path_put(&path);
26 return ret;
27}
Christoph Hellwig09267de2020-07-23 08:23:08 +020028
29int __init init_umount(const char *name, int flags)
30{
31 int lookup_flags = LOOKUP_MOUNTPOINT;
32 struct path path;
33 int ret;
34
35 if (!(flags & UMOUNT_NOFOLLOW))
36 lookup_flags |= LOOKUP_FOLLOW;
37 ret = kern_path(name, lookup_flags, &path);
38 if (ret)
39 return ret;
40 return path_umount(&path, flags);
41}
Christoph Hellwig8fb9f732020-07-23 08:23:40 +020042
Christoph Hellwigdb63f1e2020-07-22 11:25:21 +020043int __init init_chdir(const char *filename)
44{
45 struct path path;
46 int error;
47
48 error = kern_path(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
49 if (error)
50 return error;
51 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
52 if (!error)
53 set_fs_pwd(current->fs, &path);
54 path_put(&path);
55 return error;
56}
57
Christoph Hellwig4b7ca502020-07-22 11:26:13 +020058int __init init_chroot(const char *filename)
59{
60 struct path path;
61 int error;
62
63 error = kern_path(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
64 if (error)
65 return error;
66 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
67 if (error)
68 goto dput_and_out;
69 error = -EPERM;
70 if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT))
71 goto dput_and_out;
72 error = security_path_chroot(&path);
73 if (error)
74 goto dput_and_out;
75 set_fs_root(current->fs, &path);
76dput_and_out:
77 path_put(&path);
78 return error;
79}
80
Christoph Hellwig8fb9f732020-07-23 08:23:40 +020081int __init init_unlink(const char *pathname)
82{
83 return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
84}
Christoph Hellwig20cce022020-07-22 11:11:45 +020085
86int __init init_rmdir(const char *pathname)
87{
88 return do_rmdir(AT_FDCWD, getname_kernel(pathname));
89}