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