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