6 * Author: Eric Biederman <ebiederm@xmission.com>
8 * proc net directory handling functions
11 #include <linux/uaccess.h>
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>
31 static inline struct net
*PDE_NET(struct proc_dir_entry
*pde
)
33 return pde
->parent
->data
;
36 static struct net
*get_proc_net(const struct inode
*inode
)
38 return maybe_get_net(PDE_NET(PDE(inode
)));
41 static int seq_open_net(struct inode
*inode
, struct file
*file
)
43 unsigned int state_size
= PDE(inode
)->state_size
;
44 struct seq_net_private
*p
;
47 WARN_ON_ONCE(state_size
< sizeof(*p
));
49 if (file
->f_mode
& FMODE_WRITE
&& !PDE(inode
)->write
)
52 net
= get_proc_net(inode
);
56 p
= __seq_open_private(file
, PDE(inode
)->seq_ops
, state_size
);
67 static int seq_release_net(struct inode
*ino
, struct file
*f
)
69 struct seq_file
*seq
= f
->private_data
;
71 put_net(seq_file_net(seq
));
72 seq_release_private(ino
, f
);
76 static const struct file_operations proc_net_seq_fops
= {
79 .write
= proc_simple_write
,
81 .release
= seq_release_net
,
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
)
88 struct proc_dir_entry
*p
;
90 p
= proc_create_reg(name
, mode
, &parent
, data
);
93 p
->proc_fops
= &proc_net_seq_fops
;
95 p
->state_size
= state_size
;
96 return proc_register(parent
, p
);
98 EXPORT_SYMBOL_GPL(proc_create_net_data
);
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().
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.
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.
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.
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.
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
,
129 unsigned int state_size
, void *data
)
131 struct proc_dir_entry
*p
;
133 p
= proc_create_reg(name
, mode
, &parent
, data
);
136 p
->proc_fops
= &proc_net_seq_fops
;
138 p
->state_size
= state_size
;
140 return proc_register(parent
, p
);
142 EXPORT_SYMBOL_GPL(proc_create_net_data_write
);
144 static int single_open_net(struct inode
*inode
, struct file
*file
)
146 struct proc_dir_entry
*de
= PDE(inode
);
150 net
= get_proc_net(inode
);
154 err
= single_open(file
, de
->single_show
, net
);
160 static int single_release_net(struct inode
*ino
, struct file
*f
)
162 struct seq_file
*seq
= f
->private_data
;
163 put_net(seq
->private);
164 return single_release(ino
, f
);
167 static const struct file_operations proc_net_single_fops
= {
168 .open
= single_open_net
,
170 .write
= proc_simple_write
,
172 .release
= single_release_net
,
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
)
179 struct proc_dir_entry
*p
;
181 p
= proc_create_reg(name
, mode
, &parent
, data
);
184 p
->proc_fops
= &proc_net_single_fops
;
185 p
->single_show
= show
;
186 return proc_register(parent
, p
);
188 EXPORT_SYMBOL_GPL(proc_create_net_single
);
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().
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.
204 * The @show function is called to extract the readable content via the
205 * seq_file interface.
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.
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.
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 *),
221 struct proc_dir_entry
*p
;
223 p
= proc_create_reg(name
, mode
, &parent
, data
);
226 p
->proc_fops
= &proc_net_single_fops
;
227 p
->single_show
= show
;
229 return proc_register(parent
, p
);
231 EXPORT_SYMBOL_GPL(proc_create_net_single_write
);
233 static struct net
*get_proc_task_net(struct inode
*dir
)
235 struct task_struct
*task
;
237 struct net
*net
= NULL
;
240 task
= pid_task(proc_pid(dir
), PIDTYPE_PID
);
245 net
= get_net(ns
->net_ns
);
253 static struct dentry
*proc_tgid_net_lookup(struct inode
*dir
,
254 struct dentry
*dentry
, unsigned int flags
)
259 de
= ERR_PTR(-ENOENT
);
260 net
= get_proc_task_net(dir
);
262 de
= proc_lookup_de(dir
, dentry
, net
->proc_net
);
268 static int proc_tgid_net_getattr(const struct path
*path
, struct kstat
*stat
,
269 u32 request_mask
, unsigned int query_flags
)
271 struct inode
*inode
= d_inode(path
->dentry
);
274 net
= get_proc_task_net(inode
);
276 generic_fillattr(inode
, stat
);
279 stat
->nlink
= net
->proc_net
->nlink
;
286 const struct inode_operations proc_net_inode_operations
= {
287 .lookup
= proc_tgid_net_lookup
,
288 .getattr
= proc_tgid_net_getattr
,
291 static int proc_tgid_net_readdir(struct file
*file
, struct dir_context
*ctx
)
297 net
= get_proc_task_net(file_inode(file
));
299 ret
= proc_readdir_de(file
, ctx
, net
->proc_net
);
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
,
311 static __net_init
int proc_net_ns_init(struct net
*net
)
313 struct proc_dir_entry
*netd
, *net_statd
;
319 netd
= kmem_cache_zalloc(proc_dir_entry_cache
, GFP_KERNEL
);
323 netd
->subdir
= RB_ROOT
;
327 netd
->parent
= &proc_root
;
328 netd
->name
= netd
->inline_name
;
329 memcpy(netd
->name
, "net", 4);
331 uid
= make_kuid(net
->user_ns
, 0);
335 gid
= make_kgid(net
->user_ns
, 0);
339 proc_set_user(netd
, uid
, gid
);
342 net_statd
= proc_net_mkdir(net
, "stat", netd
);
346 net
->proc_net
= netd
;
347 net
->proc_net_stat
= net_statd
;
356 static __net_exit
void proc_net_ns_exit(struct net
*net
)
358 remove_proc_entry("stat", net
->proc_net
);
359 pde_free(net
->proc_net
);
362 static struct pernet_operations __net_initdata proc_net_ns_ops
= {
363 .init
= proc_net_ns_init
,
364 .exit
= proc_net_ns_exit
,
367 int __init
proc_net_init(void)
369 proc_symlink("net", NULL
, "self/net");
371 return register_pernet_subsys(&proc_net_ns_ops
);