LCOV - code coverage report
Current view: top level - fs/proc - generic.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 218 400 54.5 %
Date: 2021-04-22 12:43:58 Functions: 29 42 69.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  * proc/fs/generic.c --- generic routines for the proc-fs
       4             :  *
       5             :  * This file contains generic proc-fs routines for handling
       6             :  * directories and files.
       7             :  * 
       8             :  * Copyright (C) 1991, 1992 Linus Torvalds.
       9             :  * Copyright (C) 1997 Theodore Ts'o
      10             :  */
      11             : 
      12             : #include <linux/cache.h>
      13             : #include <linux/errno.h>
      14             : #include <linux/time.h>
      15             : #include <linux/proc_fs.h>
      16             : #include <linux/stat.h>
      17             : #include <linux/mm.h>
      18             : #include <linux/module.h>
      19             : #include <linux/namei.h>
      20             : #include <linux/slab.h>
      21             : #include <linux/printk.h>
      22             : #include <linux/mount.h>
      23             : #include <linux/init.h>
      24             : #include <linux/idr.h>
      25             : #include <linux/bitops.h>
      26             : #include <linux/spinlock.h>
      27             : #include <linux/completion.h>
      28             : #include <linux/uaccess.h>
      29             : #include <linux/seq_file.h>
      30             : 
      31             : #include "internal.h"
      32             : 
      33             : static DEFINE_RWLOCK(proc_subdir_lock);
      34             : 
      35             : struct kmem_cache *proc_dir_entry_cache __ro_after_init;
      36             : 
      37           0 : void pde_free(struct proc_dir_entry *pde)
      38             : {
      39           0 :         if (S_ISLNK(pde->mode))
      40           0 :                 kfree(pde->data);
      41           0 :         if (pde->name != pde->inline_name)
      42           0 :                 kfree(pde->name);
      43           0 :         kmem_cache_free(proc_dir_entry_cache, pde);
      44           0 : }
      45             : 
      46        1379 : static int proc_match(const char *name, struct proc_dir_entry *de, unsigned int len)
      47             : {
      48        1379 :         if (len < de->namelen)
      49             :                 return -1;
      50         777 :         if (len > de->namelen)
      51             :                 return 1;
      52             : 
      53         388 :         return memcmp(name, de->name, len);
      54             : }
      55             : 
      56           0 : static struct proc_dir_entry *pde_subdir_first(struct proc_dir_entry *dir)
      57             : {
      58           0 :         return rb_entry_safe(rb_first(&dir->subdir), struct proc_dir_entry,
      59             :                              subdir_node);
      60             : }
      61             : 
      62           0 : static struct proc_dir_entry *pde_subdir_next(struct proc_dir_entry *dir)
      63             : {
      64           0 :         return rb_entry_safe(rb_next(&dir->subdir_node), struct proc_dir_entry,
      65             :                              subdir_node);
      66             : }
      67             : 
      68         148 : static struct proc_dir_entry *pde_subdir_find(struct proc_dir_entry *dir,
      69             :                                               const char *name,
      70             :                                               unsigned int len)
      71             : {
      72         148 :         struct rb_node *node = dir->subdir.rb_node;
      73             : 
      74         930 :         while (node) {
      75         818 :                 struct proc_dir_entry *de = rb_entry(node,
      76             :                                                      struct proc_dir_entry,
      77             :                                                      subdir_node);
      78         818 :                 int result = proc_match(name, de, len);
      79             : 
      80         818 :                 if (result < 0)
      81         545 :                         node = node->rb_left;
      82         273 :                 else if (result > 0)
      83         237 :                         node = node->rb_right;
      84             :                 else
      85          36 :                         return de;
      86             :         }
      87             :         return NULL;
      88             : }
      89             : 
      90         223 : static bool pde_subdir_insert(struct proc_dir_entry *dir,
      91             :                               struct proc_dir_entry *de)
      92             : {
      93         223 :         struct rb_root *root = &dir->subdir;
      94         223 :         struct rb_node **new = &root->rb_node, *parent = NULL;
      95             : 
      96             :         /* Figure out where to put new node */
      97         784 :         while (*new) {
      98         561 :                 struct proc_dir_entry *this = rb_entry(*new,
      99             :                                                        struct proc_dir_entry,
     100             :                                                        subdir_node);
     101         561 :                 int result = proc_match(de->name, this, de->namelen);
     102             : 
     103         561 :                 parent = *new;
     104         561 :                 if (result < 0)
     105         195 :                         new = &(*new)->rb_left;
     106         366 :                 else if (result > 0)
     107         366 :                         new = &(*new)->rb_right;
     108             :                 else
     109             :                         return false;
     110             :         }
     111             : 
     112             :         /* Add new node and rebalance tree. */
     113         223 :         rb_link_node(&de->subdir_node, parent, new);
     114         223 :         rb_insert_color(&de->subdir_node, root);
     115         223 :         return true;
     116             : }
     117             : 
     118           0 : static int proc_notify_change(struct user_namespace *mnt_userns,
     119             :                               struct dentry *dentry, struct iattr *iattr)
     120             : {
     121           0 :         struct inode *inode = d_inode(dentry);
     122           0 :         struct proc_dir_entry *de = PDE(inode);
     123           0 :         int error;
     124             : 
     125           0 :         error = setattr_prepare(&init_user_ns, dentry, iattr);
     126           0 :         if (error)
     127             :                 return error;
     128             : 
     129           0 :         setattr_copy(&init_user_ns, inode, iattr);
     130           0 :         mark_inode_dirty(inode);
     131             : 
     132           0 :         proc_set_user(de, inode->i_uid, inode->i_gid);
     133           0 :         de->mode = inode->i_mode;
     134           0 :         return 0;
     135             : }
     136             : 
     137           6 : static int proc_getattr(struct user_namespace *mnt_userns,
     138             :                         const struct path *path, struct kstat *stat,
     139             :                         u32 request_mask, unsigned int query_flags)
     140             : {
     141           6 :         struct inode *inode = d_inode(path->dentry);
     142           6 :         struct proc_dir_entry *de = PDE(inode);
     143           6 :         if (de) {
     144           6 :                 nlink_t nlink = READ_ONCE(de->nlink);
     145           6 :                 if (nlink > 0) {
     146           6 :                         set_nlink(inode, nlink);
     147             :                 }
     148             :         }
     149             : 
     150           6 :         generic_fillattr(&init_user_ns, inode, stat);
     151           6 :         return 0;
     152             : }
     153             : 
     154             : static const struct inode_operations proc_file_inode_operations = {
     155             :         .setattr        = proc_notify_change,
     156             : };
     157             : 
     158             : /*
     159             :  * This function parses a name such as "tty/driver/serial", and
     160             :  * returns the struct proc_dir_entry for "/proc/tty/driver", and
     161             :  * returns "serial" in residual.
     162             :  */
     163         223 : static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
     164             :                              const char **residual)
     165             : {
     166         223 :         const char              *cp = name, *next;
     167         223 :         struct proc_dir_entry   *de;
     168             : 
     169         223 :         de = *ret;
     170         223 :         if (!de)
     171          56 :                 de = &proc_root;
     172             : 
     173         247 :         while (1) {
     174         247 :                 next = strchr(cp, '/');
     175         235 :                 if (!next)
     176             :                         break;
     177             : 
     178          12 :                 de = pde_subdir_find(de, cp, next - cp);
     179          12 :                 if (!de) {
     180           0 :                         WARN(1, "name '%s'\n", name);
     181           0 :                         return -ENOENT;
     182             :                 }
     183          12 :                 cp = next + 1;
     184             :         }
     185         223 :         *residual = cp;
     186         223 :         *ret = de;
     187         223 :         return 0;
     188             : }
     189             : 
     190         223 : static int xlate_proc_name(const char *name, struct proc_dir_entry **ret,
     191             :                            const char **residual)
     192             : {
     193         223 :         int rv;
     194             : 
     195         223 :         read_lock(&proc_subdir_lock);
     196         223 :         rv = __xlate_proc_name(name, ret, residual);
     197         223 :         read_unlock(&proc_subdir_lock);
     198         223 :         return rv;
     199             : }
     200             : 
     201             : static DEFINE_IDA(proc_inum_ida);
     202             : 
     203             : #define PROC_DYNAMIC_FIRST 0xF0000000U
     204             : 
     205             : /*
     206             :  * Return an inode number between PROC_DYNAMIC_FIRST and
     207             :  * 0xffffffff, or zero on failure.
     208             :  */
     209         277 : int proc_alloc_inum(unsigned int *inum)
     210             : {
     211         277 :         int i;
     212             : 
     213         277 :         i = ida_simple_get(&proc_inum_ida, 0, UINT_MAX - PROC_DYNAMIC_FIRST + 1,
     214             :                            GFP_KERNEL);
     215         277 :         if (i < 0)
     216             :                 return i;
     217             : 
     218         277 :         *inum = PROC_DYNAMIC_FIRST + (unsigned int)i;
     219         277 :         return 0;
     220             : }
     221             : 
     222          47 : void proc_free_inum(unsigned int inum)
     223             : {
     224          47 :         ida_simple_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST);
     225           0 : }
     226             : 
     227        1292 : static int proc_misc_d_revalidate(struct dentry *dentry, unsigned int flags)
     228             : {
     229        1292 :         if (flags & LOOKUP_RCU)
     230             :                 return -ECHILD;
     231             : 
     232         646 :         if (atomic_read(&PDE(d_inode(dentry))->in_use) < 0)
     233           0 :                 return 0; /* revalidate */
     234             :         return 1;
     235             : }
     236             : 
     237         538 : static int proc_misc_d_delete(const struct dentry *dentry)
     238             : {
     239         538 :         return atomic_read(&PDE(d_inode(dentry))->in_use) < 0;
     240             : }
     241             : 
     242             : static const struct dentry_operations proc_misc_dentry_ops = {
     243             :         .d_revalidate   = proc_misc_d_revalidate,
     244             :         .d_delete       = proc_misc_d_delete,
     245             : };
     246             : 
     247             : /*
     248             :  * Don't create negative dentries here, return -ENOENT by hand
     249             :  * instead.
     250             :  */
     251         136 : struct dentry *proc_lookup_de(struct inode *dir, struct dentry *dentry,
     252             :                               struct proc_dir_entry *de)
     253             : {
     254         136 :         struct inode *inode;
     255             : 
     256         136 :         read_lock(&proc_subdir_lock);
     257         136 :         de = pde_subdir_find(de, dentry->d_name.name, dentry->d_name.len);
     258         136 :         if (de) {
     259          24 :                 pde_get(de);
     260          24 :                 read_unlock(&proc_subdir_lock);
     261          24 :                 inode = proc_get_inode(dir->i_sb, de);
     262          24 :                 if (!inode)
     263         136 :                         return ERR_PTR(-ENOMEM);
     264          24 :                 d_set_d_op(dentry, de->proc_dops);
     265          24 :                 return d_splice_alias(inode, dentry);
     266             :         }
     267         112 :         read_unlock(&proc_subdir_lock);
     268         112 :         return ERR_PTR(-ENOENT);
     269             : }
     270             : 
     271         110 : struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
     272             :                 unsigned int flags)
     273             : {
     274         110 :         struct proc_fs_info *fs_info = proc_sb_info(dir->i_sb);
     275             : 
     276         110 :         if (fs_info->pidonly == PROC_PIDONLY_ON)
     277         110 :                 return ERR_PTR(-ENOENT);
     278             : 
     279         110 :         return proc_lookup_de(dir, dentry, PDE(dir));
     280             : }
     281             : 
     282             : /*
     283             :  * This returns non-zero if at EOF, so that the /proc
     284             :  * root directory can use this and check if it should
     285             :  * continue with the <pid> entries..
     286             :  *
     287             :  * Note that the VFS-layer doesn't care about the return
     288             :  * value of the readdir() call, as long as it's non-negative
     289             :  * for success..
     290             :  */
     291           0 : int proc_readdir_de(struct file *file, struct dir_context *ctx,
     292             :                     struct proc_dir_entry *de)
     293             : {
     294           0 :         int i;
     295             : 
     296           0 :         if (!dir_emit_dots(file, ctx))
     297             :                 return 0;
     298             : 
     299           0 :         i = ctx->pos - 2;
     300           0 :         read_lock(&proc_subdir_lock);
     301           0 :         de = pde_subdir_first(de);
     302           0 :         for (;;) {
     303           0 :                 if (!de) {
     304           0 :                         read_unlock(&proc_subdir_lock);
     305           0 :                         return 0;
     306             :                 }
     307           0 :                 if (!i)
     308             :                         break;
     309           0 :                 de = pde_subdir_next(de);
     310           0 :                 i--;
     311             :         }
     312             : 
     313           0 :         do {
     314           0 :                 struct proc_dir_entry *next;
     315           0 :                 pde_get(de);
     316           0 :                 read_unlock(&proc_subdir_lock);
     317           0 :                 if (!dir_emit(ctx, de->name, de->namelen,
     318           0 :                             de->low_ino, de->mode >> 12)) {
     319           0 :                         pde_put(de);
     320           0 :                         return 0;
     321             :                 }
     322           0 :                 ctx->pos++;
     323           0 :                 read_lock(&proc_subdir_lock);
     324           0 :                 next = pde_subdir_next(de);
     325           0 :                 pde_put(de);
     326           0 :                 de = next;
     327           0 :         } while (de);
     328           0 :         read_unlock(&proc_subdir_lock);
     329           0 :         return 1;
     330             : }
     331             : 
     332           0 : int proc_readdir(struct file *file, struct dir_context *ctx)
     333             : {
     334           0 :         struct inode *inode = file_inode(file);
     335           0 :         struct proc_fs_info *fs_info = proc_sb_info(inode->i_sb);
     336             : 
     337           0 :         if (fs_info->pidonly == PROC_PIDONLY_ON)
     338             :                 return 1;
     339             : 
     340           0 :         return proc_readdir_de(file, ctx, PDE(inode));
     341             : }
     342             : 
     343             : /*
     344             :  * These are the generic /proc directory operations. They
     345             :  * use the in-memory "struct proc_dir_entry" tree to parse
     346             :  * the /proc directory.
     347             :  */
     348             : static const struct file_operations proc_dir_operations = {
     349             :         .llseek                 = generic_file_llseek,
     350             :         .read                   = generic_read_dir,
     351             :         .iterate_shared         = proc_readdir,
     352             : };
     353             : 
     354           0 : static int proc_net_d_revalidate(struct dentry *dentry, unsigned int flags)
     355             : {
     356           0 :         return 0;
     357             : }
     358             : 
     359             : const struct dentry_operations proc_net_dentry_ops = {
     360             :         .d_revalidate   = proc_net_d_revalidate,
     361             :         .d_delete       = always_delete_dentry,
     362             : };
     363             : 
     364             : /*
     365             :  * proc directories can do almost nothing..
     366             :  */
     367             : static const struct inode_operations proc_dir_inode_operations = {
     368             :         .lookup         = proc_lookup,
     369             :         .getattr        = proc_getattr,
     370             :         .setattr        = proc_notify_change,
     371             : };
     372             : 
     373             : /* returns the registered entry, or frees dp and returns NULL on failure */
     374         223 : struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
     375             :                 struct proc_dir_entry *dp)
     376             : {
     377         223 :         if (proc_alloc_inum(&dp->low_ino))
     378           0 :                 goto out_free_entry;
     379             : 
     380         223 :         write_lock(&proc_subdir_lock);
     381         223 :         dp->parent = dir;
     382         223 :         if (pde_subdir_insert(dir, dp) == false) {
     383           0 :                 WARN(1, "proc_dir_entry '%s/%s' already registered\n",
     384             :                      dir->name, dp->name);
     385           0 :                 write_unlock(&proc_subdir_lock);
     386           0 :                 goto out_free_inum;
     387             :         }
     388         223 :         dir->nlink++;
     389         223 :         write_unlock(&proc_subdir_lock);
     390             : 
     391         223 :         return dp;
     392           0 : out_free_inum:
     393           0 :         proc_free_inum(dp->low_ino);
     394           0 : out_free_entry:
     395           0 :         pde_free(dp);
     396           0 :         return NULL;
     397             : }
     398             : 
     399         223 : static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
     400             :                                           const char *name,
     401             :                                           umode_t mode,
     402             :                                           nlink_t nlink)
     403             : {
     404         223 :         struct proc_dir_entry *ent = NULL;
     405         223 :         const char *fn;
     406         223 :         struct qstr qstr;
     407             : 
     408         223 :         if (xlate_proc_name(name, parent, &fn) != 0)
     409           0 :                 goto out;
     410         223 :         qstr.name = fn;
     411         223 :         qstr.len = strlen(fn);
     412         223 :         if (qstr.len == 0 || qstr.len >= 256) {
     413           0 :                 WARN(1, "name len %u\n", qstr.len);
     414           0 :                 return NULL;
     415             :         }
     416         223 :         if (qstr.len == 1 && fn[0] == '.') {
     417           0 :                 WARN(1, "name '.'\n");
     418           0 :                 return NULL;
     419             :         }
     420         223 :         if (qstr.len == 2 && fn[0] == '.' && fn[1] == '.') {
     421           0 :                 WARN(1, "name '..'\n");
     422           0 :                 return NULL;
     423             :         }
     424         223 :         if (*parent == &proc_root && name_to_int(&qstr) != ~0U) {
     425           0 :                 WARN(1, "create '/proc/%s' by hand\n", qstr.name);
     426           0 :                 return NULL;
     427             :         }
     428         446 :         if (is_empty_pde(*parent)) {
     429           0 :                 WARN(1, "attempt to add to permanently empty directory");
     430           0 :                 return NULL;
     431             :         }
     432             : 
     433         223 :         ent = kmem_cache_zalloc(proc_dir_entry_cache, GFP_KERNEL);
     434         223 :         if (!ent)
     435           0 :                 goto out;
     436             : 
     437         223 :         if (qstr.len + 1 <= SIZEOF_PDE_INLINE_NAME) {
     438         223 :                 ent->name = ent->inline_name;
     439             :         } else {
     440           0 :                 ent->name = kmalloc(qstr.len + 1, GFP_KERNEL);
     441           0 :                 if (!ent->name) {
     442           0 :                         pde_free(ent);
     443           0 :                         return NULL;
     444             :                 }
     445             :         }
     446             : 
     447         223 :         memcpy(ent->name, fn, qstr.len + 1);
     448         223 :         ent->namelen = qstr.len;
     449         223 :         ent->mode = mode;
     450         223 :         ent->nlink = nlink;
     451         223 :         ent->subdir = RB_ROOT;
     452         223 :         refcount_set(&ent->refcnt, 1);
     453         223 :         spin_lock_init(&ent->pde_unload_lock);
     454         223 :         INIT_LIST_HEAD(&ent->pde_openers);
     455         223 :         proc_set_user(ent, (*parent)->uid, (*parent)->gid);
     456             : 
     457         223 :         ent->proc_dops = &proc_misc_dentry_ops;
     458             : 
     459             : out:
     460             :         return ent;
     461             : }
     462             : 
     463           2 : struct proc_dir_entry *proc_symlink(const char *name,
     464             :                 struct proc_dir_entry *parent, const char *dest)
     465             : {
     466           2 :         struct proc_dir_entry *ent;
     467             : 
     468           2 :         ent = __proc_create(&parent, name,
     469             :                           (S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
     470             : 
     471           2 :         if (ent) {
     472           2 :                 ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
     473           2 :                 if (ent->data) {
     474           2 :                         strcpy((char*)ent->data,dest);
     475           2 :                         ent->proc_iops = &proc_link_inode_operations;
     476           2 :                         ent = proc_register(parent, ent);
     477             :                 } else {
     478           0 :                         pde_free(ent);
     479           0 :                         ent = NULL;
     480             :                 }
     481             :         }
     482           2 :         return ent;
     483             : }
     484             : EXPORT_SYMBOL(proc_symlink);
     485             : 
     486          35 : struct proc_dir_entry *_proc_mkdir(const char *name, umode_t mode,
     487             :                 struct proc_dir_entry *parent, void *data, bool force_lookup)
     488             : {
     489          35 :         struct proc_dir_entry *ent;
     490             : 
     491          35 :         if (mode == 0)
     492          34 :                 mode = S_IRUGO | S_IXUGO;
     493             : 
     494          35 :         ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
     495          35 :         if (ent) {
     496          35 :                 ent->data = data;
     497          35 :                 ent->proc_dir_ops = &proc_dir_operations;
     498          35 :                 ent->proc_iops = &proc_dir_inode_operations;
     499          35 :                 if (force_lookup) {
     500           2 :                         pde_force_lookup(ent);
     501             :                 }
     502          35 :                 ent = proc_register(parent, ent);
     503             :         }
     504          35 :         return ent;
     505             : }
     506             : EXPORT_SYMBOL_GPL(_proc_mkdir);
     507             : 
     508          33 : struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
     509             :                 struct proc_dir_entry *parent, void *data)
     510             : {
     511           0 :         return _proc_mkdir(name, mode, parent, data, false);
     512             : }
     513             : EXPORT_SYMBOL_GPL(proc_mkdir_data);
     514             : 
     515           1 : struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
     516             :                                        struct proc_dir_entry *parent)
     517             : {
     518           1 :         return proc_mkdir_data(name, mode, parent, NULL);
     519             : }
     520             : EXPORT_SYMBOL(proc_mkdir_mode);
     521             : 
     522          32 : struct proc_dir_entry *proc_mkdir(const char *name,
     523             :                 struct proc_dir_entry *parent)
     524             : {
     525          32 :         return proc_mkdir_data(name, 0, parent, NULL);
     526             : }
     527             : EXPORT_SYMBOL(proc_mkdir);
     528             : 
     529           1 : struct proc_dir_entry *proc_create_mount_point(const char *name)
     530             : {
     531           1 :         umode_t mode = S_IFDIR | S_IRUGO | S_IXUGO;
     532           1 :         struct proc_dir_entry *ent, *parent = NULL;
     533             : 
     534           1 :         ent = __proc_create(&parent, name, mode, 2);
     535           1 :         if (ent) {
     536           1 :                 ent->data = NULL;
     537           1 :                 ent->proc_dir_ops = NULL;
     538           1 :                 ent->proc_iops = NULL;
     539           1 :                 ent = proc_register(parent, ent);
     540             :         }
     541           1 :         return ent;
     542             : }
     543             : EXPORT_SYMBOL(proc_create_mount_point);
     544             : 
     545         185 : struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
     546             :                 struct proc_dir_entry **parent, void *data)
     547             : {
     548         185 :         struct proc_dir_entry *p;
     549             : 
     550         185 :         if ((mode & S_IFMT) == 0)
     551         185 :                 mode |= S_IFREG;
     552         185 :         if ((mode & S_IALLUGO) == 0)
     553          31 :                 mode |= S_IRUGO;
     554         185 :         if (WARN_ON_ONCE(!S_ISREG(mode)))
     555             :                 return NULL;
     556             : 
     557         185 :         p = __proc_create(parent, name, mode, 1);
     558         185 :         if (p) {
     559         185 :                 p->proc_iops = &proc_file_inode_operations;
     560         185 :                 p->data = data;
     561             :         }
     562             :         return p;
     563             : }
     564             : 
     565          48 : static inline void pde_set_flags(struct proc_dir_entry *pde)
     566             : {
     567          48 :         if (pde->proc_ops->proc_flags & PROC_ENTRY_PERMANENT)
     568           7 :                 pde->flags |= PROC_ENTRY_PERMANENT;
     569             : }
     570             : 
     571          48 : struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
     572             :                 struct proc_dir_entry *parent,
     573             :                 const struct proc_ops *proc_ops, void *data)
     574             : {
     575          48 :         struct proc_dir_entry *p;
     576             : 
     577          48 :         p = proc_create_reg(name, mode, &parent, data);
     578          48 :         if (!p)
     579             :                 return NULL;
     580          48 :         p->proc_ops = proc_ops;
     581          48 :         pde_set_flags(p);
     582          48 :         return proc_register(parent, p);
     583             : }
     584             : EXPORT_SYMBOL(proc_create_data);
     585             :  
     586          12 : struct proc_dir_entry *proc_create(const char *name, umode_t mode,
     587             :                                    struct proc_dir_entry *parent,
     588             :                                    const struct proc_ops *proc_ops)
     589             : {
     590          12 :         return proc_create_data(name, mode, parent, proc_ops, NULL);
     591             : }
     592             : EXPORT_SYMBOL(proc_create);
     593             : 
     594           1 : static int proc_seq_open(struct inode *inode, struct file *file)
     595             : {
     596           1 :         struct proc_dir_entry *de = PDE(inode);
     597             : 
     598           1 :         if (de->state_size)
     599           0 :                 return seq_open_private(file, de->seq_ops, de->state_size);
     600           1 :         return seq_open(file, de->seq_ops);
     601             : }
     602             : 
     603           1 : static int proc_seq_release(struct inode *inode, struct file *file)
     604             : {
     605           1 :         struct proc_dir_entry *de = PDE(inode);
     606             : 
     607           1 :         if (de->state_size)
     608           0 :                 return seq_release_private(inode, file);
     609           1 :         return seq_release(inode, file);
     610             : }
     611             : 
     612             : static const struct proc_ops proc_seq_ops = {
     613             :         /* not permanent -- can call into arbitrary seq_operations */
     614             :         .proc_open      = proc_seq_open,
     615             :         .proc_read_iter = seq_read_iter,
     616             :         .proc_lseek     = seq_lseek,
     617             :         .proc_release   = proc_seq_release,
     618             : };
     619             : 
     620          23 : struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
     621             :                 struct proc_dir_entry *parent, const struct seq_operations *ops,
     622             :                 unsigned int state_size, void *data)
     623             : {
     624          23 :         struct proc_dir_entry *p;
     625             : 
     626          23 :         p = proc_create_reg(name, mode, &parent, data);
     627          23 :         if (!p)
     628             :                 return NULL;
     629          23 :         p->proc_ops = &proc_seq_ops;
     630          23 :         p->seq_ops = ops;
     631          23 :         p->state_size = state_size;
     632          23 :         return proc_register(parent, p);
     633             : }
     634             : EXPORT_SYMBOL(proc_create_seq_private);
     635             : 
     636         519 : static int proc_single_open(struct inode *inode, struct file *file)
     637             : {
     638         519 :         struct proc_dir_entry *de = PDE(inode);
     639             : 
     640         519 :         return single_open(file, de->single_show, de->data);
     641             : }
     642             : 
     643             : static const struct proc_ops proc_single_ops = {
     644             :         /* not permanent -- can call into arbitrary ->single_show */
     645             :         .proc_open      = proc_single_open,
     646             :         .proc_read_iter = seq_read_iter,
     647             :         .proc_lseek     = seq_lseek,
     648             :         .proc_release   = single_release,
     649             : };
     650             : 
     651          94 : struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
     652             :                 struct proc_dir_entry *parent,
     653             :                 int (*show)(struct seq_file *, void *), void *data)
     654             : {
     655          94 :         struct proc_dir_entry *p;
     656             : 
     657          94 :         p = proc_create_reg(name, mode, &parent, data);
     658          94 :         if (!p)
     659             :                 return NULL;
     660          94 :         p->proc_ops = &proc_single_ops;
     661          94 :         p->single_show = show;
     662          94 :         return proc_register(parent, p);
     663             : }
     664             : EXPORT_SYMBOL(proc_create_single_data);
     665             : 
     666           0 : void proc_set_size(struct proc_dir_entry *de, loff_t size)
     667             : {
     668           0 :         de->size = size;
     669           0 : }
     670             : EXPORT_SYMBOL(proc_set_size);
     671             : 
     672         224 : void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid)
     673             : {
     674         224 :         de->uid = uid;
     675         223 :         de->gid = gid;
     676           1 : }
     677             : EXPORT_SYMBOL(proc_set_user);
     678             : 
     679          10 : void pde_put(struct proc_dir_entry *pde)
     680             : {
     681          10 :         if (refcount_dec_and_test(&pde->refcnt)) {
     682           0 :                 proc_free_inum(pde->low_ino);
     683           0 :                 pde_free(pde);
     684             :         }
     685          10 : }
     686             : 
     687             : /*
     688             :  * Remove a /proc entry and free it if it's not currently in use.
     689             :  */
     690           0 : void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
     691             : {
     692           0 :         struct proc_dir_entry *de = NULL;
     693           0 :         const char *fn = name;
     694           0 :         unsigned int len;
     695             : 
     696           0 :         write_lock(&proc_subdir_lock);
     697           0 :         if (__xlate_proc_name(name, &parent, &fn) != 0) {
     698           0 :                 write_unlock(&proc_subdir_lock);
     699           0 :                 return;
     700             :         }
     701           0 :         len = strlen(fn);
     702             : 
     703           0 :         de = pde_subdir_find(parent, fn, len);
     704           0 :         if (de) {
     705           0 :                 if (unlikely(pde_is_permanent(de))) {
     706           0 :                         WARN(1, "removing permanent /proc entry '%s'", de->name);
     707           0 :                         de = NULL;
     708             :                 } else {
     709           0 :                         rb_erase(&de->subdir_node, &parent->subdir);
     710           0 :                         if (S_ISDIR(de->mode))
     711           0 :                                 parent->nlink--;
     712             :                 }
     713             :         }
     714           0 :         write_unlock(&proc_subdir_lock);
     715           0 :         if (!de) {
     716           0 :                 WARN(1, "name '%s'\n", name);
     717           0 :                 return;
     718             :         }
     719             : 
     720           0 :         proc_entry_rundown(de);
     721             : 
     722           0 :         WARN(pde_subdir_first(de),
     723             :              "%s: removing non-empty directory '%s/%s', leaking at least '%s'\n",
     724             :              __func__, de->parent->name, de->name, pde_subdir_first(de)->name);
     725           0 :         pde_put(de);
     726             : }
     727             : EXPORT_SYMBOL(remove_proc_entry);
     728             : 
     729           0 : int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
     730             : {
     731           0 :         struct proc_dir_entry *root = NULL, *de, *next;
     732           0 :         const char *fn = name;
     733           0 :         unsigned int len;
     734             : 
     735           0 :         write_lock(&proc_subdir_lock);
     736           0 :         if (__xlate_proc_name(name, &parent, &fn) != 0) {
     737           0 :                 write_unlock(&proc_subdir_lock);
     738           0 :                 return -ENOENT;
     739             :         }
     740           0 :         len = strlen(fn);
     741             : 
     742           0 :         root = pde_subdir_find(parent, fn, len);
     743           0 :         if (!root) {
     744           0 :                 write_unlock(&proc_subdir_lock);
     745           0 :                 return -ENOENT;
     746             :         }
     747           0 :         if (unlikely(pde_is_permanent(root))) {
     748           0 :                 write_unlock(&proc_subdir_lock);
     749           0 :                 WARN(1, "removing permanent /proc entry '%s/%s'",
     750             :                         root->parent->name, root->name);
     751           0 :                 return -EINVAL;
     752             :         }
     753           0 :         rb_erase(&root->subdir_node, &parent->subdir);
     754             : 
     755           0 :         de = root;
     756           0 :         while (1) {
     757           0 :                 next = pde_subdir_first(de);
     758           0 :                 if (next) {
     759           0 :                         if (unlikely(pde_is_permanent(root))) {
     760           0 :                                 write_unlock(&proc_subdir_lock);
     761           0 :                                 WARN(1, "removing permanent /proc entry '%s/%s'",
     762             :                                         next->parent->name, next->name);
     763           0 :                                 return -EINVAL;
     764             :                         }
     765           0 :                         rb_erase(&next->subdir_node, &de->subdir);
     766           0 :                         de = next;
     767           0 :                         continue;
     768             :                 }
     769           0 :                 next = de->parent;
     770           0 :                 if (S_ISDIR(de->mode))
     771           0 :                         next->nlink--;
     772           0 :                 write_unlock(&proc_subdir_lock);
     773             : 
     774           0 :                 proc_entry_rundown(de);
     775           0 :                 if (de == root)
     776             :                         break;
     777           0 :                 pde_put(de);
     778             : 
     779           0 :                 write_lock(&proc_subdir_lock);
     780           0 :                 de = next;
     781             :         }
     782           0 :         pde_put(root);
     783           0 :         return 0;
     784             : }
     785             : EXPORT_SYMBOL(remove_proc_subtree);
     786             : 
     787           0 : void *proc_get_parent_data(const struct inode *inode)
     788             : {
     789           0 :         struct proc_dir_entry *de = PDE(inode);
     790           0 :         return de->parent->data;
     791             : }
     792             : EXPORT_SYMBOL_GPL(proc_get_parent_data);
     793             : 
     794           0 : void proc_remove(struct proc_dir_entry *de)
     795             : {
     796           0 :         if (de)
     797           0 :                 remove_proc_subtree(de->name, de->parent);
     798           0 : }
     799             : EXPORT_SYMBOL(proc_remove);
     800             : 
     801           0 : void *PDE_DATA(const struct inode *inode)
     802             : {
     803           0 :         return __PDE_DATA(inode);
     804             : }
     805             : EXPORT_SYMBOL(PDE_DATA);
     806             : 
     807             : /*
     808             :  * Pull a user buffer into memory and pass it to the file's write handler if
     809             :  * one is supplied.  The ->write() method is permitted to modify the
     810             :  * kernel-side buffer.
     811             :  */
     812           0 : ssize_t proc_simple_write(struct file *f, const char __user *ubuf, size_t size,
     813             :                           loff_t *_pos)
     814             : {
     815           0 :         struct proc_dir_entry *pde = PDE(file_inode(f));
     816           0 :         char *buf;
     817           0 :         int ret;
     818             : 
     819           0 :         if (!pde->write)
     820             :                 return -EACCES;
     821           0 :         if (size == 0 || size > PAGE_SIZE - 1)
     822             :                 return -EINVAL;
     823           0 :         buf = memdup_user_nul(ubuf, size);
     824           0 :         if (IS_ERR(buf))
     825           0 :                 return PTR_ERR(buf);
     826           0 :         ret = pde->write(f, buf, size);
     827           0 :         kfree(buf);
     828           0 :         return ret == 0 ? size : ret;
     829             : }

Generated by: LCOV version 1.14