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 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 static int seq_open_net(struct inode *inode, struct file *file) 43 { 44 unsigned int state_size = PDE(inode)->state_size; 45 struct seq_net_private *p; 46 struct net *net; 47 48 WARN_ON_ONCE(state_size < sizeof(*p)); 49 50 if (file->f_mode & FMODE_WRITE && !PDE(inode)->write) 51 return -EACCES; 52 53 net = get_proc_net(inode); 54 if (!net) 55 return -ENXIO; 56 57 p = __seq_open_private(file, PDE(inode)->seq_ops, state_size); 58 if (!p) { 59 put_net(net); 60 return -ENOMEM; 61 } 62 #ifdef CONFIG_NET_NS 63 p->net = net; 64 #endif 65 return 0; 66 } 67 68 static int seq_release_net(struct inode *ino, struct file *f) 69 { 70 struct seq_file *seq = f->private_data; 71 72 put_net(seq_file_net(seq)); 73 seq_release_private(ino, f); 74 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 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 return 0; 93 } 94 95 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 } 103 104 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 struct proc_dir_entry *p; 109 110 p = proc_create_reg(name, mode, &parent, data); 111 if (!p) 112 return NULL; 113 pde_force_lookup(p); 114 p->proc_ops = &proc_net_seq_ops; 115 p->seq_ops = ops; 116 p->state_size = state_size; 117 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 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 struct proc_dir_entry *p; 153 154 p = proc_create_reg(name, mode, &parent, data); 155 if (!p) 156 return NULL; 157 pde_force_lookup(p); 158 p->proc_ops = &proc_net_seq_ops; 159 p->seq_ops = ops; 160 p->state_size = state_size; 161 p->write = write; 162 return proc_register(parent, p); 163 } 164 EXPORT_SYMBOL_GPL(proc_create_net_data_write); 165 166 static int single_open_net(struct inode *inode, struct file *file) 167 { 168 struct proc_dir_entry *de = PDE(inode); 169 struct net *net; 170 int err; 171 172 net = get_proc_net(inode); 173 if (!net) 174 return -ENXIO; 175 176 err = single_open(file, de->single_show, net); 177 if (err) 178 put_net(net); 179 return err; 180 } 181 182 static int single_release_net(struct inode *ino, struct file *f) 183 { 184 struct seq_file *seq = f->private_data; 185 put_net(seq->private); 186 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 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 struct proc_dir_entry *p; 202 203 p = proc_create_reg(name, mode, &parent, data); 204 if (!p) 205 return NULL; 206 pde_force_lookup(p); 207 p->proc_ops = &proc_net_single_ops; 208 p->single_show = show; 209 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 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 struct proc_dir_entry *p; 245 246 p = proc_create_reg(name, mode, &parent, data); 247 if (!p) 248 return NULL; 249 pde_force_lookup(p); 250 p->proc_ops = &proc_net_single_ops; 251 p->single_show = show; 252 p->write = write; 253 return proc_register(parent, p); 254 } 255 EXPORT_SYMBOL_GPL(proc_create_net_single_write); 256 257 static struct net *get_proc_task_net(struct inode *dir) 258 { 259 struct task_struct *task; 260 struct nsproxy *ns; 261 struct net *net = NULL; 262 263 rcu_read_lock(); 264 task = pid_task(proc_pid(dir), PIDTYPE_PID); 265 if (task != NULL) { 266 task_lock(task); 267 ns = task->nsproxy; 268 if (ns != NULL) 269 net = get_net(ns->net_ns); 270 task_unlock(task); 271 } 272 rcu_read_unlock(); 273 274 return net; 275 } 276 277 static struct dentry *proc_tgid_net_lookup(struct inode *dir, 278 struct dentry *dentry, unsigned int flags) 279 { 280 struct dentry *de; 281 struct net *net; 282 283 de = ERR_PTR(-ENOENT); 284 net = get_proc_task_net(dir); 285 if (net != NULL) { 286 de = proc_lookup_de(dir, dentry, net->proc_net); 287 put_net(net); 288 } 289 return de; 290 } 291 292 static int proc_tgid_net_getattr(const struct path *path, struct kstat *stat, 293 u32 request_mask, unsigned int query_flags) 294 { 295 struct inode *inode = d_inode(path->dentry); 296 struct net *net; 297 298 net = get_proc_task_net(inode); 299 300 generic_fillattr(inode, stat); 301 302 if (net != NULL) { 303 stat->nlink = net->proc_net->nlink; 304 put_net(net); 305 } 306 307 return 0; 308 } 309 310 const struct inode_operations proc_net_inode_operations = { 311 .lookup = proc_tgid_net_lookup, 312 .getattr = proc_tgid_net_getattr, 313 }; 314 315 static int proc_tgid_net_readdir(struct file *file, struct dir_context *ctx) 316 { 317 int ret; 318 struct net *net; 319 320 ret = -EINVAL; 321 net = get_proc_task_net(file_inode(file)); 322 if (net != NULL) { 323 ret = proc_readdir_de(file, ctx, net->proc_net); 324 put_net(net); 325 } 326 return ret; 327 } 328 329 const struct file_operations proc_net_operations = { 330 .llseek = generic_file_llseek, 331 .read = generic_read_dir, 332 .iterate_shared = proc_tgid_net_readdir, 333 }; 334 335 static __net_init int proc_net_ns_init(struct net *net) 336 { 337 struct proc_dir_entry *netd, *net_statd; 338 kuid_t uid; 339 kgid_t gid; 340 int err; 341 342 err = -ENOMEM; 343 netd = kmem_cache_zalloc(proc_dir_entry_cache, GFP_KERNEL); 344 if (!netd) 345 goto out; 346 347 netd->subdir = RB_ROOT; 348 netd->data = net; 349 netd->nlink = 2; 350 netd->namelen = 3; 351 netd->parent = &proc_root; 352 netd->name = netd->inline_name; 353 memcpy(netd->name, "net", 4); 354 355 uid = make_kuid(net->user_ns, 0); 356 if (!uid_valid(uid)) 357 uid = netd->uid; 358 359 gid = make_kgid(net->user_ns, 0); 360 if (!gid_valid(gid)) 361 gid = netd->gid; 362 363 proc_set_user(netd, uid, gid); 364 365 err = -EEXIST; 366 net_statd = proc_net_mkdir(net, "stat", netd); 367 if (!net_statd) 368 goto free_net; 369 370 net->proc_net = netd; 371 net->proc_net_stat = net_statd; 372 return 0; 373 374 free_net: 375 pde_free(netd); 376 out: 377 return err; 378 } 379 380 static __net_exit void proc_net_ns_exit(struct net *net) 381 { 382 remove_proc_entry("stat", net->proc_net); 383 pde_free(net->proc_net); 384 } 385 386 static struct pernet_operations __net_initdata proc_net_ns_ops = { 387 .init = proc_net_ns_init, 388 .exit = proc_net_ns_exit, 389 }; 390 391 int __init proc_net_init(void) 392 { 393 proc_symlink("net", NULL, "self/net"); 394 395 return register_pernet_subsys(&proc_net_ns_ops); 396 } 397