LCOV - code coverage report
Current view: top level - fs - init.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 20 123 16.3 %
Date: 2023-03-27 20:00:47 Functions: 2 16 12.5 %

          Line data    Source code
       1             : // 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>
      10             : #include <linux/fs_struct.h>
      11             : #include <linux/file.h>
      12             : #include <linux/init_syscalls.h>
      13             : #include <linux/security.h>
      14             : #include "internal.h"
      15             : 
      16           0 : int __init init_mount(const char *dev_name, const char *dir_name,
      17             :                 const char *type_page, unsigned long flags, void *data_page)
      18             : {
      19             :         struct path path;
      20             :         int ret;
      21             : 
      22           0 :         ret = kern_path(dir_name, LOOKUP_FOLLOW, &path);
      23           0 :         if (ret)
      24             :                 return ret;
      25           0 :         ret = path_mount(dev_name, &path, type_page, flags, data_page);
      26           0 :         path_put(&path);
      27           0 :         return ret;
      28             : }
      29             : 
      30           0 : int __init init_umount(const char *name, int flags)
      31             : {
      32           0 :         int lookup_flags = LOOKUP_MOUNTPOINT;
      33             :         struct path path;
      34             :         int ret;
      35             : 
      36           0 :         if (!(flags & UMOUNT_NOFOLLOW))
      37           0 :                 lookup_flags |= LOOKUP_FOLLOW;
      38           0 :         ret = kern_path(name, lookup_flags, &path);
      39           0 :         if (ret)
      40             :                 return ret;
      41           0 :         return path_umount(&path, flags);
      42             : }
      43             : 
      44           0 : int __init init_chdir(const char *filename)
      45             : {
      46             :         struct path path;
      47             :         int error;
      48             : 
      49           0 :         error = kern_path(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
      50           0 :         if (error)
      51             :                 return error;
      52           0 :         error = path_permission(&path, MAY_EXEC | MAY_CHDIR);
      53           0 :         if (!error)
      54           0 :                 set_fs_pwd(current->fs, &path);
      55           0 :         path_put(&path);
      56           0 :         return error;
      57             : }
      58             : 
      59           0 : int __init init_chroot(const char *filename)
      60             : {
      61             :         struct path path;
      62             :         int error;
      63             : 
      64           0 :         error = kern_path(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
      65           0 :         if (error)
      66             :                 return error;
      67           0 :         error = path_permission(&path, MAY_EXEC | MAY_CHDIR);
      68           0 :         if (error)
      69             :                 goto dput_and_out;
      70           0 :         error = -EPERM;
      71           0 :         if (!ns_capable(current_user_ns(), CAP_SYS_CHROOT))
      72             :                 goto dput_and_out;
      73           0 :         error = security_path_chroot(&path);
      74             :         if (error)
      75             :                 goto dput_and_out;
      76           0 :         set_fs_root(current->fs, &path);
      77             : dput_and_out:
      78           0 :         path_put(&path);
      79           0 :         return error;
      80             : }
      81             : 
      82           0 : int __init init_chown(const char *filename, uid_t user, gid_t group, int flags)
      83             : {
      84           0 :         int lookup_flags = (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
      85             :         struct path path;
      86             :         int error;
      87             : 
      88           0 :         error = kern_path(filename, lookup_flags, &path);
      89           0 :         if (error)
      90             :                 return error;
      91           0 :         error = mnt_want_write(path.mnt);
      92           0 :         if (!error) {
      93           0 :                 error = chown_common(&path, user, group);
      94           0 :                 mnt_drop_write(path.mnt);
      95             :         }
      96           0 :         path_put(&path);
      97           0 :         return error;
      98             : }
      99             : 
     100           0 : int __init init_chmod(const char *filename, umode_t mode)
     101             : {
     102             :         struct path path;
     103             :         int error;
     104             : 
     105           0 :         error = kern_path(filename, LOOKUP_FOLLOW, &path);
     106           0 :         if (error)
     107             :                 return error;
     108           0 :         error = chmod_common(&path, mode);
     109           0 :         path_put(&path);
     110           0 :         return error;
     111             : }
     112             : 
     113           0 : int __init init_eaccess(const char *filename)
     114             : {
     115             :         struct path path;
     116             :         int error;
     117             : 
     118           0 :         error = kern_path(filename, LOOKUP_FOLLOW, &path);
     119           0 :         if (error)
     120             :                 return error;
     121           0 :         error = path_permission(&path, MAY_ACCESS);
     122           0 :         path_put(&path);
     123           0 :         return error;
     124             : }
     125             : 
     126           0 : int __init init_stat(const char *filename, struct kstat *stat, int flags)
     127             : {
     128           0 :         int lookup_flags = (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
     129             :         struct path path;
     130             :         int error;
     131             : 
     132           0 :         error = kern_path(filename, lookup_flags, &path);
     133           0 :         if (error)
     134             :                 return error;
     135           0 :         error = vfs_getattr(&path, stat, STATX_BASIC_STATS,
     136           0 :                             flags | AT_NO_AUTOMOUNT);
     137           0 :         path_put(&path);
     138           0 :         return error;
     139             : }
     140             : 
     141           1 : int __init init_mknod(const char *filename, umode_t mode, unsigned int dev)
     142             : {
     143             :         struct dentry *dentry;
     144             :         struct path path;
     145             :         int error;
     146             : 
     147           1 :         if (S_ISFIFO(mode) || S_ISSOCK(mode))
     148             :                 dev = 0;
     149           1 :         else if (!(S_ISBLK(mode) || S_ISCHR(mode)))
     150             :                 return -EINVAL;
     151             : 
     152           1 :         dentry = kern_path_create(AT_FDCWD, filename, &path, 0);
     153           1 :         if (IS_ERR(dentry))
     154           0 :                 return PTR_ERR(dentry);
     155             : 
     156           1 :         if (!IS_POSIXACL(path.dentry->d_inode))
     157           1 :                 mode &= ~current_umask();
     158           1 :         error = security_path_mknod(&path, dentry, mode, dev);
     159             :         if (!error)
     160           2 :                 error = vfs_mknod(mnt_idmap(path.mnt), path.dentry->d_inode,
     161             :                                   dentry, mode, new_decode_dev(dev));
     162           1 :         done_path_create(&path, dentry);
     163           1 :         return error;
     164             : }
     165             : 
     166           0 : int __init init_link(const char *oldname, const char *newname)
     167             : {
     168             :         struct dentry *new_dentry;
     169             :         struct path old_path, new_path;
     170             :         struct mnt_idmap *idmap;
     171             :         int error;
     172             : 
     173           0 :         error = kern_path(oldname, 0, &old_path);
     174           0 :         if (error)
     175             :                 return error;
     176             : 
     177           0 :         new_dentry = kern_path_create(AT_FDCWD, newname, &new_path, 0);
     178           0 :         error = PTR_ERR(new_dentry);
     179           0 :         if (IS_ERR(new_dentry))
     180             :                 goto out;
     181             : 
     182           0 :         error = -EXDEV;
     183           0 :         if (old_path.mnt != new_path.mnt)
     184             :                 goto out_dput;
     185           0 :         idmap = mnt_idmap(new_path.mnt);
     186           0 :         error = may_linkat(idmap, &old_path);
     187           0 :         if (unlikely(error))
     188             :                 goto out_dput;
     189           0 :         error = security_path_link(old_path.dentry, &new_path, new_dentry);
     190             :         if (error)
     191             :                 goto out_dput;
     192           0 :         error = vfs_link(old_path.dentry, idmap, new_path.dentry->d_inode,
     193             :                          new_dentry, NULL);
     194             : out_dput:
     195           0 :         done_path_create(&new_path, new_dentry);
     196             : out:
     197           0 :         path_put(&old_path);
     198           0 :         return error;
     199             : }
     200             : 
     201           0 : int __init init_symlink(const char *oldname, const char *newname)
     202             : {
     203             :         struct dentry *dentry;
     204             :         struct path path;
     205             :         int error;
     206             : 
     207           0 :         dentry = kern_path_create(AT_FDCWD, newname, &path, 0);
     208           0 :         if (IS_ERR(dentry))
     209           0 :                 return PTR_ERR(dentry);
     210           0 :         error = security_path_symlink(&path, dentry, oldname);
     211             :         if (!error)
     212           0 :                 error = vfs_symlink(mnt_idmap(path.mnt), path.dentry->d_inode,
     213             :                                     dentry, oldname);
     214           0 :         done_path_create(&path, dentry);
     215           0 :         return error;
     216             : }
     217             : 
     218           0 : int __init init_unlink(const char *pathname)
     219             : {
     220           0 :         return do_unlinkat(AT_FDCWD, getname_kernel(pathname));
     221             : }
     222             : 
     223           2 : int __init init_mkdir(const char *pathname, umode_t mode)
     224             : {
     225             :         struct dentry *dentry;
     226             :         struct path path;
     227             :         int error;
     228             : 
     229           2 :         dentry = kern_path_create(AT_FDCWD, pathname, &path, LOOKUP_DIRECTORY);
     230           2 :         if (IS_ERR(dentry))
     231           0 :                 return PTR_ERR(dentry);
     232           2 :         if (!IS_POSIXACL(path.dentry->d_inode))
     233           2 :                 mode &= ~current_umask();
     234           2 :         error = security_path_mkdir(&path, dentry, mode);
     235             :         if (!error)
     236           4 :                 error = vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode,
     237             :                                   dentry, mode);
     238           2 :         done_path_create(&path, dentry);
     239           2 :         return error;
     240             : }
     241             : 
     242           0 : int __init init_rmdir(const char *pathname)
     243             : {
     244           0 :         return do_rmdir(AT_FDCWD, getname_kernel(pathname));
     245             : }
     246             : 
     247           0 : int __init init_utimes(char *filename, struct timespec64 *ts)
     248             : {
     249             :         struct path path;
     250             :         int error;
     251             : 
     252           0 :         error = kern_path(filename, 0, &path);
     253           0 :         if (error)
     254             :                 return error;
     255           0 :         error = vfs_utimes(&path, ts);
     256           0 :         path_put(&path);
     257           0 :         return error;
     258             : }
     259             : 
     260           0 : int __init init_dup(struct file *file)
     261             : {
     262             :         int fd;
     263             : 
     264           0 :         fd = get_unused_fd_flags(0);
     265           0 :         if (fd < 0)
     266             :                 return fd;
     267           0 :         fd_install(fd, get_file(file));
     268           0 :         return 0;
     269             : }

Generated by: LCOV version 1.14