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 seq_open_net(struct inode *inode, struct file *file) 42 { 43 unsigned int state_size = PDE(inode)->state_size; 44 struct seq_net_private *p; 45 struct net *net; 46 47 WARN_ON_ONCE(state_size < sizeof(*p)); 48 49 net = get_proc_net(inode); 50 if (!net) 51 return -ENXIO; 52 53 p = __seq_open_private(file, PDE(inode)->seq_ops, state_size); 54 if (!p) { 55 put_net(net); 56 return -ENOMEM; 57 } 58 #ifdef CONFIG_NET_NS 59 p->net = net; 60 #endif 61 return 0; 62 } 63 64 static int seq_release_net(struct inode *ino, struct file *f) 65 { 66 struct seq_file *seq = f->private_data; 67 68 put_net(seq_file_net(seq)); 69 seq_release_private(ino, f); 70 return 0; 71 } 72 73 static const struct file_operations proc_net_seq_fops = { 74 .open = seq_open_net, 75 .read = seq_read, 76 .llseek = seq_lseek, 77 .release = seq_release_net, 78 }; 79 80 struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode, 81 struct proc_dir_entry *parent, const struct seq_operations *ops, 82 unsigned int state_size, void *data) 83 { 84 struct proc_dir_entry *p; 85 86 p = proc_create_reg(name, mode, &parent, data); 87 if (!p) 88 return NULL; 89 p->proc_fops = &proc_net_seq_fops; 90 p->seq_ops = ops; 91 p->state_size = state_size; 92 return proc_register(parent, p); 93 } 94 EXPORT_SYMBOL_GPL(proc_create_net_data); 95 96 static int single_open_net(struct inode *inode, struct file *file) 97 { 98 struct proc_dir_entry *de = PDE(inode); 99 struct net *net; 100 int err; 101 102 net = get_proc_net(inode); 103 if (!net) 104 return -ENXIO; 105 106 err = single_open(file, de->single_show, net); 107 if (err) 108 put_net(net); 109 return err; 110 } 111 112 static int single_release_net(struct inode *ino, struct file *f) 113 { 114 struct seq_file *seq = f->private_data; 115 put_net(seq->private); 116 return single_release(ino, f); 117 } 118 119 static const struct file_operations proc_net_single_fops = { 120 .open = single_open_net, 121 .read = seq_read, 122 .llseek = seq_lseek, 123 .release = single_release_net, 124 }; 125 126 struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode, 127 struct proc_dir_entry *parent, 128 int (*show)(struct seq_file *, void *), void *data) 129 { 130 struct proc_dir_entry *p; 131 132 p = proc_create_reg(name, mode, &parent, data); 133 if (!p) 134 return NULL; 135 p->proc_fops = &proc_net_single_fops; 136 p->single_show = show; 137 return proc_register(parent, p); 138 } 139 EXPORT_SYMBOL_GPL(proc_create_net_single); 140 141 static struct net *get_proc_task_net(struct inode *dir) 142 { 143 struct task_struct *task; 144 struct nsproxy *ns; 145 struct net *net = NULL; 146 147 rcu_read_lock(); 148 task = pid_task(proc_pid(dir), PIDTYPE_PID); 149 if (task != NULL) { 150 task_lock(task); 151 ns = task->nsproxy; 152 if (ns != NULL) 153 net = get_net(ns->net_ns); 154 task_unlock(task); 155 } 156 rcu_read_unlock(); 157 158 return net; 159 } 160 161 static struct dentry *proc_tgid_net_lookup(struct inode *dir, 162 struct dentry *dentry, unsigned int flags) 163 { 164 struct dentry *de; 165 struct net *net; 166 167 de = ERR_PTR(-ENOENT); 168 net = get_proc_task_net(dir); 169 if (net != NULL) { 170 de = proc_lookup_de(dir, dentry, net->proc_net); 171 put_net(net); 172 } 173 return de; 174 } 175 176 static int proc_tgid_net_getattr(const struct path *path, struct kstat *stat, 177 u32 request_mask, unsigned int query_flags) 178 { 179 struct inode *inode = d_inode(path->dentry); 180 struct net *net; 181 182 net = get_proc_task_net(inode); 183 184 generic_fillattr(inode, stat); 185 186 if (net != NULL) { 187 stat->nlink = net->proc_net->nlink; 188 put_net(net); 189 } 190 191 return 0; 192 } 193 194 const struct inode_operations proc_net_inode_operations = { 195 .lookup = proc_tgid_net_lookup, 196 .getattr = proc_tgid_net_getattr, 197 }; 198 199 static int proc_tgid_net_readdir(struct file *file, struct dir_context *ctx) 200 { 201 int ret; 202 struct net *net; 203 204 ret = -EINVAL; 205 net = get_proc_task_net(file_inode(file)); 206 if (net != NULL) { 207 ret = proc_readdir_de(file, ctx, net->proc_net); 208 put_net(net); 209 } 210 return ret; 211 } 212 213 const struct file_operations proc_net_operations = { 214 .llseek = generic_file_llseek, 215 .read = generic_read_dir, 216 .iterate_shared = proc_tgid_net_readdir, 217 }; 218 219 static __net_init int proc_net_ns_init(struct net *net) 220 { 221 struct proc_dir_entry *netd, *net_statd; 222 kuid_t uid; 223 kgid_t gid; 224 int err; 225 226 err = -ENOMEM; 227 netd = kmem_cache_zalloc(proc_dir_entry_cache, GFP_KERNEL); 228 if (!netd) 229 goto out; 230 231 netd->subdir = RB_ROOT; 232 netd->data = net; 233 netd->nlink = 2; 234 netd->namelen = 3; 235 netd->parent = &proc_root; 236 netd->name = netd->inline_name; 237 memcpy(netd->name, "net", 4); 238 239 uid = make_kuid(net->user_ns, 0); 240 if (!uid_valid(uid)) 241 uid = netd->uid; 242 243 gid = make_kgid(net->user_ns, 0); 244 if (!gid_valid(gid)) 245 gid = netd->gid; 246 247 proc_set_user(netd, uid, gid); 248 249 err = -EEXIST; 250 net_statd = proc_net_mkdir(net, "stat", netd); 251 if (!net_statd) 252 goto free_net; 253 254 net->proc_net = netd; 255 net->proc_net_stat = net_statd; 256 return 0; 257 258 free_net: 259 pde_free(netd); 260 out: 261 return err; 262 } 263 264 static __net_exit void proc_net_ns_exit(struct net *net) 265 { 266 remove_proc_entry("stat", net->proc_net); 267 pde_free(net->proc_net); 268 } 269 270 static struct pernet_operations __net_initdata proc_net_ns_ops = { 271 .init = proc_net_ns_init, 272 .exit = proc_net_ns_exit, 273 }; 274 275 int __init proc_net_init(void) 276 { 277 proc_symlink("net", NULL, "self/net"); 278 279 return register_pernet_subsys(&proc_net_ns_ops); 280 } 281