LCOV - code coverage report
Current view: top level - fs/proc - generic.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 148 356 41.6 %
Date: 2023-08-24 13:40:31 Functions: 17 40 42.5 %

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

Generated by: LCOV version 1.14