LCOV - code coverage report
Current view: top level - fs/proc - proc_net.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 69 153 45.1 %
Date: 2021-04-22 12:43:58 Functions: 6 17 35.3 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  *  linux/fs/proc/net.c
       4             :  *
       5             :  *  Copyright (C) 2007
       6             :  *
       7             :  *  Author: Eric Biederman <ebiederm@xmission.com>
       8             :  *
       9             :  *  proc net directory handling functions
      10             :  */
      11             : 
      12             : #include <linux/uaccess.h>
      13             : 
      14             : #include <linux/errno.h>
      15             : #include <linux/time.h>
      16             : #include <linux/proc_fs.h>
      17             : #include <linux/stat.h>
      18             : #include <linux/slab.h>
      19             : #include <linux/init.h>
      20             : #include <linux/sched.h>
      21             : #include <linux/sched/task.h>
      22             : #include <linux/module.h>
      23             : #include <linux/bitops.h>
      24             : #include <linux/mount.h>
      25             : #include <linux/nsproxy.h>
      26             : #include <linux/uidgid.h>
      27             : #include <net/net_namespace.h>
      28             : #include <linux/seq_file.h>
      29             : 
      30             : #include "internal.h"
      31             : 
      32           0 : static inline struct net *PDE_NET(struct proc_dir_entry *pde)
      33             : {
      34           0 :         return pde->parent->data;
      35             : }
      36             : 
      37           0 : static struct net *get_proc_net(const struct inode *inode)
      38             : {
      39           0 :         return maybe_get_net(PDE_NET(PDE(inode)));
      40             : }
      41             : 
      42           0 : static int seq_open_net(struct inode *inode, struct file *file)
      43             : {
      44           0 :         unsigned int state_size = PDE(inode)->state_size;
      45           0 :         struct seq_net_private *p;
      46           0 :         struct net *net;
      47             : 
      48           0 :         WARN_ON_ONCE(state_size < sizeof(*p));
      49             : 
      50           0 :         if (file->f_mode & FMODE_WRITE && !PDE(inode)->write)
      51             :                 return -EACCES;
      52             : 
      53           0 :         net = get_proc_net(inode);
      54           0 :         if (!net)
      55             :                 return -ENXIO;
      56             : 
      57           0 :         p = __seq_open_private(file, PDE(inode)->seq_ops, state_size);
      58           0 :         if (!p) {
      59           0 :                 put_net(net);
      60           0 :                 return -ENOMEM;
      61             :         }
      62             : #ifdef CONFIG_NET_NS
      63             :         p->net = net;
      64             : #endif
      65             :         return 0;
      66             : }
      67             : 
      68           0 : static int seq_release_net(struct inode *ino, struct file *f)
      69             : {
      70           0 :         struct seq_file *seq = f->private_data;
      71             : 
      72           0 :         put_net(seq_file_net(seq));
      73           0 :         seq_release_private(ino, f);
      74           0 :         return 0;
      75             : }
      76             : 
      77             : static const struct proc_ops proc_net_seq_ops = {
      78             :         .proc_open      = seq_open_net,
      79             :         .proc_read      = seq_read,
      80             :         .proc_write     = proc_simple_write,
      81             :         .proc_lseek     = seq_lseek,
      82             :         .proc_release   = seq_release_net,
      83             : };
      84             : 
      85           0 : int bpf_iter_init_seq_net(void *priv_data, struct bpf_iter_aux_info *aux)
      86             : {
      87             : #ifdef CONFIG_NET_NS
      88             :         struct seq_net_private *p = priv_data;
      89             : 
      90             :         p->net = get_net(current->nsproxy->net_ns);
      91             : #endif
      92           0 :         return 0;
      93             : }
      94             : 
      95           0 : void bpf_iter_fini_seq_net(void *priv_data)
      96             : {
      97             : #ifdef CONFIG_NET_NS
      98             :         struct seq_net_private *p = priv_data;
      99             : 
     100             :         put_net(p->net);
     101             : #endif
     102           0 : }
     103             : 
     104          16 : struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode,
     105             :                 struct proc_dir_entry *parent, const struct seq_operations *ops,
     106             :                 unsigned int state_size, void *data)
     107             : {
     108          16 :         struct proc_dir_entry *p;
     109             : 
     110          16 :         p = proc_create_reg(name, mode, &parent, data);
     111          16 :         if (!p)
     112             :                 return NULL;
     113          16 :         pde_force_lookup(p);
     114          16 :         p->proc_ops = &proc_net_seq_ops;
     115          16 :         p->seq_ops = ops;
     116          16 :         p->state_size = state_size;
     117          16 :         return proc_register(parent, p);
     118             : }
     119             : EXPORT_SYMBOL_GPL(proc_create_net_data);
     120             : 
     121             : /**
     122             :  * proc_create_net_data_write - Create a writable net_ns-specific proc file
     123             :  * @name: The name of the file.
     124             :  * @mode: The file's access mode.
     125             :  * @parent: The parent directory in which to create.
     126             :  * @ops: The seq_file ops with which to read the file.
     127             :  * @write: The write method with which to 'modify' the file.
     128             :  * @data: Data for retrieval by PDE_DATA().
     129             :  *
     130             :  * Create a network namespaced proc file in the @parent directory with the
     131             :  * specified @name and @mode that allows reading of a file that displays a
     132             :  * series of elements and also provides for the file accepting writes that have
     133             :  * some arbitrary effect.
     134             :  *
     135             :  * The functions in the @ops table are used to iterate over items to be
     136             :  * presented and extract the readable content using the seq_file interface.
     137             :  *
     138             :  * The @write function is called with the data copied into a kernel space
     139             :  * scratch buffer and has a NUL appended for convenience.  The buffer may be
     140             :  * modified by the @write function.  @write should return 0 on success.
     141             :  *
     142             :  * The @data value is accessible from the @show and @write functions by calling
     143             :  * PDE_DATA() on the file inode.  The network namespace must be accessed by
     144             :  * calling seq_file_net() on the seq_file struct.
     145             :  */
     146           0 : struct proc_dir_entry *proc_create_net_data_write(const char *name, umode_t mode,
     147             :                                                   struct proc_dir_entry *parent,
     148             :                                                   const struct seq_operations *ops,
     149             :                                                   proc_write_t write,
     150             :                                                   unsigned int state_size, void *data)
     151             : {
     152           0 :         struct proc_dir_entry *p;
     153             : 
     154           0 :         p = proc_create_reg(name, mode, &parent, data);
     155           0 :         if (!p)
     156             :                 return NULL;
     157           0 :         pde_force_lookup(p);
     158           0 :         p->proc_ops = &proc_net_seq_ops;
     159           0 :         p->seq_ops = ops;
     160           0 :         p->state_size = state_size;
     161           0 :         p->write = write;
     162           0 :         return proc_register(parent, p);
     163             : }
     164             : EXPORT_SYMBOL_GPL(proc_create_net_data_write);
     165             : 
     166           0 : static int single_open_net(struct inode *inode, struct file *file)
     167             : {
     168           0 :         struct proc_dir_entry *de = PDE(inode);
     169           0 :         struct net *net;
     170           0 :         int err;
     171             : 
     172           0 :         net = get_proc_net(inode);
     173           0 :         if (!net)
     174             :                 return -ENXIO;
     175             : 
     176           0 :         err = single_open(file, de->single_show, net);
     177           0 :         if (err)
     178           0 :                 put_net(net);
     179           0 :         return err;
     180             : }
     181             : 
     182           0 : static int single_release_net(struct inode *ino, struct file *f)
     183             : {
     184           0 :         struct seq_file *seq = f->private_data;
     185           0 :         put_net(seq->private);
     186           0 :         return single_release(ino, f);
     187             : }
     188             : 
     189             : static const struct proc_ops proc_net_single_ops = {
     190             :         .proc_open      = single_open_net,
     191             :         .proc_read      = seq_read,
     192             :         .proc_write     = proc_simple_write,
     193             :         .proc_lseek     = seq_lseek,
     194             :         .proc_release   = single_release_net,
     195             : };
     196             : 
     197           4 : struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode,
     198             :                 struct proc_dir_entry *parent,
     199             :                 int (*show)(struct seq_file *, void *), void *data)
     200             : {
     201           4 :         struct proc_dir_entry *p;
     202             : 
     203           4 :         p = proc_create_reg(name, mode, &parent, data);
     204           4 :         if (!p)
     205             :                 return NULL;
     206           4 :         pde_force_lookup(p);
     207           4 :         p->proc_ops = &proc_net_single_ops;
     208           4 :         p->single_show = show;
     209           4 :         return proc_register(parent, p);
     210             : }
     211             : EXPORT_SYMBOL_GPL(proc_create_net_single);
     212             : 
     213             : /**
     214             :  * proc_create_net_single_write - Create a writable net_ns-specific proc file
     215             :  * @name: The name of the file.
     216             :  * @mode: The file's access mode.
     217             :  * @parent: The parent directory in which to create.
     218             :  * @show: The seqfile show method with which to read the file.
     219             :  * @write: The write method with which to 'modify' the file.
     220             :  * @data: Data for retrieval by PDE_DATA().
     221             :  *
     222             :  * Create a network-namespaced proc file in the @parent directory with the
     223             :  * specified @name and @mode that allows reading of a file that displays a
     224             :  * single element rather than a series and also provides for the file accepting
     225             :  * writes that have some arbitrary effect.
     226             :  *
     227             :  * The @show function is called to extract the readable content via the
     228             :  * seq_file interface.
     229             :  *
     230             :  * The @write function is called with the data copied into a kernel space
     231             :  * scratch buffer and has a NUL appended for convenience.  The buffer may be
     232             :  * modified by the @write function.  @write should return 0 on success.
     233             :  *
     234             :  * The @data value is accessible from the @show and @write functions by calling
     235             :  * PDE_DATA() on the file inode.  The network namespace must be accessed by
     236             :  * calling seq_file_single_net() on the seq_file struct.
     237             :  */
     238           0 : struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mode,
     239             :                                                     struct proc_dir_entry *parent,
     240             :                                                     int (*show)(struct seq_file *, void *),
     241             :                                                     proc_write_t write,
     242             :                                                     void *data)
     243             : {
     244           0 :         struct proc_dir_entry *p;
     245             : 
     246           0 :         p = proc_create_reg(name, mode, &parent, data);
     247           0 :         if (!p)
     248             :                 return NULL;
     249           0 :         pde_force_lookup(p);
     250           0 :         p->proc_ops = &proc_net_single_ops;
     251           0 :         p->single_show = show;
     252           0 :         p->write = write;
     253           0 :         return proc_register(parent, p);
     254             : }
     255             : EXPORT_SYMBOL_GPL(proc_create_net_single_write);
     256             : 
     257          26 : static struct net *get_proc_task_net(struct inode *dir)
     258             : {
     259          26 :         struct task_struct *task;
     260          26 :         struct nsproxy *ns;
     261          26 :         struct net *net = NULL;
     262             : 
     263          26 :         rcu_read_lock();
     264          26 :         task = pid_task(proc_pid(dir), PIDTYPE_PID);
     265          26 :         if (task != NULL) {
     266          26 :                 task_lock(task);
     267          26 :                 ns = task->nsproxy;
     268          26 :                 if (ns != NULL)
     269          26 :                         net = get_net(ns->net_ns);
     270          26 :                 task_unlock(task);
     271             :         }
     272          26 :         rcu_read_unlock();
     273             : 
     274          26 :         return net;
     275             : }
     276             : 
     277          26 : static struct dentry *proc_tgid_net_lookup(struct inode *dir,
     278             :                 struct dentry *dentry, unsigned int flags)
     279             : {
     280          26 :         struct dentry *de;
     281          26 :         struct net *net;
     282             : 
     283          26 :         de = ERR_PTR(-ENOENT);
     284          26 :         net = get_proc_task_net(dir);
     285          26 :         if (net != NULL) {
     286          26 :                 de = proc_lookup_de(dir, dentry, net->proc_net);
     287          26 :                 put_net(net);
     288             :         }
     289          26 :         return de;
     290             : }
     291             : 
     292           0 : static int proc_tgid_net_getattr(struct user_namespace *mnt_userns,
     293             :                                  const struct path *path, struct kstat *stat,
     294             :                                  u32 request_mask, unsigned int query_flags)
     295             : {
     296           0 :         struct inode *inode = d_inode(path->dentry);
     297           0 :         struct net *net;
     298             : 
     299           0 :         net = get_proc_task_net(inode);
     300             : 
     301           0 :         generic_fillattr(&init_user_ns, inode, stat);
     302             : 
     303           0 :         if (net != NULL) {
     304           0 :                 stat->nlink = net->proc_net->nlink;
     305           0 :                 put_net(net);
     306             :         }
     307             : 
     308           0 :         return 0;
     309             : }
     310             : 
     311             : const struct inode_operations proc_net_inode_operations = {
     312             :         .lookup         = proc_tgid_net_lookup,
     313             :         .getattr        = proc_tgid_net_getattr,
     314             : };
     315             : 
     316           0 : static int proc_tgid_net_readdir(struct file *file, struct dir_context *ctx)
     317             : {
     318           0 :         int ret;
     319           0 :         struct net *net;
     320             : 
     321           0 :         ret = -EINVAL;
     322           0 :         net = get_proc_task_net(file_inode(file));
     323           0 :         if (net != NULL) {
     324           0 :                 ret = proc_readdir_de(file, ctx, net->proc_net);
     325           0 :                 put_net(net);
     326             :         }
     327           0 :         return ret;
     328             : }
     329             : 
     330             : const struct file_operations proc_net_operations = {
     331             :         .llseek         = generic_file_llseek,
     332             :         .read           = generic_read_dir,
     333             :         .iterate_shared = proc_tgid_net_readdir,
     334             : };
     335             : 
     336           1 : static __net_init int proc_net_ns_init(struct net *net)
     337             : {
     338           1 :         struct proc_dir_entry *netd, *net_statd;
     339           1 :         kuid_t uid;
     340           1 :         kgid_t gid;
     341           1 :         int err;
     342             : 
     343           1 :         err = -ENOMEM;
     344           1 :         netd = kmem_cache_zalloc(proc_dir_entry_cache, GFP_KERNEL);
     345           1 :         if (!netd)
     346           0 :                 goto out;
     347             : 
     348           1 :         netd->subdir = RB_ROOT;
     349           1 :         netd->data = net;
     350           1 :         netd->nlink = 2;
     351           1 :         netd->namelen = 3;
     352           1 :         netd->parent = &proc_root;
     353           1 :         netd->name = netd->inline_name;
     354           1 :         memcpy(netd->name, "net", 4);
     355             : 
     356           1 :         uid = make_kuid(net->user_ns, 0);
     357           1 :         if (!uid_valid(uid))
     358             :                 uid = netd->uid;
     359             : 
     360           1 :         gid = make_kgid(net->user_ns, 0);
     361           1 :         if (!gid_valid(gid))
     362             :                 gid = netd->gid;
     363             : 
     364           1 :         proc_set_user(netd, uid, gid);
     365             : 
     366           1 :         err = -EEXIST;
     367           1 :         net_statd = proc_net_mkdir(net, "stat", netd);
     368           1 :         if (!net_statd)
     369           0 :                 goto free_net;
     370             : 
     371           1 :         net->proc_net = netd;
     372           1 :         net->proc_net_stat = net_statd;
     373           1 :         return 0;
     374             : 
     375           0 : free_net:
     376           0 :         pde_free(netd);
     377             : out:
     378             :         return err;
     379             : }
     380             : 
     381           0 : static __net_exit void proc_net_ns_exit(struct net *net)
     382             : {
     383           0 :         remove_proc_entry("stat", net->proc_net);
     384           0 :         pde_free(net->proc_net);
     385           0 : }
     386             : 
     387             : static struct pernet_operations __net_initdata proc_net_ns_ops = {
     388             :         .init = proc_net_ns_init,
     389             :         .exit = proc_net_ns_exit,
     390             : };
     391             : 
     392           1 : int __init proc_net_init(void)
     393             : {
     394           1 :         proc_symlink("net", NULL, "self/net");
     395             : 
     396           1 :         return register_pernet_subsys(&proc_net_ns_ops);
     397             : }

Generated by: LCOV version 1.14