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