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