LCOV - code coverage report
Current view: top level - security - inode.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 56 102 54.9 %
Date: 2022-04-01 14:17:54 Functions: 6 11 54.5 %
Branches: 14 44 31.8 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  *  inode.c - securityfs
       4                 :            :  *
       5                 :            :  *  Copyright (C) 2005 Greg Kroah-Hartman <gregkh@suse.de>
       6                 :            :  *
       7                 :            :  *  Based on fs/debugfs/inode.c which had the following copyright notice:
       8                 :            :  *    Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
       9                 :            :  *    Copyright (C) 2004 IBM Inc.
      10                 :            :  */
      11                 :            : 
      12                 :            : /* #define DEBUG */
      13                 :            : #include <linux/sysfs.h>
      14                 :            : #include <linux/kobject.h>
      15                 :            : #include <linux/fs.h>
      16                 :            : #include <linux/fs_context.h>
      17                 :            : #include <linux/mount.h>
      18                 :            : #include <linux/pagemap.h>
      19                 :            : #include <linux/init.h>
      20                 :            : #include <linux/namei.h>
      21                 :            : #include <linux/security.h>
      22                 :            : #include <linux/lsm_hooks.h>
      23                 :            : #include <linux/magic.h>
      24                 :            : 
      25                 :            : static struct vfsmount *mount;
      26                 :            : static int mount_count;
      27                 :            : 
      28                 :          0 : static void securityfs_free_inode(struct inode *inode)
      29                 :            : {
      30         [ #  # ]:          0 :         if (S_ISLNK(inode->i_mode))
      31                 :          0 :                 kfree(inode->i_link);
      32                 :          0 :         free_inode_nonrcu(inode);
      33                 :          0 : }
      34                 :            : 
      35                 :            : static const struct super_operations securityfs_super_operations = {
      36                 :            :         .statfs         = simple_statfs,
      37                 :            :         .free_inode     = securityfs_free_inode,
      38                 :            : };
      39                 :            : 
      40                 :         11 : static int securityfs_fill_super(struct super_block *sb, struct fs_context *fc)
      41                 :            : {
      42                 :         11 :         static const struct tree_descr files[] = {{""}};
      43                 :         11 :         int error;
      44                 :            : 
      45                 :         11 :         error = simple_fill_super(sb, SECURITYFS_MAGIC, files);
      46         [ +  - ]:         11 :         if (error)
      47                 :            :                 return error;
      48                 :            : 
      49                 :         11 :         sb->s_op = &securityfs_super_operations;
      50                 :            : 
      51                 :         11 :         return 0;
      52                 :            : }
      53                 :            : 
      54                 :         22 : static int securityfs_get_tree(struct fs_context *fc)
      55                 :            : {
      56                 :         22 :         return get_tree_single(fc, securityfs_fill_super);
      57                 :            : }
      58                 :            : 
      59                 :            : static const struct fs_context_operations securityfs_context_ops = {
      60                 :            :         .get_tree       = securityfs_get_tree,
      61                 :            : };
      62                 :            : 
      63                 :         33 : static int securityfs_init_fs_context(struct fs_context *fc)
      64                 :            : {
      65                 :         33 :         fc->ops = &securityfs_context_ops;
      66                 :         33 :         return 0;
      67                 :            : }
      68                 :            : 
      69                 :            : static struct file_system_type fs_type = {
      70                 :            :         .owner =        THIS_MODULE,
      71                 :            :         .name =         "securityfs",
      72                 :            :         .init_fs_context = securityfs_init_fs_context,
      73                 :            :         .kill_sb =      kill_litter_super,
      74                 :            : };
      75                 :            : 
      76                 :            : /**
      77                 :            :  * securityfs_create_dentry - create a dentry in the securityfs filesystem
      78                 :            :  *
      79                 :            :  * @name: a pointer to a string containing the name of the file to create.
      80                 :            :  * @mode: the permission that the file should have
      81                 :            :  * @parent: a pointer to the parent dentry for this file.  This should be a
      82                 :            :  *          directory dentry if set.  If this parameter is %NULL, then the
      83                 :            :  *          file will be created in the root of the securityfs filesystem.
      84                 :            :  * @data: a pointer to something that the caller will want to get to later
      85                 :            :  *        on.  The inode.i_private pointer will point to this value on
      86                 :            :  *        the open() call.
      87                 :            :  * @fops: a pointer to a struct file_operations that should be used for
      88                 :            :  *        this file.
      89                 :            :  * @iops: a point to a struct of inode_operations that should be used for
      90                 :            :  *        this file/dir
      91                 :            :  *
      92                 :            :  * This is the basic "create a file/dir/symlink" function for
      93                 :            :  * securityfs.  It allows for a wide range of flexibility in creating
      94                 :            :  * a file, or a directory (if you want to create a directory, the
      95                 :            :  * securityfs_create_dir() function is recommended to be used
      96                 :            :  * instead).
      97                 :            :  *
      98                 :            :  * This function returns a pointer to a dentry if it succeeds.  This
      99                 :            :  * pointer must be passed to the securityfs_remove() function when the
     100                 :            :  * file is to be removed (no automatic cleanup happens if your module
     101                 :            :  * is unloaded, you are responsible here).  If an error occurs, the
     102                 :            :  * function will return the error value (via ERR_PTR).
     103                 :            :  *
     104                 :            :  * If securityfs is not enabled in the kernel, the value %-ENODEV is
     105                 :            :  * returned.
     106                 :            :  */
     107                 :         22 : static struct dentry *securityfs_create_dentry(const char *name, umode_t mode,
     108                 :            :                                         struct dentry *parent, void *data,
     109                 :            :                                         const struct file_operations *fops,
     110                 :            :                                         const struct inode_operations *iops)
     111                 :            : {
     112                 :         22 :         struct dentry *dentry;
     113                 :         22 :         struct inode *dir, *inode;
     114                 :         22 :         int error;
     115                 :            : 
     116         [ +  + ]:         22 :         if (!(mode & S_IFMT))
     117                 :         11 :                 mode = (mode & S_IALLUGO) | S_IFREG;
     118                 :            : 
     119                 :         22 :         pr_debug("securityfs: creating file '%s'\n",name);
     120                 :            : 
     121                 :         22 :         error = simple_pin_fs(&fs_type, &mount, &mount_count);
     122         [ -  + ]:         22 :         if (error)
     123                 :          0 :                 return ERR_PTR(error);
     124                 :            : 
     125         [ +  - ]:         22 :         if (!parent)
     126                 :         22 :                 parent = mount->mnt_root;
     127                 :            : 
     128                 :         22 :         dir = d_inode(parent);
     129                 :            : 
     130                 :         22 :         inode_lock(dir);
     131                 :         22 :         dentry = lookup_one_len(name, parent, strlen(name));
     132         [ -  + ]:         22 :         if (IS_ERR(dentry))
     133                 :          0 :                 goto out;
     134                 :            : 
     135         [ -  + ]:         22 :         if (d_really_is_positive(dentry)) {
     136                 :          0 :                 error = -EEXIST;
     137                 :          0 :                 goto out1;
     138                 :            :         }
     139                 :            : 
     140                 :         22 :         inode = new_inode(dir->i_sb);
     141         [ -  + ]:         22 :         if (!inode) {
     142                 :          0 :                 error = -ENOMEM;
     143                 :          0 :                 goto out1;
     144                 :            :         }
     145                 :            : 
     146                 :         22 :         inode->i_ino = get_next_ino();
     147                 :         22 :         inode->i_mode = mode;
     148                 :         22 :         inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
     149                 :         22 :         inode->i_private = data;
     150         [ +  + ]:         22 :         if (S_ISDIR(mode)) {
     151                 :         11 :                 inode->i_op = &simple_dir_inode_operations;
     152                 :         11 :                 inode->i_fop = &simple_dir_operations;
     153                 :         11 :                 inc_nlink(inode);
     154                 :         11 :                 inc_nlink(dir);
     155         [ -  + ]:         11 :         } else if (S_ISLNK(mode)) {
     156         [ #  # ]:          0 :                 inode->i_op = iops ? iops : &simple_symlink_inode_operations;
     157                 :          0 :                 inode->i_link = data;
     158                 :            :         } else {
     159                 :         11 :                 inode->i_fop = fops;
     160                 :            :         }
     161                 :         22 :         d_instantiate(dentry, inode);
     162         [ +  - ]:         22 :         dget(dentry);
     163                 :         22 :         inode_unlock(dir);
     164                 :         22 :         return dentry;
     165                 :            : 
     166                 :          0 : out1:
     167                 :          0 :         dput(dentry);
     168                 :          0 :         dentry = ERR_PTR(error);
     169                 :          0 : out:
     170                 :          0 :         inode_unlock(dir);
     171                 :          0 :         simple_release_fs(&mount, &mount_count);
     172                 :          0 :         return dentry;
     173                 :            : }
     174                 :            : 
     175                 :            : /**
     176                 :            :  * securityfs_create_file - create a file in the securityfs filesystem
     177                 :            :  *
     178                 :            :  * @name: a pointer to a string containing the name of the file to create.
     179                 :            :  * @mode: the permission that the file should have
     180                 :            :  * @parent: a pointer to the parent dentry for this file.  This should be a
     181                 :            :  *          directory dentry if set.  If this parameter is %NULL, then the
     182                 :            :  *          file will be created in the root of the securityfs filesystem.
     183                 :            :  * @data: a pointer to something that the caller will want to get to later
     184                 :            :  *        on.  The inode.i_private pointer will point to this value on
     185                 :            :  *        the open() call.
     186                 :            :  * @fops: a pointer to a struct file_operations that should be used for
     187                 :            :  *        this file.
     188                 :            :  *
     189                 :            :  * This function creates a file in securityfs with the given @name.
     190                 :            :  *
     191                 :            :  * This function returns a pointer to a dentry if it succeeds.  This
     192                 :            :  * pointer must be passed to the securityfs_remove() function when the file is
     193                 :            :  * to be removed (no automatic cleanup happens if your module is unloaded,
     194                 :            :  * you are responsible here).  If an error occurs, the function will return
     195                 :            :  * the error value (via ERR_PTR).
     196                 :            :  *
     197                 :            :  * If securityfs is not enabled in the kernel, the value %-ENODEV is
     198                 :            :  * returned.
     199                 :            :  */
     200                 :         22 : struct dentry *securityfs_create_file(const char *name, umode_t mode,
     201                 :            :                                       struct dentry *parent, void *data,
     202                 :            :                                       const struct file_operations *fops)
     203                 :            : {
     204                 :          0 :         return securityfs_create_dentry(name, mode, parent, data, fops, NULL);
     205                 :            : }
     206                 :            : EXPORT_SYMBOL_GPL(securityfs_create_file);
     207                 :            : 
     208                 :            : /**
     209                 :            :  * securityfs_create_dir - create a directory in the securityfs filesystem
     210                 :            :  *
     211                 :            :  * @name: a pointer to a string containing the name of the directory to
     212                 :            :  *        create.
     213                 :            :  * @parent: a pointer to the parent dentry for this file.  This should be a
     214                 :            :  *          directory dentry if set.  If this parameter is %NULL, then the
     215                 :            :  *          directory will be created in the root of the securityfs filesystem.
     216                 :            :  *
     217                 :            :  * This function creates a directory in securityfs with the given @name.
     218                 :            :  *
     219                 :            :  * This function returns a pointer to a dentry if it succeeds.  This
     220                 :            :  * pointer must be passed to the securityfs_remove() function when the file is
     221                 :            :  * to be removed (no automatic cleanup happens if your module is unloaded,
     222                 :            :  * you are responsible here).  If an error occurs, the function will return
     223                 :            :  * the error value (via ERR_PTR).
     224                 :            :  *
     225                 :            :  * If securityfs is not enabled in the kernel, the value %-ENODEV is
     226                 :            :  * returned.
     227                 :            :  */
     228                 :         11 : struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
     229                 :            : {
     230                 :         11 :         return securityfs_create_file(name, S_IFDIR | 0755, parent, NULL, NULL);
     231                 :            : }
     232                 :            : EXPORT_SYMBOL_GPL(securityfs_create_dir);
     233                 :            : 
     234                 :            : /**
     235                 :            :  * securityfs_create_symlink - create a symlink in the securityfs filesystem
     236                 :            :  *
     237                 :            :  * @name: a pointer to a string containing the name of the symlink to
     238                 :            :  *        create.
     239                 :            :  * @parent: a pointer to the parent dentry for the symlink.  This should be a
     240                 :            :  *          directory dentry if set.  If this parameter is %NULL, then the
     241                 :            :  *          directory will be created in the root of the securityfs filesystem.
     242                 :            :  * @target: a pointer to a string containing the name of the symlink's target.
     243                 :            :  *          If this parameter is %NULL, then the @iops parameter needs to be
     244                 :            :  *          setup to handle .readlink and .get_link inode_operations.
     245                 :            :  * @iops: a pointer to the struct inode_operations to use for the symlink. If
     246                 :            :  *        this parameter is %NULL, then the default simple_symlink_inode
     247                 :            :  *        operations will be used.
     248                 :            :  *
     249                 :            :  * This function creates a symlink in securityfs with the given @name.
     250                 :            :  *
     251                 :            :  * This function returns a pointer to a dentry if it succeeds.  This
     252                 :            :  * pointer must be passed to the securityfs_remove() function when the file is
     253                 :            :  * to be removed (no automatic cleanup happens if your module is unloaded,
     254                 :            :  * you are responsible here).  If an error occurs, the function will return
     255                 :            :  * the error value (via ERR_PTR).
     256                 :            :  *
     257                 :            :  * If securityfs is not enabled in the kernel, the value %-ENODEV is
     258                 :            :  * returned.
     259                 :            :  */
     260                 :          0 : struct dentry *securityfs_create_symlink(const char *name,
     261                 :            :                                          struct dentry *parent,
     262                 :            :                                          const char *target,
     263                 :            :                                          const struct inode_operations *iops)
     264                 :            : {
     265                 :          0 :         struct dentry *dent;
     266                 :          0 :         char *link = NULL;
     267                 :            : 
     268         [ #  # ]:          0 :         if (target) {
     269                 :          0 :                 link = kstrdup(target, GFP_KERNEL);
     270         [ #  # ]:          0 :                 if (!link)
     271                 :            :                         return ERR_PTR(-ENOMEM);
     272                 :            :         }
     273                 :          0 :         dent = securityfs_create_dentry(name, S_IFLNK | 0444, parent,
     274                 :            :                                         link, NULL, iops);
     275         [ #  # ]:          0 :         if (IS_ERR(dent))
     276                 :          0 :                 kfree(link);
     277                 :            : 
     278                 :            :         return dent;
     279                 :            : }
     280                 :            : EXPORT_SYMBOL_GPL(securityfs_create_symlink);
     281                 :            : 
     282                 :            : /**
     283                 :            :  * securityfs_remove - removes a file or directory from the securityfs filesystem
     284                 :            :  *
     285                 :            :  * @dentry: a pointer to a the dentry of the file or directory to be removed.
     286                 :            :  *
     287                 :            :  * This function removes a file or directory in securityfs that was previously
     288                 :            :  * created with a call to another securityfs function (like
     289                 :            :  * securityfs_create_file() or variants thereof.)
     290                 :            :  *
     291                 :            :  * This function is required to be called in order for the file to be
     292                 :            :  * removed. No automatic cleanup of files will happen when a module is
     293                 :            :  * removed; you are responsible here.
     294                 :            :  */
     295                 :          0 : void securityfs_remove(struct dentry *dentry)
     296                 :            : {
     297                 :          0 :         struct inode *dir;
     298                 :            : 
     299   [ #  #  #  # ]:          0 :         if (!dentry || IS_ERR(dentry))
     300                 :            :                 return;
     301                 :            : 
     302                 :          0 :         dir = d_inode(dentry->d_parent);
     303                 :          0 :         inode_lock(dir);
     304         [ #  # ]:          0 :         if (simple_positive(dentry)) {
     305   [ #  #  #  # ]:          0 :                 if (d_is_dir(dentry))
     306                 :          0 :                         simple_rmdir(dir, dentry);
     307                 :            :                 else
     308                 :          0 :                         simple_unlink(dir, dentry);
     309                 :          0 :                 dput(dentry);
     310                 :            :         }
     311                 :          0 :         inode_unlock(dir);
     312                 :          0 :         simple_release_fs(&mount, &mount_count);
     313                 :            : }
     314                 :            : EXPORT_SYMBOL_GPL(securityfs_remove);
     315                 :            : 
     316                 :            : #ifdef CONFIG_SECURITY
     317                 :            : static struct dentry *lsm_dentry;
     318                 :          0 : static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count,
     319                 :            :                         loff_t *ppos)
     320                 :            : {
     321                 :          0 :         return simple_read_from_buffer(buf, count, ppos, lsm_names,
     322                 :            :                 strlen(lsm_names));
     323                 :            : }
     324                 :            : 
     325                 :            : static const struct file_operations lsm_ops = {
     326                 :            :         .read = lsm_read,
     327                 :            :         .llseek = generic_file_llseek,
     328                 :            : };
     329                 :            : #endif
     330                 :            : 
     331                 :         11 : static int __init securityfs_init(void)
     332                 :            : {
     333                 :         11 :         int retval;
     334                 :            : 
     335                 :         11 :         retval = sysfs_create_mount_point(kernel_kobj, "security");
     336         [ +  - ]:         11 :         if (retval)
     337                 :            :                 return retval;
     338                 :            : 
     339                 :         11 :         retval = register_filesystem(&fs_type);
     340         [ -  + ]:         11 :         if (retval) {
     341                 :          0 :                 sysfs_remove_mount_point(kernel_kobj, "security");
     342                 :          0 :                 return retval;
     343                 :            :         }
     344                 :            : #ifdef CONFIG_SECURITY
     345                 :         11 :         lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL,
     346                 :            :                                                 &lsm_ops);
     347                 :            : #endif
     348                 :         11 :         return 0;
     349                 :            : }
     350                 :            : core_initcall(securityfs_init);

Generated by: LCOV version 1.14