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