1 // SPDX-License-Identifier: GPL-2.0
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.
6 #include <linux/init.h>
7 #include <linux/mount.h>
8 #include <linux/namei.h>
10 #include <linux/fs_struct.h>
11 #include <linux/file.h>
12 #include <linux/init_syscalls.h>
13 #include <linux/security.h>
16 int __init
init_mount(const char *dev_name
, const char *dir_name
,
17 const char *type_page
, unsigned long flags
, void *data_page
)
22 ret
= kern_path(dir_name
, LOOKUP_FOLLOW
, &path
);
25 ret
= path_mount(dev_name
, &path
, type_page
, flags
, data_page
);
30 int __init
init_umount(const char *name
, int flags
)
32 int lookup_flags
= LOOKUP_MOUNTPOINT
;
36 if (!(flags
& UMOUNT_NOFOLLOW
))
37 lookup_flags
|= LOOKUP_FOLLOW
;
38 ret
= kern_path(name
, lookup_flags
, &path
);
41 return path_umount(&path
, flags
);
44 int __init
init_chdir(const char *filename
)
49 error
= kern_path(filename
, LOOKUP_FOLLOW
| LOOKUP_DIRECTORY
, &path
);
52 error
= inode_permission(path
.dentry
->d_inode
, MAY_EXEC
| MAY_CHDIR
);
54 set_fs_pwd(current
->fs
, &path
);
59 int __init
init_chroot(const char *filename
)
64 error
= kern_path(filename
, LOOKUP_FOLLOW
| LOOKUP_DIRECTORY
, &path
);
67 error
= inode_permission(path
.dentry
->d_inode
, MAY_EXEC
| MAY_CHDIR
);
71 if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT
))
73 error
= security_path_chroot(&path
);
76 set_fs_root(current
->fs
, &path
);
82 int __init
init_chown(const char *filename
, uid_t user
, gid_t group
, int flags
)
84 int lookup_flags
= (flags
& AT_SYMLINK_NOFOLLOW
) ? 0 : LOOKUP_FOLLOW
;
88 error
= kern_path(filename
, lookup_flags
, &path
);
91 error
= mnt_want_write(path
.mnt
);
93 error
= chown_common(&path
, user
, group
);
94 mnt_drop_write(path
.mnt
);
100 int __init
init_chmod(const char *filename
, umode_t mode
)
105 error
= kern_path(filename
, LOOKUP_FOLLOW
, &path
);
108 error
= chmod_common(&path
, mode
);
113 int __init
init_eaccess(const char *filename
)
118 error
= kern_path(filename
, LOOKUP_FOLLOW
, &path
);
121 error
= inode_permission(d_inode(path
.dentry
), MAY_ACCESS
);
126 int __init
init_stat(const char *filename
, struct kstat
*stat
, int flags
)
128 int lookup_flags
= (flags
& AT_SYMLINK_NOFOLLOW
) ? 0 : LOOKUP_FOLLOW
;
132 error
= kern_path(filename
, lookup_flags
, &path
);
135 error
= vfs_getattr(&path
, stat
, STATX_BASIC_STATS
,
136 flags
| AT_NO_AUTOMOUNT
);
141 int __init
init_mknod(const char *filename
, umode_t mode
, unsigned int dev
)
143 struct dentry
*dentry
;
147 if (S_ISFIFO(mode
) || S_ISSOCK(mode
))
149 else if (!(S_ISBLK(mode
) || S_ISCHR(mode
)))
152 dentry
= kern_path_create(AT_FDCWD
, filename
, &path
, 0);
154 return PTR_ERR(dentry
);
156 if (!IS_POSIXACL(path
.dentry
->d_inode
))
157 mode
&= ~current_umask();
158 error
= security_path_mknod(&path
, dentry
, mode
, dev
);
160 error
= vfs_mknod(path
.dentry
->d_inode
, dentry
, mode
,
161 new_decode_dev(dev
));
162 done_path_create(&path
, dentry
);
166 int __init
init_link(const char *oldname
, const char *newname
)
168 struct dentry
*new_dentry
;
169 struct path old_path
, new_path
;
172 error
= kern_path(oldname
, 0, &old_path
);
176 new_dentry
= kern_path_create(AT_FDCWD
, newname
, &new_path
, 0);
177 error
= PTR_ERR(new_dentry
);
178 if (IS_ERR(new_dentry
))
182 if (old_path
.mnt
!= new_path
.mnt
)
184 error
= may_linkat(&old_path
);
187 error
= security_path_link(old_path
.dentry
, &new_path
, new_dentry
);
190 error
= vfs_link(old_path
.dentry
, new_path
.dentry
->d_inode
, new_dentry
,
193 done_path_create(&new_path
, new_dentry
);
199 int __init
init_symlink(const char *oldname
, const char *newname
)
201 struct dentry
*dentry
;
205 dentry
= kern_path_create(AT_FDCWD
, newname
, &path
, 0);
207 return PTR_ERR(dentry
);
208 error
= security_path_symlink(&path
, dentry
, oldname
);
210 error
= vfs_symlink(path
.dentry
->d_inode
, dentry
, oldname
);
211 done_path_create(&path
, dentry
);
215 int __init
init_unlink(const char *pathname
)
217 return do_unlinkat(AT_FDCWD
, getname_kernel(pathname
));
220 int __init
init_mkdir(const char *pathname
, umode_t mode
)
222 struct dentry
*dentry
;
226 dentry
= kern_path_create(AT_FDCWD
, pathname
, &path
, LOOKUP_DIRECTORY
);
228 return PTR_ERR(dentry
);
229 if (!IS_POSIXACL(path
.dentry
->d_inode
))
230 mode
&= ~current_umask();
231 error
= security_path_mkdir(&path
, dentry
, mode
);
233 error
= vfs_mkdir(path
.dentry
->d_inode
, dentry
, mode
);
234 done_path_create(&path
, dentry
);
238 int __init
init_rmdir(const char *pathname
)
240 return do_rmdir(AT_FDCWD
, getname_kernel(pathname
));
243 int __init
init_utimes(char *filename
, struct timespec64
*ts
)
248 error
= kern_path(filename
, 0, &path
);
251 error
= vfs_utimes(&path
, ts
);
256 int __init
init_dup(struct file
*file
)
260 fd
= get_unused_fd_flags(0);
263 fd_install(fd
, get_file(file
));