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

Generated by: LCOV version 1.14