Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*
3 : : * proc/fs/generic.c --- generic routines for the proc-fs
4 : : *
5 : : * This file contains generic proc-fs routines for handling
6 : : * directories and files.
7 : : *
8 : : * Copyright (C) 1991, 1992 Linus Torvalds.
9 : : * Copyright (C) 1997 Theodore Ts'o
10 : : */
11 : :
12 : : #include <linux/cache.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/mm.h>
18 : : #include <linux/module.h>
19 : : #include <linux/namei.h>
20 : : #include <linux/slab.h>
21 : : #include <linux/printk.h>
22 : : #include <linux/mount.h>
23 : : #include <linux/init.h>
24 : : #include <linux/idr.h>
25 : : #include <linux/bitops.h>
26 : : #include <linux/spinlock.h>
27 : : #include <linux/completion.h>
28 : : #include <linux/uaccess.h>
29 : : #include <linux/seq_file.h>
30 : :
31 : : #include "internal.h"
32 : :
33 : : static DEFINE_RWLOCK(proc_subdir_lock);
34 : :
35 : : struct kmem_cache *proc_dir_entry_cache __ro_after_init;
36 : :
37 : 1212 : void pde_free(struct proc_dir_entry *pde)
38 : : {
39 [ - + ]: 1212 : if (S_ISLNK(pde->mode))
40 : 0 : kfree(pde->data);
41 [ - + ]: 1212 : if (pde->name != pde->inline_name)
42 : 0 : kfree(pde->name);
43 : 1212 : kmem_cache_free(proc_dir_entry_cache, pde);
44 : 1212 : }
45 : :
46 : : static int proc_match(const char *name, struct proc_dir_entry *de, unsigned int len)
47 : : {
48 [ + + + + ]: 1913716 : if (len < de->namelen)
49 : : return -1;
50 [ + + + + ]: 1424036 : if (len > de->namelen)
51 : : return 1;
52 : :
53 : 622974 : return memcmp(name, de->name, len);
54 : : }
55 : :
56 : : static struct proc_dir_entry *pde_subdir_first(struct proc_dir_entry *dir)
57 : : {
58 [ - + # # : 1212 : return rb_entry_safe(rb_first(&dir->subdir), struct proc_dir_entry,
# # # # ]
59 : : subdir_node);
60 : : }
61 : :
62 : : static struct proc_dir_entry *pde_subdir_next(struct proc_dir_entry *dir)
63 : : {
64 [ # # # # ]: 0 : return rb_entry_safe(rb_next(&dir->subdir_node), struct proc_dir_entry,
65 : : subdir_node);
66 : : }
67 : :
68 : 66960 : static struct proc_dir_entry *pde_subdir_find(struct proc_dir_entry *dir,
69 : : const char *name,
70 : : unsigned int len)
71 : : {
72 : 66960 : struct rb_node *node = dir->subdir.rb_node;
73 : :
74 [ + + ]: 427038 : while (node) {
75 : 324256 : struct proc_dir_entry *de = rb_entry(node,
76 : : struct proc_dir_entry,
77 : : subdir_node);
78 : : int result = proc_match(name, de, len);
79 : :
80 [ + + ]: 324256 : if (result < 0)
81 : 183030 : node = node->rb_left;
82 [ + + ]: 141226 : else if (result > 0)
83 : 110088 : node = node->rb_right;
84 : : else
85 : 31138 : return de;
86 : : }
87 : : return NULL;
88 : : }
89 : :
90 : 556860 : static bool pde_subdir_insert(struct proc_dir_entry *dir,
91 : : struct proc_dir_entry *de)
92 : : {
93 : 556860 : struct rb_root *root = &dir->subdir;
94 : 556860 : struct rb_node **new = &root->rb_node, *parent = NULL;
95 : :
96 : : /* Figure out where to put new node */
97 [ + + ]: 2703180 : while (*new) {
98 : : struct proc_dir_entry *this = rb_entry(*new,
99 : : struct proc_dir_entry,
100 : : subdir_node);
101 : 1589460 : int result = proc_match(de->name, this, de->namelen);
102 : :
103 : : parent = *new;
104 [ + + ]: 1589460 : if (result < 0)
105 : 401406 : new = &(*new)->rb_left;
106 [ + - ]: 1188054 : else if (result > 0)
107 : 1188054 : new = &(*new)->rb_right;
108 : : else
109 : : return false;
110 : : }
111 : :
112 : : /* Add new node and rebalance tree. */
113 : 556860 : rb_link_node(&de->subdir_node, parent, new);
114 : 556860 : rb_insert_color(&de->subdir_node, root);
115 : 556860 : return true;
116 : : }
117 : :
118 : 0 : static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
119 : : {
120 : : struct inode *inode = d_inode(dentry);
121 : : struct proc_dir_entry *de = PDE(inode);
122 : : int error;
123 : :
124 : 0 : error = setattr_prepare(dentry, iattr);
125 [ # # ]: 0 : if (error)
126 : : return error;
127 : :
128 : 0 : setattr_copy(inode, iattr);
129 : : mark_inode_dirty(inode);
130 : :
131 : : proc_set_user(de, inode->i_uid, inode->i_gid);
132 : 0 : de->mode = inode->i_mode;
133 : 0 : return 0;
134 : : }
135 : :
136 : 2424 : static int proc_getattr(const struct path *path, struct kstat *stat,
137 : : u32 request_mask, unsigned int query_flags)
138 : : {
139 : 2424 : struct inode *inode = d_inode(path->dentry);
140 : : struct proc_dir_entry *de = PDE(inode);
141 [ + - + - ]: 2424 : if (de && de->nlink)
142 : 2424 : set_nlink(inode, de->nlink);
143 : :
144 : 2424 : generic_fillattr(inode, stat);
145 : 2424 : return 0;
146 : : }
147 : :
148 : : static const struct inode_operations proc_file_inode_operations = {
149 : : .setattr = proc_notify_change,
150 : : };
151 : :
152 : : /*
153 : : * This function parses a name such as "tty/driver/serial", and
154 : : * returns the struct proc_dir_entry for "/proc/tty/driver", and
155 : : * returns "serial" in residual.
156 : : */
157 : 558072 : static int __xlate_proc_name(const char *name, struct proc_dir_entry **ret,
158 : : const char **residual)
159 : : {
160 : : const char *cp = name, *next;
161 : : struct proc_dir_entry *de;
162 : : unsigned int len;
163 : :
164 : 558072 : de = *ret;
165 [ + + ]: 558072 : if (!de)
166 : : de = &proc_root;
167 : :
168 : : while (1) {
169 : 568980 : next = strchr(cp, '/');
170 [ + + ]: 568980 : if (!next)
171 : : break;
172 : :
173 : 10908 : len = next - cp;
174 : 10908 : de = pde_subdir_find(de, cp, len);
175 [ - + ]: 10908 : if (!de) {
176 : 0 : WARN(1, "name '%s'\n", name);
177 : 0 : return -ENOENT;
178 : : }
179 : 10908 : cp += len + 1;
180 : 10908 : }
181 : 558072 : *residual = cp;
182 : 558072 : *ret = de;
183 : 558072 : return 0;
184 : : }
185 : :
186 : 556860 : static int xlate_proc_name(const char *name, struct proc_dir_entry **ret,
187 : : const char **residual)
188 : : {
189 : : int rv;
190 : :
191 : 556860 : read_lock(&proc_subdir_lock);
192 : 556860 : rv = __xlate_proc_name(name, ret, residual);
193 : : read_unlock(&proc_subdir_lock);
194 : 556860 : return rv;
195 : : }
196 : :
197 : : static DEFINE_IDA(proc_inum_ida);
198 : :
199 : : #define PROC_DYNAMIC_FIRST 0xF0000000U
200 : :
201 : : /*
202 : : * Return an inode number between PROC_DYNAMIC_FIRST and
203 : : * 0xffffffff, or zero on failure.
204 : : */
205 : 559700 : int proc_alloc_inum(unsigned int *inum)
206 : : {
207 : : int i;
208 : :
209 : 559700 : i = ida_simple_get(&proc_inum_ida, 0, UINT_MAX - PROC_DYNAMIC_FIRST + 1,
210 : : GFP_KERNEL);
211 [ + - ]: 559700 : if (i < 0)
212 : : return i;
213 : :
214 : 559700 : *inum = PROC_DYNAMIC_FIRST + (unsigned int)i;
215 : 559700 : return 0;
216 : : }
217 : :
218 : 4 : void proc_free_inum(unsigned int inum)
219 : : {
220 : 1216 : ida_simple_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST);
221 : 4 : }
222 : :
223 : 487400 : static int proc_misc_d_revalidate(struct dentry *dentry, unsigned int flags)
224 : : {
225 [ + + ]: 487400 : if (flags & LOOKUP_RCU)
226 : : return -ECHILD;
227 : :
228 [ + - ]: 243694 : if (atomic_read(&PDE(d_inode(dentry))->in_use) < 0)
229 : : return 0; /* revalidate */
230 : 243702 : return 1;
231 : : }
232 : :
233 : 189478 : static int proc_misc_d_delete(const struct dentry *dentry)
234 : : {
235 : 189478 : return atomic_read(&PDE(d_inode(dentry))->in_use) < 0;
236 : : }
237 : :
238 : : static const struct dentry_operations proc_misc_dentry_ops = {
239 : : .d_revalidate = proc_misc_d_revalidate,
240 : : .d_delete = proc_misc_d_delete,
241 : : };
242 : :
243 : : /*
244 : : * Don't create negative dentries here, return -ENOENT by hand
245 : : * instead.
246 : : */
247 : 54840 : struct dentry *proc_lookup_de(struct inode *dir, struct dentry *dentry,
248 : : struct proc_dir_entry *de)
249 : : {
250 : : struct inode *inode;
251 : :
252 : 54840 : read_lock(&proc_subdir_lock);
253 : 54840 : de = pde_subdir_find(de, dentry->d_name.name, dentry->d_name.len);
254 [ + + ]: 54840 : if (de) {
255 : : pde_get(de);
256 : : read_unlock(&proc_subdir_lock);
257 : 19024 : inode = proc_get_inode(dir->i_sb, de);
258 [ + - ]: 19024 : if (!inode)
259 : : return ERR_PTR(-ENOMEM);
260 : 19024 : d_set_d_op(dentry, de->proc_dops);
261 : 19024 : return d_splice_alias(inode, dentry);
262 : : }
263 : : read_unlock(&proc_subdir_lock);
264 : 35816 : return ERR_PTR(-ENOENT);
265 : : }
266 : :
267 : 45548 : struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
268 : : unsigned int flags)
269 : : {
270 : 45548 : return proc_lookup_de(dir, dentry, PDE(dir));
271 : : }
272 : :
273 : : /*
274 : : * This returns non-zero if at EOF, so that the /proc
275 : : * root directory can use this and check if it should
276 : : * continue with the <pid> entries..
277 : : *
278 : : * Note that the VFS-layer doesn't care about the return
279 : : * value of the readdir() call, as long as it's non-negative
280 : : * for success..
281 : : */
282 : 0 : int proc_readdir_de(struct file *file, struct dir_context *ctx,
283 : : struct proc_dir_entry *de)
284 : : {
285 : : int i;
286 : :
287 [ # # ]: 0 : if (!dir_emit_dots(file, ctx))
288 : : return 0;
289 : :
290 : 0 : i = ctx->pos - 2;
291 : 0 : read_lock(&proc_subdir_lock);
292 : : de = pde_subdir_first(de);
293 : : for (;;) {
294 [ # # ]: 0 : if (!de) {
295 : : read_unlock(&proc_subdir_lock);
296 : 0 : return 0;
297 : : }
298 [ # # ]: 0 : if (!i)
299 : : break;
300 : : de = pde_subdir_next(de);
301 : 0 : i--;
302 : 0 : }
303 : :
304 : : do {
305 : : struct proc_dir_entry *next;
306 : : pde_get(de);
307 : : read_unlock(&proc_subdir_lock);
308 [ # # ]: 0 : if (!dir_emit(ctx, de->name, de->namelen,
309 : 0 : de->low_ino, de->mode >> 12)) {
310 : 0 : pde_put(de);
311 : 0 : return 0;
312 : : }
313 : 0 : ctx->pos++;
314 : 0 : read_lock(&proc_subdir_lock);
315 : : next = pde_subdir_next(de);
316 : 0 : pde_put(de);
317 : : de = next;
318 [ # # ]: 0 : } while (de);
319 : : read_unlock(&proc_subdir_lock);
320 : 0 : return 1;
321 : : }
322 : :
323 : 0 : int proc_readdir(struct file *file, struct dir_context *ctx)
324 : : {
325 : : struct inode *inode = file_inode(file);
326 : :
327 : 0 : return proc_readdir_de(file, ctx, PDE(inode));
328 : : }
329 : :
330 : : /*
331 : : * These are the generic /proc directory operations. They
332 : : * use the in-memory "struct proc_dir_entry" tree to parse
333 : : * the /proc directory.
334 : : */
335 : : static const struct file_operations proc_dir_operations = {
336 : : .llseek = generic_file_llseek,
337 : : .read = generic_read_dir,
338 : : .iterate_shared = proc_readdir,
339 : : };
340 : :
341 : : /*
342 : : * proc directories can do almost nothing..
343 : : */
344 : : static const struct inode_operations proc_dir_inode_operations = {
345 : : .lookup = proc_lookup,
346 : : .getattr = proc_getattr,
347 : : .setattr = proc_notify_change,
348 : : };
349 : :
350 : : /* returns the registered entry, or frees dp and returns NULL on failure */
351 : 556860 : struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
352 : : struct proc_dir_entry *dp)
353 : : {
354 [ + - ]: 556860 : if (proc_alloc_inum(&dp->low_ino))
355 : : goto out_free_entry;
356 : :
357 : 556860 : write_lock(&proc_subdir_lock);
358 : 556860 : dp->parent = dir;
359 [ - + ]: 556860 : if (pde_subdir_insert(dir, dp) == false) {
360 : 0 : WARN(1, "proc_dir_entry '%s/%s' already registered\n",
361 : : dir->name, dp->name);
362 : : write_unlock(&proc_subdir_lock);
363 : : goto out_free_inum;
364 : : }
365 : : write_unlock(&proc_subdir_lock);
366 : :
367 : 556860 : return dp;
368 : : out_free_inum:
369 : 0 : proc_free_inum(dp->low_ino);
370 : : out_free_entry:
371 : 0 : pde_free(dp);
372 : 0 : return NULL;
373 : : }
374 : :
375 : 556860 : static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
376 : : const char *name,
377 : : umode_t mode,
378 : : nlink_t nlink)
379 : : {
380 : : struct proc_dir_entry *ent = NULL;
381 : : const char *fn;
382 : : struct qstr qstr;
383 : :
384 [ + - ]: 556860 : if (xlate_proc_name(name, parent, &fn) != 0)
385 : : goto out;
386 : 556860 : qstr.name = fn;
387 : 556860 : qstr.len = strlen(fn);
388 [ - + ]: 556860 : if (qstr.len == 0 || qstr.len >= 256) {
389 : 0 : WARN(1, "name len %u\n", qstr.len);
390 : 0 : return NULL;
391 : : }
392 [ - + # # ]: 556860 : if (qstr.len == 1 && fn[0] == '.') {
393 : 0 : WARN(1, "name '.'\n");
394 : 0 : return NULL;
395 : : }
396 [ + + - + : 556860 : if (qstr.len == 2 && fn[0] == '.' && fn[1] == '.') {
# # ]
397 : 0 : WARN(1, "name '..'\n");
398 : 0 : return NULL;
399 : : }
400 [ + + - + ]: 556860 : if (*parent == &proc_root && name_to_int(&qstr) != ~0U) {
401 : 0 : WARN(1, "create '/proc/%s' by hand\n", qstr.name);
402 : 0 : return NULL;
403 : : }
404 [ - + ]: 1113720 : if (is_empty_pde(*parent)) {
405 : 0 : WARN(1, "attempt to add to permanently empty directory");
406 : 0 : return NULL;
407 : : }
408 : :
409 : 556860 : ent = kmem_cache_zalloc(proc_dir_entry_cache, GFP_KERNEL);
410 [ + - ]: 556860 : if (!ent)
411 : : goto out;
412 : :
413 [ + + ]: 556860 : if (qstr.len + 1 <= SIZEOF_PDE_INLINE_NAME) {
414 : 371820 : ent->name = ent->inline_name;
415 : : } else {
416 : 185040 : ent->name = kmalloc(qstr.len + 1, GFP_KERNEL);
417 [ - + ]: 185040 : if (!ent->name) {
418 : 0 : pde_free(ent);
419 : 0 : return NULL;
420 : : }
421 : : }
422 : :
423 : 556860 : memcpy(ent->name, fn, qstr.len + 1);
424 : 556860 : ent->namelen = qstr.len;
425 : 556860 : ent->mode = mode;
426 : 556860 : ent->nlink = nlink;
427 : 556860 : ent->subdir = RB_ROOT;
428 : : refcount_set(&ent->refcnt, 1);
429 : 556860 : spin_lock_init(&ent->pde_unload_lock);
430 : 556860 : INIT_LIST_HEAD(&ent->pde_openers);
431 : 556860 : proc_set_user(ent, (*parent)->uid, (*parent)->gid);
432 : :
433 : 556860 : ent->proc_dops = &proc_misc_dentry_ops;
434 : :
435 : : out:
436 : 556860 : return ent;
437 : : }
438 : :
439 : 2020 : struct proc_dir_entry *proc_symlink(const char *name,
440 : : struct proc_dir_entry *parent, const char *dest)
441 : : {
442 : : struct proc_dir_entry *ent;
443 : :
444 : 2020 : ent = __proc_create(&parent, name,
445 : : (S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO),1);
446 : :
447 [ + - ]: 2020 : if (ent) {
448 : 4040 : ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
449 [ + - ]: 2020 : if (ent->data) {
450 : 2020 : strcpy((char*)ent->data,dest);
451 : 2020 : ent->proc_iops = &proc_link_inode_operations;
452 : 2020 : ent = proc_register(parent, ent);
453 : : } else {
454 : 0 : pde_free(ent);
455 : : ent = NULL;
456 : : }
457 : : }
458 : 2020 : return ent;
459 : : }
460 : : EXPORT_SYMBOL(proc_symlink);
461 : :
462 : 77588 : struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
463 : : struct proc_dir_entry *parent, void *data)
464 : : {
465 : : struct proc_dir_entry *ent;
466 : :
467 [ + + ]: 77588 : if (mode == 0)
468 : : mode = S_IRUGO | S_IXUGO;
469 : :
470 : 77588 : ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
471 [ + - ]: 77588 : if (ent) {
472 : 77588 : ent->data = data;
473 : 77588 : ent->proc_fops = &proc_dir_operations;
474 : 77588 : ent->proc_iops = &proc_dir_inode_operations;
475 : 77588 : parent->nlink++;
476 : 77588 : ent = proc_register(parent, ent);
477 [ - + ]: 77588 : if (!ent)
478 : 0 : parent->nlink--;
479 : : }
480 : 77588 : return ent;
481 : : }
482 : : EXPORT_SYMBOL_GPL(proc_mkdir_data);
483 : :
484 : 404 : struct proc_dir_entry *proc_mkdir_mode(const char *name, umode_t mode,
485 : : struct proc_dir_entry *parent)
486 : : {
487 : 404 : return proc_mkdir_data(name, mode, parent, NULL);
488 : : }
489 : : EXPORT_SYMBOL(proc_mkdir_mode);
490 : :
491 : 75156 : struct proc_dir_entry *proc_mkdir(const char *name,
492 : : struct proc_dir_entry *parent)
493 : : {
494 : 75156 : return proc_mkdir_data(name, 0, parent, NULL);
495 : : }
496 : : EXPORT_SYMBOL(proc_mkdir);
497 : :
498 : 404 : struct proc_dir_entry *proc_create_mount_point(const char *name)
499 : : {
500 : : umode_t mode = S_IFDIR | S_IRUGO | S_IXUGO;
501 : 404 : struct proc_dir_entry *ent, *parent = NULL;
502 : :
503 : 404 : ent = __proc_create(&parent, name, mode, 2);
504 [ + - ]: 404 : if (ent) {
505 : 404 : ent->data = NULL;
506 : 404 : ent->proc_fops = NULL;
507 : 404 : ent->proc_iops = NULL;
508 : 404 : parent->nlink++;
509 : 404 : ent = proc_register(parent, ent);
510 [ - + ]: 404 : if (!ent)
511 : 0 : parent->nlink--;
512 : : }
513 : 404 : return ent;
514 : : }
515 : : EXPORT_SYMBOL(proc_create_mount_point);
516 : :
517 : 476848 : struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
518 : : struct proc_dir_entry **parent, void *data)
519 : : {
520 : : struct proc_dir_entry *p;
521 : :
522 [ + + ]: 476848 : if ((mode & S_IFMT) == 0)
523 : 470356 : mode |= S_IFREG;
524 [ + + ]: 476848 : if ((mode & S_IALLUGO) == 0)
525 : 18606 : mode |= S_IRUGO;
526 [ - + # # : 476848 : if (WARN_ON_ONCE(!S_ISREG(mode)))
+ - ]
527 : : return NULL;
528 : :
529 : 476848 : p = __proc_create(parent, name, mode, 1);
530 [ + - ]: 476848 : if (p) {
531 : 476848 : p->proc_iops = &proc_file_inode_operations;
532 : 476848 : p->data = data;
533 : : }
534 : 476848 : return p;
535 : : }
536 : :
537 : 135770 : struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
538 : : struct proc_dir_entry *parent,
539 : : const struct file_operations *proc_fops, void *data)
540 : : {
541 : : struct proc_dir_entry *p;
542 : :
543 [ - + ]: 135770 : BUG_ON(proc_fops == NULL);
544 : :
545 : 135770 : p = proc_create_reg(name, mode, &parent, data);
546 [ + - ]: 135770 : if (!p)
547 : : return NULL;
548 : 135770 : p->proc_fops = proc_fops;
549 : 135770 : return proc_register(parent, p);
550 : : }
551 : : EXPORT_SYMBOL(proc_create_data);
552 : :
553 : 8084 : struct proc_dir_entry *proc_create(const char *name, umode_t mode,
554 : : struct proc_dir_entry *parent,
555 : : const struct file_operations *proc_fops)
556 : : {
557 : 8084 : return proc_create_data(name, mode, parent, proc_fops, NULL);
558 : : }
559 : : EXPORT_SYMBOL(proc_create);
560 : :
561 : 808 : static int proc_seq_open(struct inode *inode, struct file *file)
562 : : {
563 : : struct proc_dir_entry *de = PDE(inode);
564 : :
565 [ - + ]: 808 : if (de->state_size)
566 : 0 : return seq_open_private(file, de->seq_ops, de->state_size);
567 : 808 : return seq_open(file, de->seq_ops);
568 : : }
569 : :
570 : 808 : static int proc_seq_release(struct inode *inode, struct file *file)
571 : : {
572 : : struct proc_dir_entry *de = PDE(inode);
573 : :
574 [ - + ]: 808 : if (de->state_size)
575 : 0 : return seq_release_private(inode, file);
576 : 808 : return seq_release(inode, file);
577 : : }
578 : :
579 : : static const struct file_operations proc_seq_fops = {
580 : : .open = proc_seq_open,
581 : : .read = seq_read,
582 : : .llseek = seq_lseek,
583 : : .release = proc_seq_release,
584 : : };
585 : :
586 : 12126 : struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
587 : : struct proc_dir_entry *parent, const struct seq_operations *ops,
588 : : unsigned int state_size, void *data)
589 : : {
590 : : struct proc_dir_entry *p;
591 : :
592 : 12126 : p = proc_create_reg(name, mode, &parent, data);
593 [ + - ]: 12126 : if (!p)
594 : : return NULL;
595 : 12126 : p->proc_fops = &proc_seq_fops;
596 : 12126 : p->seq_ops = ops;
597 : 12126 : p->state_size = state_size;
598 : 12126 : return proc_register(parent, p);
599 : : }
600 : : EXPORT_SYMBOL(proc_create_seq_private);
601 : :
602 : 160256 : static int proc_single_open(struct inode *inode, struct file *file)
603 : : {
604 : : struct proc_dir_entry *de = PDE(inode);
605 : :
606 : 160256 : return single_open(file, de->single_show, de->data);
607 : : }
608 : :
609 : : static const struct file_operations proc_single_fops = {
610 : : .open = proc_single_open,
611 : : .read = seq_read,
612 : : .llseek = seq_lseek,
613 : : .release = single_release,
614 : : };
615 : :
616 : 310682 : struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
617 : : struct proc_dir_entry *parent,
618 : : int (*show)(struct seq_file *, void *), void *data)
619 : : {
620 : : struct proc_dir_entry *p;
621 : :
622 : 310682 : p = proc_create_reg(name, mode, &parent, data);
623 [ + - ]: 310682 : if (!p)
624 : : return NULL;
625 : 310682 : p->proc_fops = &proc_single_fops;
626 : 310682 : p->single_show = show;
627 : 310682 : return proc_register(parent, p);
628 : : }
629 : : EXPORT_SYMBOL(proc_create_single_data);
630 : :
631 : 0 : void proc_set_size(struct proc_dir_entry *de, loff_t size)
632 : : {
633 : 0 : de->size = size;
634 : 0 : }
635 : : EXPORT_SYMBOL(proc_set_size);
636 : :
637 : 1618 : void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid)
638 : : {
639 : 558478 : de->uid = uid;
640 : 558478 : de->gid = gid;
641 : 1618 : }
642 : : EXPORT_SYMBOL(proc_set_user);
643 : :
644 : 12962 : void pde_put(struct proc_dir_entry *pde)
645 : : {
646 [ + + ]: 12962 : if (refcount_dec_and_test(&pde->refcnt)) {
647 : 1212 : proc_free_inum(pde->low_ino);
648 : 1212 : pde_free(pde);
649 : : }
650 : 12962 : }
651 : :
652 : : /*
653 : : * Remove a /proc entry and free it if it's not currently in use.
654 : : */
655 : 0 : void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
656 : : {
657 : : struct proc_dir_entry *de = NULL;
658 : 0 : const char *fn = name;
659 : : unsigned int len;
660 : :
661 : 0 : write_lock(&proc_subdir_lock);
662 [ # # ]: 0 : if (__xlate_proc_name(name, &parent, &fn) != 0) {
663 : : write_unlock(&proc_subdir_lock);
664 : 0 : return;
665 : : }
666 : 0 : len = strlen(fn);
667 : :
668 : 0 : de = pde_subdir_find(parent, fn, len);
669 [ # # ]: 0 : if (de)
670 : 0 : rb_erase(&de->subdir_node, &parent->subdir);
671 : : write_unlock(&proc_subdir_lock);
672 [ # # ]: 0 : if (!de) {
673 : 0 : WARN(1, "name '%s'\n", name);
674 : 0 : return;
675 : : }
676 : :
677 : 0 : proc_entry_rundown(de);
678 : :
679 [ # # ]: 0 : if (S_ISDIR(de->mode))
680 : 0 : parent->nlink--;
681 : 0 : de->nlink = 0;
682 [ # # ]: 0 : WARN(pde_subdir_first(de),
683 : : "%s: removing non-empty directory '%s/%s', leaking at least '%s'\n",
684 : : __func__, de->parent->name, de->name, pde_subdir_first(de)->name);
685 : 0 : pde_put(de);
686 : : }
687 : : EXPORT_SYMBOL(remove_proc_entry);
688 : :
689 : 1212 : int remove_proc_subtree(const char *name, struct proc_dir_entry *parent)
690 : : {
691 : : struct proc_dir_entry *root = NULL, *de, *next;
692 : 1212 : const char *fn = name;
693 : : unsigned int len;
694 : :
695 : 1212 : write_lock(&proc_subdir_lock);
696 [ - + ]: 1212 : if (__xlate_proc_name(name, &parent, &fn) != 0) {
697 : : write_unlock(&proc_subdir_lock);
698 : 0 : return -ENOENT;
699 : : }
700 : 1212 : len = strlen(fn);
701 : :
702 : 1212 : root = pde_subdir_find(parent, fn, len);
703 [ - + ]: 1212 : if (!root) {
704 : : write_unlock(&proc_subdir_lock);
705 : 0 : return -ENOENT;
706 : : }
707 : 1212 : rb_erase(&root->subdir_node, &parent->subdir);
708 : :
709 : : de = root;
710 : : while (1) {
711 : : next = pde_subdir_first(de);
712 [ - + ]: 1212 : if (next) {
713 : 0 : rb_erase(&next->subdir_node, &de->subdir);
714 : : de = next;
715 : 0 : continue;
716 : : }
717 : : write_unlock(&proc_subdir_lock);
718 : :
719 : 1212 : proc_entry_rundown(de);
720 : 1212 : next = de->parent;
721 [ + - ]: 1212 : if (S_ISDIR(de->mode))
722 : 1212 : next->nlink--;
723 : 1212 : de->nlink = 0;
724 [ - + ]: 1212 : if (de == root)
725 : : break;
726 : 0 : pde_put(de);
727 : :
728 : 0 : write_lock(&proc_subdir_lock);
729 : : de = next;
730 : : }
731 : 1212 : pde_put(root);
732 : 1212 : return 0;
733 : : }
734 : : EXPORT_SYMBOL(remove_proc_subtree);
735 : :
736 : 0 : void *proc_get_parent_data(const struct inode *inode)
737 : : {
738 : : struct proc_dir_entry *de = PDE(inode);
739 : 0 : return de->parent->data;
740 : : }
741 : : EXPORT_SYMBOL_GPL(proc_get_parent_data);
742 : :
743 : 1212 : void proc_remove(struct proc_dir_entry *de)
744 : : {
745 [ + - ]: 1212 : if (de)
746 : 1212 : remove_proc_subtree(de->name, de->parent);
747 : 1212 : }
748 : : EXPORT_SYMBOL(proc_remove);
749 : :
750 : 0 : void *PDE_DATA(const struct inode *inode)
751 : : {
752 : 0 : return __PDE_DATA(inode);
753 : : }
754 : : EXPORT_SYMBOL(PDE_DATA);
755 : :
756 : : /*
757 : : * Pull a user buffer into memory and pass it to the file's write handler if
758 : : * one is supplied. The ->write() method is permitted to modify the
759 : : * kernel-side buffer.
760 : : */
761 : 0 : ssize_t proc_simple_write(struct file *f, const char __user *ubuf, size_t size,
762 : : loff_t *_pos)
763 : : {
764 : : struct proc_dir_entry *pde = PDE(file_inode(f));
765 : : char *buf;
766 : : int ret;
767 : :
768 [ # # ]: 0 : if (!pde->write)
769 : : return -EACCES;
770 [ # # ]: 0 : if (size == 0 || size > PAGE_SIZE - 1)
771 : : return -EINVAL;
772 : 0 : buf = memdup_user_nul(ubuf, size);
773 [ # # ]: 0 : if (IS_ERR(buf))
774 : 0 : return PTR_ERR(buf);
775 : 0 : ret = pde->write(f, buf, size);
776 : 0 : kfree(buf);
777 [ # # ]: 0 : return ret == 0 ? size : ret;
778 : : }
|