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 * @state_size: The size of the per-file private state to allocate.
139 * @data: Data for retrieval by pde_data().
141 * Create a network namespaced proc file in the @parent directory with the
142 * specified @name and @mode that allows reading of a file that displays a
143 * series of elements and also provides for the file accepting writes that have
144 * some arbitrary effect.
146 * The functions in the @ops table are used to iterate over items to be
147 * presented and extract the readable content using the seq_file interface.
149 * The @write function is called with the data copied into a kernel space
150 * scratch buffer and has a NUL appended for convenience. The buffer may be
151 * modified by the @write function. @write should return 0 on success.
153 * The @data value is accessible from the @show and @write functions by calling
154 * pde_data() on the file inode. The network namespace must be accessed by
155 * calling seq_file_net() on the seq_file struct.
157 struct proc_dir_entry
*proc_create_net_data_write(const char *name
, umode_t mode
,
158 struct proc_dir_entry
*parent
,
159 const struct seq_operations
*ops
,
161 unsigned int state_size
, void *data
)
163 struct proc_dir_entry
*p
;
165 p
= proc_create_reg(name
, mode
, &parent
, data
);
169 p
->proc_ops
= &proc_net_seq_ops
;
171 p
->state_size
= state_size
;
173 return proc_register(parent
, p
);
175 EXPORT_SYMBOL_GPL(proc_create_net_data_write
);
177 static int single_open_net(struct inode
*inode
, struct file
*file
)
179 struct proc_dir_entry
*de
= PDE(inode
);
183 net
= get_proc_net(inode
);
187 err
= single_open(file
, de
->single_show
, net
);
193 static int single_release_net(struct inode
*ino
, struct file
*f
)
195 struct seq_file
*seq
= f
->private_data
;
196 put_net(seq
->private);
197 return single_release(ino
, f
);
200 static const struct proc_ops proc_net_single_ops
= {
201 .proc_open
= single_open_net
,
202 .proc_read
= seq_read
,
203 .proc_write
= proc_simple_write
,
204 .proc_lseek
= seq_lseek
,
205 .proc_release
= single_release_net
,
208 struct proc_dir_entry
*proc_create_net_single(const char *name
, umode_t mode
,
209 struct proc_dir_entry
*parent
,
210 int (*show
)(struct seq_file
*, void *), void *data
)
212 struct proc_dir_entry
*p
;
214 p
= proc_create_reg(name
, mode
, &parent
, data
);
218 p
->proc_ops
= &proc_net_single_ops
;
219 p
->single_show
= show
;
220 return proc_register(parent
, p
);
222 EXPORT_SYMBOL_GPL(proc_create_net_single
);
225 * proc_create_net_single_write - Create a writable net_ns-specific proc file
226 * @name: The name of the file.
227 * @mode: The file's access mode.
228 * @parent: The parent directory in which to create.
229 * @show: The seqfile show method with which to read the file.
230 * @write: The write method with which to 'modify' the file.
231 * @data: Data for retrieval by pde_data().
233 * Create a network-namespaced proc file in the @parent directory with the
234 * specified @name and @mode that allows reading of a file that displays a
235 * single element rather than a series and also provides for the file accepting
236 * writes that have some arbitrary effect.
238 * The @show function is called to extract the readable content via the
239 * seq_file interface.
241 * The @write function is called with the data copied into a kernel space
242 * scratch buffer and has a NUL appended for convenience. The buffer may be
243 * modified by the @write function. @write should return 0 on success.
245 * The @data value is accessible from the @show and @write functions by calling
246 * pde_data() on the file inode. The network namespace must be accessed by
247 * calling seq_file_single_net() on the seq_file struct.
249 struct proc_dir_entry
*proc_create_net_single_write(const char *name
, umode_t mode
,
250 struct proc_dir_entry
*parent
,
251 int (*show
)(struct seq_file
*, void *),
255 struct proc_dir_entry
*p
;
257 p
= proc_create_reg(name
, mode
, &parent
, data
);
261 p
->proc_ops
= &proc_net_single_ops
;
262 p
->single_show
= show
;
264 return proc_register(parent
, p
);
266 EXPORT_SYMBOL_GPL(proc_create_net_single_write
);
268 static struct net
*get_proc_task_net(struct inode
*dir
)
270 struct task_struct
*task
;
272 struct net
*net
= NULL
;
275 task
= pid_task(proc_pid(dir
), PIDTYPE_PID
);
280 net
= get_net(ns
->net_ns
);
288 static struct dentry
*proc_tgid_net_lookup(struct inode
*dir
,
289 struct dentry
*dentry
, unsigned int flags
)
294 de
= ERR_PTR(-ENOENT
);
295 net
= get_proc_task_net(dir
);
297 de
= proc_lookup_de(dir
, dentry
, net
->proc_net
);
303 static int proc_tgid_net_getattr(struct mnt_idmap
*idmap
,
304 const struct path
*path
, struct kstat
*stat
,
305 u32 request_mask
, unsigned int query_flags
)
307 struct inode
*inode
= d_inode(path
->dentry
);
310 net
= get_proc_task_net(inode
);
312 generic_fillattr(&nop_mnt_idmap
, request_mask
, inode
, stat
);
315 stat
->nlink
= net
->proc_net
->nlink
;
322 const struct inode_operations proc_net_inode_operations
= {
323 .lookup
= proc_tgid_net_lookup
,
324 .getattr
= proc_tgid_net_getattr
,
325 .setattr
= proc_setattr
,
328 static int proc_tgid_net_readdir(struct file
*file
, struct dir_context
*ctx
)
334 net
= get_proc_task_net(file_inode(file
));
336 ret
= proc_readdir_de(file
, ctx
, net
->proc_net
);
342 const struct file_operations proc_net_operations
= {
343 .llseek
= generic_file_llseek
,
344 .read
= generic_read_dir
,
345 .iterate_shared
= proc_tgid_net_readdir
,
348 static __net_init
int proc_net_ns_init(struct net
*net
)
350 struct proc_dir_entry
*netd
, *net_statd
;
356 * This PDE acts only as an anchor for /proc/${pid}/net hierarchy.
357 * Corresponding inode (PDE(inode) == net->proc_net) is never
358 * instantiated therefore blanket zeroing is fine.
359 * net->proc_net_stat inode is instantiated normally.
362 netd
= kmem_cache_zalloc(proc_dir_entry_cache
, GFP_KERNEL
);
366 netd
->subdir
= RB_ROOT
;
370 netd
->parent
= &proc_root
;
371 netd
->name
= netd
->inline_name
;
372 memcpy(netd
->name
, "net", 4);
374 uid
= make_kuid(net
->user_ns
, 0);
378 gid
= make_kgid(net
->user_ns
, 0);
382 proc_set_user(netd
, uid
, gid
);
384 /* Seed dentry revalidation for /proc/${pid}/net */
385 pde_force_lookup(netd
);
388 net_statd
= proc_net_mkdir(net
, "stat", netd
);
392 net
->proc_net
= netd
;
393 net
->proc_net_stat
= net_statd
;
402 static __net_exit
void proc_net_ns_exit(struct net
*net
)
404 remove_proc_entry("stat", net
->proc_net
);
405 pde_free(net
->proc_net
);
408 static struct pernet_operations __net_initdata proc_net_ns_ops
= {
409 .init
= proc_net_ns_init
,
410 .exit
= proc_net_ns_exit
,
413 int __init
proc_net_init(void)
415 proc_symlink("net", NULL
, "self/net");
417 return register_pernet_subsys(&proc_net_ns_ops
);