1 // SPDX-License-Identifier: GPL-2.0-only
7 * Author: Eric Biederman <ebiederm@xmission.com>
9 * proc net directory handling functions
11 #include <linux/errno.h>
12 #include <linux/time.h>
13 #include <linux/proc_fs.h>
14 #include <linux/stat.h>
15 #include <linux/slab.h>
16 #include <linux/init.h>
17 #include <linux/sched.h>
18 #include <linux/sched/task.h>
19 #include <linux/module.h>
20 #include <linux/bitops.h>
21 #include <linux/mount.h>
22 #include <linux/nsproxy.h>
23 #include <linux/uidgid.h>
24 #include <net/net_namespace.h>
25 #include <linux/seq_file.h>
29 static inline struct net
*PDE_NET(struct proc_dir_entry
*pde
)
31 return pde
->parent
->data
;
34 static struct net
*get_proc_net(const struct inode
*inode
)
36 return maybe_get_net(PDE_NET(PDE(inode
)));
39 static int seq_open_net(struct inode
*inode
, struct file
*file
)
41 unsigned int state_size
= PDE(inode
)->state_size
;
42 struct seq_net_private
*p
;
45 WARN_ON_ONCE(state_size
< sizeof(*p
));
47 if (file
->f_mode
& FMODE_WRITE
&& !PDE(inode
)->write
)
50 net
= get_proc_net(inode
);
54 p
= __seq_open_private(file
, PDE(inode
)->seq_ops
, state_size
);
61 netns_tracker_alloc(net
, &p
->ns_tracker
, GFP_KERNEL
);
66 static void seq_file_net_put_net(struct seq_file
*seq
)
69 struct seq_net_private
*priv
= seq
->private;
71 put_net_track(priv
->net
, &priv
->ns_tracker
);
77 static int seq_release_net(struct inode
*ino
, struct file
*f
)
79 struct seq_file
*seq
= f
->private_data
;
81 seq_file_net_put_net(seq
);
82 seq_release_private(ino
, f
);
86 static const struct proc_ops proc_net_seq_ops
= {
87 .proc_open
= seq_open_net
,
88 .proc_read
= seq_read
,
89 .proc_write
= proc_simple_write
,
90 .proc_lseek
= seq_lseek
,
91 .proc_release
= seq_release_net
,
94 int bpf_iter_init_seq_net(void *priv_data
, struct bpf_iter_aux_info
*aux
)
97 struct seq_net_private
*p
= priv_data
;
99 p
->net
= get_net_track(current
->nsproxy
->net_ns
, &p
->ns_tracker
,
105 void bpf_iter_fini_seq_net(void *priv_data
)
108 struct seq_net_private
*p
= priv_data
;
110 put_net_track(p
->net
, &p
->ns_tracker
);
114 struct proc_dir_entry
*proc_create_net_data(const char *name
, umode_t mode
,
115 struct proc_dir_entry
*parent
, const struct seq_operations
*ops
,
116 unsigned int state_size
, void *data
)
118 struct proc_dir_entry
*p
;
120 p
= proc_create_reg(name
, mode
, &parent
, data
);
124 p
->proc_ops
= &proc_net_seq_ops
;
126 p
->state_size
= state_size
;
127 return proc_register(parent
, p
);
129 EXPORT_SYMBOL_GPL(proc_create_net_data
);
132 * proc_create_net_data_write - Create a writable net_ns-specific proc file
133 * @name: The name of the file.
134 * @mode: The file's access mode.
135 * @parent: The parent directory in which to create.
136 * @ops: The seq_file ops with which to read the file.
137 * @write: The write method with which to 'modify' the file.
138 * @data: Data for retrieval by pde_data().
140 * Create a network namespaced proc file in the @parent directory with the
141 * specified @name and @mode that allows reading of a file that displays a
142 * series of elements and also provides for the file accepting writes that have
143 * some arbitrary effect.
145 * The functions in the @ops table are used to iterate over items to be
146 * presented and extract the readable content using the seq_file interface.
148 * The @write function is called with the data copied into a kernel space
149 * scratch buffer and has a NUL appended for convenience. The buffer may be
150 * modified by the @write function. @write should return 0 on success.
152 * The @data value is accessible from the @show and @write functions by calling
153 * pde_data() on the file inode. The network namespace must be accessed by
154 * calling seq_file_net() on the seq_file struct.
156 struct proc_dir_entry
*proc_create_net_data_write(const char *name
, umode_t mode
,
157 struct proc_dir_entry
*parent
,
158 const struct seq_operations
*ops
,
160 unsigned int state_size
, void *data
)
162 struct proc_dir_entry
*p
;
164 p
= proc_create_reg(name
, mode
, &parent
, data
);
168 p
->proc_ops
= &proc_net_seq_ops
;
170 p
->state_size
= state_size
;
172 return proc_register(parent
, p
);
174 EXPORT_SYMBOL_GPL(proc_create_net_data_write
);
176 static int single_open_net(struct inode
*inode
, struct file
*file
)
178 struct proc_dir_entry
*de
= PDE(inode
);
182 net
= get_proc_net(inode
);
186 err
= single_open(file
, de
->single_show
, net
);
192 static int single_release_net(struct inode
*ino
, struct file
*f
)
194 struct seq_file
*seq
= f
->private_data
;
195 put_net(seq
->private);
196 return single_release(ino
, f
);
199 static const struct proc_ops proc_net_single_ops
= {
200 .proc_open
= single_open_net
,
201 .proc_read
= seq_read
,
202 .proc_write
= proc_simple_write
,
203 .proc_lseek
= seq_lseek
,
204 .proc_release
= single_release_net
,
207 struct proc_dir_entry
*proc_create_net_single(const char *name
, umode_t mode
,
208 struct proc_dir_entry
*parent
,
209 int (*show
)(struct seq_file
*, void *), void *data
)
211 struct proc_dir_entry
*p
;
213 p
= proc_create_reg(name
, mode
, &parent
, data
);
217 p
->proc_ops
= &proc_net_single_ops
;
218 p
->single_show
= show
;
219 return proc_register(parent
, p
);
221 EXPORT_SYMBOL_GPL(proc_create_net_single
);
224 * proc_create_net_single_write - Create a writable net_ns-specific proc file
225 * @name: The name of the file.
226 * @mode: The file's access mode.
227 * @parent: The parent directory in which to create.
228 * @show: The seqfile show method with which to read the file.
229 * @write: The write method with which to 'modify' the file.
230 * @data: Data for retrieval by pde_data().
232 * Create a network-namespaced proc file in the @parent directory with the
233 * specified @name and @mode that allows reading of a file that displays a
234 * single element rather than a series and also provides for the file accepting
235 * writes that have some arbitrary effect.
237 * The @show function is called to extract the readable content via the
238 * seq_file interface.
240 * The @write function is called with the data copied into a kernel space
241 * scratch buffer and has a NUL appended for convenience. The buffer may be
242 * modified by the @write function. @write should return 0 on success.
244 * The @data value is accessible from the @show and @write functions by calling
245 * pde_data() on the file inode. The network namespace must be accessed by
246 * calling seq_file_single_net() on the seq_file struct.
248 struct proc_dir_entry
*proc_create_net_single_write(const char *name
, umode_t mode
,
249 struct proc_dir_entry
*parent
,
250 int (*show
)(struct seq_file
*, void *),
254 struct proc_dir_entry
*p
;
256 p
= proc_create_reg(name
, mode
, &parent
, data
);
260 p
->proc_ops
= &proc_net_single_ops
;
261 p
->single_show
= show
;
263 return proc_register(parent
, p
);
265 EXPORT_SYMBOL_GPL(proc_create_net_single_write
);
267 static struct net
*get_proc_task_net(struct inode
*dir
)
269 struct task_struct
*task
;
271 struct net
*net
= NULL
;
274 task
= pid_task(proc_pid(dir
), PIDTYPE_PID
);
279 net
= get_net(ns
->net_ns
);
287 static struct dentry
*proc_tgid_net_lookup(struct inode
*dir
,
288 struct dentry
*dentry
, unsigned int flags
)
293 de
= ERR_PTR(-ENOENT
);
294 net
= get_proc_task_net(dir
);
296 de
= proc_lookup_de(dir
, dentry
, net
->proc_net
);
302 static int proc_tgid_net_getattr(struct user_namespace
*mnt_userns
,
303 const struct path
*path
, struct kstat
*stat
,
304 u32 request_mask
, unsigned int query_flags
)
306 struct inode
*inode
= d_inode(path
->dentry
);
309 net
= get_proc_task_net(inode
);
311 generic_fillattr(&init_user_ns
, inode
, stat
);
314 stat
->nlink
= net
->proc_net
->nlink
;
321 const struct inode_operations proc_net_inode_operations
= {
322 .lookup
= proc_tgid_net_lookup
,
323 .getattr
= proc_tgid_net_getattr
,
326 static int proc_tgid_net_readdir(struct file
*file
, struct dir_context
*ctx
)
332 net
= get_proc_task_net(file_inode(file
));
334 ret
= proc_readdir_de(file
, ctx
, net
->proc_net
);
340 const struct file_operations proc_net_operations
= {
341 .llseek
= generic_file_llseek
,
342 .read
= generic_read_dir
,
343 .iterate_shared
= proc_tgid_net_readdir
,
346 static __net_init
int proc_net_ns_init(struct net
*net
)
348 struct proc_dir_entry
*netd
, *net_statd
;
354 * This PDE acts only as an anchor for /proc/${pid}/net hierarchy.
355 * Corresponding inode (PDE(inode) == net->proc_net) is never
356 * instantiated therefore blanket zeroing is fine.
357 * net->proc_net_stat inode is instantiated normally.
360 netd
= kmem_cache_zalloc(proc_dir_entry_cache
, GFP_KERNEL
);
364 netd
->subdir
= RB_ROOT
;
368 netd
->parent
= &proc_root
;
369 netd
->name
= netd
->inline_name
;
370 memcpy(netd
->name
, "net", 4);
372 uid
= make_kuid(net
->user_ns
, 0);
376 gid
= make_kgid(net
->user_ns
, 0);
380 proc_set_user(netd
, uid
, gid
);
382 /* Seed dentry revalidation for /proc/${pid}/net */
383 pde_force_lookup(netd
);
386 net_statd
= proc_net_mkdir(net
, "stat", netd
);
390 net
->proc_net
= netd
;
391 net
->proc_net_stat
= net_statd
;
400 static __net_exit
void proc_net_ns_exit(struct net
*net
)
402 remove_proc_entry("stat", net
->proc_net
);
403 pde_free(net
->proc_net
);
406 static struct pernet_operations __net_initdata proc_net_ns_ops
= {
407 .init
= proc_net_ns_init
,
408 .exit
= proc_net_ns_exit
,
411 int __init
proc_net_init(void)
413 proc_symlink("net", NULL
, "self/net");
415 return register_pernet_subsys(&proc_net_ns_ops
);