1
2
3
4
5#include <linux/init.h>
6#include <linux/sysctl.h>
7#include <linux/poll.h>
8#include <linux/proc_fs.h>
9#include <linux/printk.h>
10#include <linux/security.h>
11#include <linux/sched.h>
12#include <linux/cred.h>
13#include <linux/namei.h>
14#include <linux/mm.h>
15#include <linux/module.h>
16#include "internal.h"
17
18static const struct dentry_operations proc_sys_dentry_operations;
19static const struct file_operations proc_sys_file_operations;
20static const struct inode_operations proc_sys_inode_operations;
21static const struct file_operations proc_sys_dir_file_operations;
22static const struct inode_operations proc_sys_dir_operations;
23
24
25
26struct ctl_table sysctl_mount_point[] = {
27 { }
28};
29
30static bool is_empty_dir(struct ctl_table_header *head)
31{
32 return head->ctl_table[0].child == sysctl_mount_point;
33}
34
35static void set_empty_dir(struct ctl_dir *dir)
36{
37 dir->header.ctl_table[0].child = sysctl_mount_point;
38}
39
40static void clear_empty_dir(struct ctl_dir *dir)
41
42{
43 dir->header.ctl_table[0].child = NULL;
44}
45
46void proc_sys_poll_notify(struct ctl_table_poll *poll)
47{
48 if (!poll)
49 return;
50
51 atomic_inc(&poll->event);
52 wake_up_interruptible(&poll->wait);
53}
54
55static struct ctl_table root_table[] = {
56 {
57 .procname = "",
58 .mode = S_IFDIR|S_IRUGO|S_IXUGO,
59 },
60 { }
61};
62static struct ctl_table_root sysctl_table_root = {
63 .default_set.dir.header = {
64 {{.count = 1,
65 .nreg = 1,
66 .ctl_table = root_table }},
67 .ctl_table_arg = root_table,
68 .root = &sysctl_table_root,
69 .set = &sysctl_table_root.default_set,
70 },
71};
72
73static DEFINE_SPINLOCK(sysctl_lock);
74
75static void drop_sysctl_table(struct ctl_table_header *header);
76static int sysctl_follow_link(struct ctl_table_header **phead,
77 struct ctl_table **pentry);
78static int insert_links(struct ctl_table_header *head);
79static void put_links(struct ctl_table_header *header);
80
81static void sysctl_print_dir(struct ctl_dir *dir)
82{
83 if (dir->header.parent)
84 sysctl_print_dir(dir->header.parent);
85 pr_cont("%s/", dir->header.ctl_table[0].procname);
86}
87
88static int namecmp(const char *name1, int len1, const char *name2, int len2)
89{
90 int minlen;
91 int cmp;
92
93 minlen = len1;
94 if (minlen > len2)
95 minlen = len2;
96
97 cmp = memcmp(name1, name2, minlen);
98 if (cmp == 0)
99 cmp = len1 - len2;
100 return cmp;
101}
102
103
104static struct ctl_table *find_entry(struct ctl_table_header **phead,
105 struct ctl_dir *dir, const char *name, int namelen)
106{
107 struct ctl_table_header *head;
108 struct ctl_table *entry;
109 struct rb_node *node = dir->root.rb_node;
110
111 while (node)
112 {
113 struct ctl_node *ctl_node;
114 const char *procname;
115 int cmp;
116
117 ctl_node = rb_entry(node, struct ctl_node, node);
118 head = ctl_node->header;
119 entry = &head->ctl_table[ctl_node - head->node];
120 procname = entry->procname;
121
122 cmp = namecmp(name, namelen, procname, strlen(procname));
123 if (cmp < 0)
124 node = node->rb_left;
125 else if (cmp > 0)
126 node = node->rb_right;
127 else {
128 *phead = head;
129 return entry;
130 }
131 }
132 return NULL;
133}
134
135static int insert_entry(struct ctl_table_header *head, struct ctl_table *entry)
136{
137 struct rb_node *node = &head->node[entry - head->ctl_table].node;
138 struct rb_node **p = &head->parent->root.rb_node;
139 struct rb_node *parent = NULL;
140 const char *name = entry->procname;
141 int namelen = strlen(name);
142
143 while (*p) {
144 struct ctl_table_header *parent_head;
145 struct ctl_table *parent_entry;
146 struct ctl_node *parent_node;
147 const char *parent_name;
148 int cmp;
149
150 parent = *p;
151 parent_node = rb_entry(parent, struct ctl_node, node);
152 parent_head = parent_node->header;
153 parent_entry = &parent_head->ctl_table[parent_node - parent_head->node];
154 parent_name = parent_entry->procname;
155
156 cmp = namecmp(name, namelen, parent_name, strlen(parent_name));
157 if (cmp < 0)
158 p = &(*p)->rb_left;
159 else if (cmp > 0)
160 p = &(*p)->rb_right;
161 else {
162 pr_err("sysctl duplicate entry: ");
163 sysctl_print_dir(head->parent);
164 pr_cont("/%s\n", entry->procname);
165 return -EEXIST;
166 }
167 }
168
169 rb_link_node(node, parent, p);
170 rb_insert_color(node, &head->parent->root);
171 return 0;
172}
173
174static void erase_entry(struct ctl_table_header *head, struct ctl_table *entry)
175{
176 struct rb_node *node = &head->node[entry - head->ctl_table].node;
177
178 rb_erase(node, &head->parent->root);
179}
180
181static void init_header(struct ctl_table_header *head,
182 struct ctl_table_root *root, struct ctl_table_set *set,
183 struct ctl_node *node, struct ctl_table *table)
184{
185 head->ctl_table = table;
186 head->ctl_table_arg = table;
187 head->used = 0;
188 head->count = 1;
189 head->nreg = 1;
190 head->unregistering = NULL;
191 head->root = root;
192 head->set = set;
193 head->parent = NULL;
194 head->node = node;
195 INIT_HLIST_HEAD(&head->inodes);
196 if (node) {
197 struct ctl_table *entry;
198 for (entry = table; entry->procname; entry++, node++)
199 node->header = head;
200 }
201}
202
203static void erase_header(struct ctl_table_header *head)
204{
205 struct ctl_table *entry;
206 for (entry = head->ctl_table; entry->procname; entry++)
207 erase_entry(head, entry);
208}
209
210static int insert_header(struct ctl_dir *dir, struct ctl_table_header *header)
211{
212 struct ctl_table *entry;
213 int err;
214
215
216 if (is_empty_dir(&dir->header))
217 return -EROFS;
218
219
220 if (header->ctl_table == sysctl_mount_point) {
221 if (!RB_EMPTY_ROOT(&dir->root))
222 return -EINVAL;
223 set_empty_dir(dir);
224 }
225
226 dir->header.nreg++;
227 header->parent = dir;
228 err = insert_links(header);
229 if (err)
230 goto fail_links;
231 for (entry = header->ctl_table; entry->procname; entry++) {
232 err = insert_entry(header, entry);
233 if (err)
234 goto fail;
235 }
236 return 0;
237fail:
238 erase_header(header);
239 put_links(header);
240fail_links:
241 if (header->ctl_table == sysctl_mount_point)
242 clear_empty_dir(dir);
243 header->parent = NULL;
244 drop_sysctl_table(&dir->header);
245 return err;
246}
247
248
249static int use_table(struct ctl_table_header *p)
250{
251 if (unlikely(p->unregistering))
252 return 0;
253 p->used++;
254 return 1;
255}
256
257
258static void unuse_table(struct ctl_table_header *p)
259{
260 if (!--p->used)
261 if (unlikely(p->unregistering))
262 complete(p->unregistering);
263}
264
265static void proc_sys_prune_dcache(struct ctl_table_header *head)
266{
267 struct inode *inode;
268 struct proc_inode *ei;
269 struct hlist_node *node;
270 struct super_block *sb;
271
272 rcu_read_lock();
273 for (;;) {
274 node = hlist_first_rcu(&head->inodes);
275 if (!node)
276 break;
277 ei = hlist_entry(node, struct proc_inode, sysctl_inodes);
278 spin_lock(&sysctl_lock);
279 hlist_del_init_rcu(&ei->sysctl_inodes);
280 spin_unlock(&sysctl_lock);
281
282 inode = &ei->vfs_inode;
283 sb = inode->i_sb;
284 if (!atomic_inc_not_zero(&sb->s_active))
285 continue;
286 inode = igrab(inode);
287 rcu_read_unlock();
288 if (unlikely(!inode)) {
289 deactivate_super(sb);
290 rcu_read_lock();
291 continue;
292 }
293
294 d_prune_aliases(inode);
295 iput(inode);
296 deactivate_super(sb);
297
298 rcu_read_lock();
299 }
300 rcu_read_unlock();
301}
302
303
304static void start_unregistering(struct ctl_table_header *p)
305{
306
307
308
309
310 if (unlikely(p->used)) {
311 struct completion wait;
312 init_completion(&wait);
313 p->unregistering = &wait;
314 spin_unlock(&sysctl_lock);
315 wait_for_completion(&wait);
316 } else {
317
318 p->unregistering = ERR_PTR(-EINVAL);
319 spin_unlock(&sysctl_lock);
320 }
321
322
323
324
325 proc_sys_prune_dcache(p);
326
327
328
329
330 spin_lock(&sysctl_lock);
331 erase_header(p);
332}
333
334static struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
335{
336 BUG_ON(!head);
337 spin_lock(&sysctl_lock);
338 if (!use_table(head))
339 head = ERR_PTR(-ENOENT);
340 spin_unlock(&sysctl_lock);
341 return head;
342}
343
344static void sysctl_head_finish(struct ctl_table_header *head)
345{
346 if (!head)
347 return;
348 spin_lock(&sysctl_lock);
349 unuse_table(head);
350 spin_unlock(&sysctl_lock);
351}
352
353static struct ctl_table_set *
354lookup_header_set(struct ctl_table_root *root)
355{
356 struct ctl_table_set *set = &root->default_set;
357 if (root->lookup)
358 set = root->lookup(root);
359 return set;
360}
361
362static struct ctl_table *lookup_entry(struct ctl_table_header **phead,
363 struct ctl_dir *dir,
364 const char *name, int namelen)
365{
366 struct ctl_table_header *head;
367 struct ctl_table *entry;
368
369 spin_lock(&sysctl_lock);
370 entry = find_entry(&head, dir, name, namelen);
371 if (entry && use_table(head))
372 *phead = head;
373 else
374 entry = NULL;
375 spin_unlock(&sysctl_lock);
376 return entry;
377}
378
379static struct ctl_node *first_usable_entry(struct rb_node *node)
380{
381 struct ctl_node *ctl_node;
382
383 for (;node; node = rb_next(node)) {
384 ctl_node = rb_entry(node, struct ctl_node, node);
385 if (use_table(ctl_node->header))
386 return ctl_node;
387 }
388 return NULL;
389}
390
391static void first_entry(struct ctl_dir *dir,
392 struct ctl_table_header **phead, struct ctl_table **pentry)
393{
394 struct ctl_table_header *head = NULL;
395 struct ctl_table *entry = NULL;
396 struct ctl_node *ctl_node;
397
398 spin_lock(&sysctl_lock);
399 ctl_node = first_usable_entry(rb_first(&dir->root));
400 spin_unlock(&sysctl_lock);
401 if (ctl_node) {
402 head = ctl_node->header;
403 entry = &head->ctl_table[ctl_node - head->node];
404 }
405 *phead = head;
406 *pentry = entry;
407}
408
409static void next_entry(struct ctl_table_header **phead, struct ctl_table **pentry)
410{
411 struct ctl_table_header *head = *phead;
412 struct ctl_table *entry = *pentry;
413 struct ctl_node *ctl_node = &head->node[entry - head->ctl_table];
414
415 spin_lock(&sysctl_lock);
416 unuse_table(head);
417
418 ctl_node = first_usable_entry(rb_next(&ctl_node->node));
419 spin_unlock(&sysctl_lock);
420 head = NULL;
421 if (ctl_node) {
422 head = ctl_node->header;
423 entry = &head->ctl_table[ctl_node - head->node];
424 }
425 *phead = head;
426 *pentry = entry;
427}
428
429
430
431
432
433
434static int test_perm(int mode, int op)
435{
436 if (uid_eq(current_euid(), GLOBAL_ROOT_UID))
437 mode >>= 6;
438 else if (in_egroup_p(GLOBAL_ROOT_GID))
439 mode >>= 3;
440 if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
441 return 0;
442 return -EACCES;
443}
444
445static int sysctl_perm(struct ctl_table_header *head, struct ctl_table *table, int op)
446{
447 struct ctl_table_root *root = head->root;
448 int mode;
449
450 if (root->permissions)
451 mode = root->permissions(head, table);
452 else
453 mode = table->mode;
454
455 return test_perm(mode, op);
456}
457
458static struct inode *proc_sys_make_inode(struct super_block *sb,
459 struct ctl_table_header *head, struct ctl_table *table)
460{
461 struct ctl_table_root *root = head->root;
462 struct inode *inode;
463 struct proc_inode *ei;
464
465 inode = new_inode(sb);
466 if (!inode)
467 goto out;
468
469 inode->i_ino = get_next_ino();
470
471 ei = PROC_I(inode);
472
473 spin_lock(&sysctl_lock);
474 if (unlikely(head->unregistering)) {
475 spin_unlock(&sysctl_lock);
476 iput(inode);
477 inode = NULL;
478 goto out;
479 }
480 ei->sysctl = head;
481 ei->sysctl_entry = table;
482 hlist_add_head_rcu(&ei->sysctl_inodes, &head->inodes);
483 head->count++;
484 spin_unlock(&sysctl_lock);
485
486 inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
487 inode->i_mode = table->mode;
488 if (!S_ISDIR(table->mode)) {
489 inode->i_mode |= S_IFREG;
490 inode->i_op = &proc_sys_inode_operations;
491 inode->i_fop = &proc_sys_file_operations;
492 } else {
493 inode->i_mode |= S_IFDIR;
494 inode->i_op = &proc_sys_dir_operations;
495 inode->i_fop = &proc_sys_dir_file_operations;
496 if (is_empty_dir(head))
497 make_empty_dir_inode(inode);
498 }
499
500 if (root->set_ownership)
501 root->set_ownership(head, table, &inode->i_uid, &inode->i_gid);
502
503out:
504 return inode;
505}
506
507void proc_sys_evict_inode(struct inode *inode, struct ctl_table_header *head)
508{
509 spin_lock(&sysctl_lock);
510 hlist_del_init_rcu(&PROC_I(inode)->sysctl_inodes);
511 if (!--head->count)
512 kfree_rcu(head, rcu);
513 spin_unlock(&sysctl_lock);
514}
515
516static struct ctl_table_header *grab_header(struct inode *inode)
517{
518 struct ctl_table_header *head = PROC_I(inode)->sysctl;
519 if (!head)
520 head = &sysctl_table_root.default_set.dir.header;
521 return sysctl_head_grab(head);
522}
523
524static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
525 unsigned int flags)
526{
527 struct ctl_table_header *head = grab_header(dir);
528 struct ctl_table_header *h = NULL;
529 const struct qstr *name = &dentry->d_name;
530 struct ctl_table *p;
531 struct inode *inode;
532 struct dentry *err = ERR_PTR(-ENOENT);
533 struct ctl_dir *ctl_dir;
534 int ret;
535
536 if (IS_ERR(head))
537 return ERR_CAST(head);
538
539 ctl_dir = container_of(head, struct ctl_dir, header);
540
541 p = lookup_entry(&h, ctl_dir, name->name, name->len);
542 if (!p)
543 goto out;
544
545 if (S_ISLNK(p->mode)) {
546 ret = sysctl_follow_link(&h, &p);
547 err = ERR_PTR(ret);
548 if (ret)
549 goto out;
550 }
551
552 err = ERR_PTR(-ENOMEM);
553 inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
554 if (!inode)
555 goto out;
556
557 err = NULL;
558 d_set_d_op(dentry, &proc_sys_dentry_operations);
559 d_add(dentry, inode);
560
561out:
562 if (h)
563 sysctl_head_finish(h);
564 sysctl_head_finish(head);
565 return err;
566}
567
568static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
569 size_t count, loff_t *ppos, int write)
570{
571 struct inode *inode = file_inode(filp);
572 struct ctl_table_header *head = grab_header(inode);
573 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
574 ssize_t error;
575 size_t res;
576
577 if (IS_ERR(head))
578 return PTR_ERR(head);
579
580
581
582
583
584 error = -EPERM;
585 if (sysctl_perm(head, table, write ? MAY_WRITE : MAY_READ))
586 goto out;
587
588
589 error = -EINVAL;
590 if (!table->proc_handler)
591 goto out;
592
593
594 res = count;
595 error = table->proc_handler(table, write, buf, &res, ppos);
596 if (!error)
597 error = res;
598out:
599 sysctl_head_finish(head);
600
601 return error;
602}
603
604static ssize_t proc_sys_read(struct file *filp, char __user *buf,
605 size_t count, loff_t *ppos)
606{
607 return proc_sys_call_handler(filp, (void __user *)buf, count, ppos, 0);
608}
609
610static ssize_t proc_sys_write(struct file *filp, const char __user *buf,
611 size_t count, loff_t *ppos)
612{
613 return proc_sys_call_handler(filp, (void __user *)buf, count, ppos, 1);
614}
615
616static int proc_sys_open(struct inode *inode, struct file *filp)
617{
618 struct ctl_table_header *head = grab_header(inode);
619 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
620
621
622 if (IS_ERR(head))
623 return PTR_ERR(head);
624
625 if (table->poll)
626 filp->private_data = proc_sys_poll_event(table->poll);
627
628 sysctl_head_finish(head);
629
630 return 0;
631}
632
633static unsigned int proc_sys_poll(struct file *filp, poll_table *wait)
634{
635 struct inode *inode = file_inode(filp);
636 struct ctl_table_header *head = grab_header(inode);
637 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
638 unsigned int ret = DEFAULT_POLLMASK;
639 unsigned long event;
640
641
642 if (IS_ERR(head))
643 return POLLERR | POLLHUP;
644
645 if (!table->proc_handler)
646 goto out;
647
648 if (!table->poll)
649 goto out;
650
651 event = (unsigned long)filp->private_data;
652 poll_wait(filp, &table->poll->wait, wait);
653
654 if (event != atomic_read(&table->poll->event)) {
655 filp->private_data = proc_sys_poll_event(table->poll);
656 ret = POLLIN | POLLRDNORM | POLLERR | POLLPRI;
657 }
658
659out:
660 sysctl_head_finish(head);
661
662 return ret;
663}
664
665static bool proc_sys_fill_cache(struct file *file,
666 struct dir_context *ctx,
667 struct ctl_table_header *head,
668 struct ctl_table *table)
669{
670 struct dentry *child, *dir = file->f_path.dentry;
671 struct inode *inode;
672 struct qstr qname;
673 ino_t ino = 0;
674 unsigned type = DT_UNKNOWN;
675
676 qname.name = table->procname;
677 qname.len = strlen(table->procname);
678 qname.hash = full_name_hash(dir, qname.name, qname.len);
679
680 child = d_lookup(dir, &qname);
681 if (!child) {
682 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
683 child = d_alloc_parallel(dir, &qname, &wq);
684 if (IS_ERR(child))
685 return false;
686 if (d_in_lookup(child)) {
687 inode = proc_sys_make_inode(dir->d_sb, head, table);
688 if (!inode) {
689 d_lookup_done(child);
690 dput(child);
691 return false;
692 }
693 d_set_d_op(child, &proc_sys_dentry_operations);
694 d_add(child, inode);
695 }
696 }
697 inode = d_inode(child);
698 ino = inode->i_ino;
699 type = inode->i_mode >> 12;
700 dput(child);
701 return dir_emit(ctx, qname.name, qname.len, ino, type);
702}
703
704static bool proc_sys_link_fill_cache(struct file *file,
705 struct dir_context *ctx,
706 struct ctl_table_header *head,
707 struct ctl_table *table)
708{
709 bool ret = true;
710 head = sysctl_head_grab(head);
711
712 if (S_ISLNK(table->mode)) {
713
714 int err = sysctl_follow_link(&head, &table);
715 if (err)
716 goto out;
717 }
718
719 ret = proc_sys_fill_cache(file, ctx, head, table);
720out:
721 sysctl_head_finish(head);
722 return ret;
723}
724
725static int scan(struct ctl_table_header *head, struct ctl_table *table,
726 unsigned long *pos, struct file *file,
727 struct dir_context *ctx)
728{
729 bool res;
730
731 if ((*pos)++ < ctx->pos)
732 return true;
733
734 if (unlikely(S_ISLNK(table->mode)))
735 res = proc_sys_link_fill_cache(file, ctx, head, table);
736 else
737 res = proc_sys_fill_cache(file, ctx, head, table);
738
739 if (res)
740 ctx->pos = *pos;
741
742 return res;
743}
744
745static int proc_sys_readdir(struct file *file, struct dir_context *ctx)
746{
747 struct ctl_table_header *head = grab_header(file_inode(file));
748 struct ctl_table_header *h = NULL;
749 struct ctl_table *entry;
750 struct ctl_dir *ctl_dir;
751 unsigned long pos;
752
753 if (IS_ERR(head))
754 return PTR_ERR(head);
755
756 ctl_dir = container_of(head, struct ctl_dir, header);
757
758 if (!dir_emit_dots(file, ctx))
759 goto out;
760
761 pos = 2;
762
763 for (first_entry(ctl_dir, &h, &entry); h; next_entry(&h, &entry)) {
764 if (!scan(h, entry, &pos, file, ctx)) {
765 sysctl_head_finish(h);
766 break;
767 }
768 }
769out:
770 sysctl_head_finish(head);
771 return 0;
772}
773
774static int proc_sys_permission(struct inode *inode, int mask)
775{
776
777
778
779
780 struct ctl_table_header *head;
781 struct ctl_table *table;
782 int error;
783
784
785 if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))
786 return -EACCES;
787
788 head = grab_header(inode);
789 if (IS_ERR(head))
790 return PTR_ERR(head);
791
792 table = PROC_I(inode)->sysctl_entry;
793 if (!table)
794 error = mask & MAY_WRITE ? -EACCES : 0;
795 else
796 error = sysctl_perm(head, table, mask & ~MAY_NOT_BLOCK);
797
798 sysctl_head_finish(head);
799 return error;
800}
801
802static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
803{
804 struct inode *inode = d_inode(dentry);
805 int error;
806
807 if (attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
808 return -EPERM;
809
810 error = setattr_prepare(dentry, attr);
811 if (error)
812 return error;
813
814 setattr_copy(inode, attr);
815 mark_inode_dirty(inode);
816 return 0;
817}
818
819static int proc_sys_getattr(const struct path *path, struct kstat *stat,
820 u32 request_mask, unsigned int query_flags)
821{
822 struct inode *inode = d_inode(path->dentry);
823 struct ctl_table_header *head = grab_header(inode);
824 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
825
826 if (IS_ERR(head))
827 return PTR_ERR(head);
828
829 generic_fillattr(inode, stat);
830 if (table)
831 stat->mode = (stat->mode & S_IFMT) | table->mode;
832
833 sysctl_head_finish(head);
834 return 0;
835}
836
837static const struct file_operations proc_sys_file_operations = {
838 .open = proc_sys_open,
839 .poll = proc_sys_poll,
840 .read = proc_sys_read,
841 .write = proc_sys_write,
842 .llseek = default_llseek,
843};
844
845static const struct file_operations proc_sys_dir_file_operations = {
846 .read = generic_read_dir,
847 .iterate_shared = proc_sys_readdir,
848 .llseek = generic_file_llseek,
849};
850
851static const struct inode_operations proc_sys_inode_operations = {
852 .permission = proc_sys_permission,
853 .setattr = proc_sys_setattr,
854 .getattr = proc_sys_getattr,
855};
856
857static const struct inode_operations proc_sys_dir_operations = {
858 .lookup = proc_sys_lookup,
859 .permission = proc_sys_permission,
860 .setattr = proc_sys_setattr,
861 .getattr = proc_sys_getattr,
862};
863
864static int proc_sys_revalidate(struct dentry *dentry, unsigned int flags)
865{
866 if (flags & LOOKUP_RCU)
867 return -ECHILD;
868 return !PROC_I(d_inode(dentry))->sysctl->unregistering;
869}
870
871static int proc_sys_delete(const struct dentry *dentry)
872{
873 return !!PROC_I(d_inode(dentry))->sysctl->unregistering;
874}
875
876static int sysctl_is_seen(struct ctl_table_header *p)
877{
878 struct ctl_table_set *set = p->set;
879 int res;
880 spin_lock(&sysctl_lock);
881 if (p->unregistering)
882 res = 0;
883 else if (!set->is_seen)
884 res = 1;
885 else
886 res = set->is_seen(set);
887 spin_unlock(&sysctl_lock);
888 return res;
889}
890
891static int proc_sys_compare(const struct dentry *dentry,
892 unsigned int len, const char *str, const struct qstr *name)
893{
894 struct ctl_table_header *head;
895 struct inode *inode;
896
897
898
899
900 inode = d_inode_rcu(dentry);
901 if (!inode)
902 return 1;
903 if (name->len != len)
904 return 1;
905 if (memcmp(name->name, str, len))
906 return 1;
907 head = rcu_dereference(PROC_I(inode)->sysctl);
908 return !head || !sysctl_is_seen(head);
909}
910
911static const struct dentry_operations proc_sys_dentry_operations = {
912 .d_revalidate = proc_sys_revalidate,
913 .d_delete = proc_sys_delete,
914 .d_compare = proc_sys_compare,
915};
916
917static struct ctl_dir *find_subdir(struct ctl_dir *dir,
918 const char *name, int namelen)
919{
920 struct ctl_table_header *head;
921 struct ctl_table *entry;
922
923 entry = find_entry(&head, dir, name, namelen);
924 if (!entry)
925 return ERR_PTR(-ENOENT);
926 if (!S_ISDIR(entry->mode))
927 return ERR_PTR(-ENOTDIR);
928 return container_of(head, struct ctl_dir, header);
929}
930
931static struct ctl_dir *new_dir(struct ctl_table_set *set,
932 const char *name, int namelen)
933{
934 struct ctl_table *table;
935 struct ctl_dir *new;
936 struct ctl_node *node;
937 char *new_name;
938
939 new = kzalloc(sizeof(*new) + sizeof(struct ctl_node) +
940 sizeof(struct ctl_table)*2 + namelen + 1,
941 GFP_KERNEL);
942 if (!new)
943 return NULL;
944
945 node = (struct ctl_node *)(new + 1);
946 table = (struct ctl_table *)(node + 1);
947 new_name = (char *)(table + 2);
948 memcpy(new_name, name, namelen);
949 new_name[namelen] = '\0';
950 table[0].procname = new_name;
951 table[0].mode = S_IFDIR|S_IRUGO|S_IXUGO;
952 init_header(&new->header, set->dir.header.root, set, node, table);
953
954 return new;
955}
956
957
958
959
960
961
962
963
964
965
966
967
968
969static struct ctl_dir *get_subdir(struct ctl_dir *dir,
970 const char *name, int namelen)
971{
972 struct ctl_table_set *set = dir->header.set;
973 struct ctl_dir *subdir, *new = NULL;
974 int err;
975
976 spin_lock(&sysctl_lock);
977 subdir = find_subdir(dir, name, namelen);
978 if (!IS_ERR(subdir))
979 goto found;
980 if (PTR_ERR(subdir) != -ENOENT)
981 goto failed;
982
983 spin_unlock(&sysctl_lock);
984 new = new_dir(set, name, namelen);
985 spin_lock(&sysctl_lock);
986 subdir = ERR_PTR(-ENOMEM);
987 if (!new)
988 goto failed;
989
990
991 subdir = find_subdir(dir, name, namelen);
992 if (!IS_ERR(subdir))
993 goto found;
994 if (PTR_ERR(subdir) != -ENOENT)
995 goto failed;
996
997
998 err = insert_header(dir, &new->header);
999 subdir = ERR_PTR(err);
1000 if (err)
1001 goto failed;
1002 subdir = new;
1003found:
1004 subdir->header.nreg++;
1005failed:
1006 if (IS_ERR(subdir)) {
1007 pr_err("sysctl could not get directory: ");
1008 sysctl_print_dir(dir);
1009 pr_cont("/%*.*s %ld\n",
1010 namelen, namelen, name, PTR_ERR(subdir));
1011 }
1012 drop_sysctl_table(&dir->header);
1013 if (new)
1014 drop_sysctl_table(&new->header);
1015 spin_unlock(&sysctl_lock);
1016 return subdir;
1017}
1018
1019static struct ctl_dir *xlate_dir(struct ctl_table_set *set, struct ctl_dir *dir)
1020{
1021 struct ctl_dir *parent;
1022 const char *procname;
1023 if (!dir->header.parent)
1024 return &set->dir;
1025 parent = xlate_dir(set, dir->header.parent);
1026 if (IS_ERR(parent))
1027 return parent;
1028 procname = dir->header.ctl_table[0].procname;
1029 return find_subdir(parent, procname, strlen(procname));
1030}
1031
1032static int sysctl_follow_link(struct ctl_table_header **phead,
1033 struct ctl_table **pentry)
1034{
1035 struct ctl_table_header *head;
1036 struct ctl_table_root *root;
1037 struct ctl_table_set *set;
1038 struct ctl_table *entry;
1039 struct ctl_dir *dir;
1040 int ret;
1041
1042 ret = 0;
1043 spin_lock(&sysctl_lock);
1044 root = (*pentry)->data;
1045 set = lookup_header_set(root);
1046 dir = xlate_dir(set, (*phead)->parent);
1047 if (IS_ERR(dir))
1048 ret = PTR_ERR(dir);
1049 else {
1050 const char *procname = (*pentry)->procname;
1051 head = NULL;
1052 entry = find_entry(&head, dir, procname, strlen(procname));
1053 ret = -ENOENT;
1054 if (entry && use_table(head)) {
1055 unuse_table(*phead);
1056 *phead = head;
1057 *pentry = entry;
1058 ret = 0;
1059 }
1060 }
1061
1062 spin_unlock(&sysctl_lock);
1063 return ret;
1064}
1065
1066static int sysctl_err(const char *path, struct ctl_table *table, char *fmt, ...)
1067{
1068 struct va_format vaf;
1069 va_list args;
1070
1071 va_start(args, fmt);
1072 vaf.fmt = fmt;
1073 vaf.va = &args;
1074
1075 pr_err("sysctl table check failed: %s/%s %pV\n",
1076 path, table->procname, &vaf);
1077
1078 va_end(args);
1079 return -EINVAL;
1080}
1081
1082static int sysctl_check_table_array(const char *path, struct ctl_table *table)
1083{
1084 int err = 0;
1085
1086 if ((table->proc_handler == proc_douintvec) ||
1087 (table->proc_handler == proc_douintvec_minmax)) {
1088 if (table->maxlen != sizeof(unsigned int))
1089 err |= sysctl_err(path, table, "array now allowed");
1090 }
1091
1092 return err;
1093}
1094
1095static int sysctl_check_table(const char *path, struct ctl_table *table)
1096{
1097 int err = 0;
1098 for (; table->procname; table++) {
1099 if (table->child)
1100 err |= sysctl_err(path, table, "Not a file");
1101
1102 if ((table->proc_handler == proc_dostring) ||
1103 (table->proc_handler == proc_dointvec) ||
1104 (table->proc_handler == proc_douintvec) ||
1105 (table->proc_handler == proc_douintvec_minmax) ||
1106 (table->proc_handler == proc_dointvec_minmax) ||
1107 (table->proc_handler == proc_dointvec_jiffies) ||
1108 (table->proc_handler == proc_dointvec_userhz_jiffies) ||
1109 (table->proc_handler == proc_dointvec_ms_jiffies) ||
1110 (table->proc_handler == proc_doulongvec_minmax) ||
1111 (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
1112 if (!table->data)
1113 err |= sysctl_err(path, table, "No data");
1114 if (!table->maxlen)
1115 err |= sysctl_err(path, table, "No maxlen");
1116 else
1117 err |= sysctl_check_table_array(path, table);
1118 }
1119 if (!table->proc_handler)
1120 err |= sysctl_err(path, table, "No proc_handler");
1121
1122 if ((table->mode & (S_IRUGO|S_IWUGO)) != table->mode)
1123 err |= sysctl_err(path, table, "bogus .mode 0%o",
1124 table->mode);
1125 }
1126 return err;
1127}
1128
1129static struct ctl_table_header *new_links(struct ctl_dir *dir, struct ctl_table *table,
1130 struct ctl_table_root *link_root)
1131{
1132 struct ctl_table *link_table, *entry, *link;
1133 struct ctl_table_header *links;
1134 struct ctl_node *node;
1135 char *link_name;
1136 int nr_entries, name_bytes;
1137
1138 name_bytes = 0;
1139 nr_entries = 0;
1140 for (entry = table; entry->procname; entry++) {
1141 nr_entries++;
1142 name_bytes += strlen(entry->procname) + 1;
1143 }
1144
1145 links = kzalloc(sizeof(struct ctl_table_header) +
1146 sizeof(struct ctl_node)*nr_entries +
1147 sizeof(struct ctl_table)*(nr_entries + 1) +
1148 name_bytes,
1149 GFP_KERNEL);
1150
1151 if (!links)
1152 return NULL;
1153
1154 node = (struct ctl_node *)(links + 1);
1155 link_table = (struct ctl_table *)(node + nr_entries);
1156 link_name = (char *)&link_table[nr_entries + 1];
1157
1158 for (link = link_table, entry = table; entry->procname; link++, entry++) {
1159 int len = strlen(entry->procname) + 1;
1160 memcpy(link_name, entry->procname, len);
1161 link->procname = link_name;
1162 link->mode = S_IFLNK|S_IRWXUGO;
1163 link->data = link_root;
1164 link_name += len;
1165 }
1166 init_header(links, dir->header.root, dir->header.set, node, link_table);
1167 links->nreg = nr_entries;
1168
1169 return links;
1170}
1171
1172static bool get_links(struct ctl_dir *dir,
1173 struct ctl_table *table, struct ctl_table_root *link_root)
1174{
1175 struct ctl_table_header *head;
1176 struct ctl_table *entry, *link;
1177
1178
1179 for (entry = table; entry->procname; entry++) {
1180 const char *procname = entry->procname;
1181 link = find_entry(&head, dir, procname, strlen(procname));
1182 if (!link)
1183 return false;
1184 if (S_ISDIR(link->mode) && S_ISDIR(entry->mode))
1185 continue;
1186 if (S_ISLNK(link->mode) && (link->data == link_root))
1187 continue;
1188 return false;
1189 }
1190
1191
1192 for (entry = table; entry->procname; entry++) {
1193 const char *procname = entry->procname;
1194 link = find_entry(&head, dir, procname, strlen(procname));
1195 head->nreg++;
1196 }
1197 return true;
1198}
1199
1200static int insert_links(struct ctl_table_header *head)
1201{
1202 struct ctl_table_set *root_set = &sysctl_table_root.default_set;
1203 struct ctl_dir *core_parent = NULL;
1204 struct ctl_table_header *links;
1205 int err;
1206
1207 if (head->set == root_set)
1208 return 0;
1209
1210 core_parent = xlate_dir(root_set, head->parent);
1211 if (IS_ERR(core_parent))
1212 return 0;
1213
1214 if (get_links(core_parent, head->ctl_table, head->root))
1215 return 0;
1216
1217 core_parent->header.nreg++;
1218 spin_unlock(&sysctl_lock);
1219
1220 links = new_links(core_parent, head->ctl_table, head->root);
1221
1222 spin_lock(&sysctl_lock);
1223 err = -ENOMEM;
1224 if (!links)
1225 goto out;
1226
1227 err = 0;
1228 if (get_links(core_parent, head->ctl_table, head->root)) {
1229 kfree(links);
1230 goto out;
1231 }
1232
1233 err = insert_header(core_parent, links);
1234 if (err)
1235 kfree(links);
1236out:
1237 drop_sysctl_table(&core_parent->header);
1238 return err;
1239}
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283struct ctl_table_header *__register_sysctl_table(
1284 struct ctl_table_set *set,
1285 const char *path, struct ctl_table *table)
1286{
1287 struct ctl_table_root *root = set->dir.header.root;
1288 struct ctl_table_header *header;
1289 const char *name, *nextname;
1290 struct ctl_dir *dir;
1291 struct ctl_table *entry;
1292 struct ctl_node *node;
1293 int nr_entries = 0;
1294
1295 for (entry = table; entry->procname; entry++)
1296 nr_entries++;
1297
1298 header = kzalloc(sizeof(struct ctl_table_header) +
1299 sizeof(struct ctl_node)*nr_entries, GFP_KERNEL);
1300 if (!header)
1301 return NULL;
1302
1303 node = (struct ctl_node *)(header + 1);
1304 init_header(header, root, set, node, table);
1305 if (sysctl_check_table(path, table))
1306 goto fail;
1307
1308 spin_lock(&sysctl_lock);
1309 dir = &set->dir;
1310
1311 dir->header.nreg++;
1312 spin_unlock(&sysctl_lock);
1313
1314
1315 for (name = path; name; name = nextname) {
1316 int namelen;
1317 nextname = strchr(name, '/');
1318 if (nextname) {
1319 namelen = nextname - name;
1320 nextname++;
1321 } else {
1322 namelen = strlen(name);
1323 }
1324 if (namelen == 0)
1325 continue;
1326
1327 dir = get_subdir(dir, name, namelen);
1328 if (IS_ERR(dir))
1329 goto fail;
1330 }
1331
1332 spin_lock(&sysctl_lock);
1333 if (insert_header(dir, header))
1334 goto fail_put_dir_locked;
1335
1336 drop_sysctl_table(&dir->header);
1337 spin_unlock(&sysctl_lock);
1338
1339 return header;
1340
1341fail_put_dir_locked:
1342 drop_sysctl_table(&dir->header);
1343 spin_unlock(&sysctl_lock);
1344fail:
1345 kfree(header);
1346 dump_stack();
1347 return NULL;
1348}
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table)
1361{
1362 return __register_sysctl_table(&sysctl_table_root.default_set,
1363 path, table);
1364}
1365EXPORT_SYMBOL(register_sysctl);
1366
1367static char *append_path(const char *path, char *pos, const char *name)
1368{
1369 int namelen;
1370 namelen = strlen(name);
1371 if (((pos - path) + namelen + 2) >= PATH_MAX)
1372 return NULL;
1373 memcpy(pos, name, namelen);
1374 pos[namelen] = '/';
1375 pos[namelen + 1] = '\0';
1376 pos += namelen + 1;
1377 return pos;
1378}
1379
1380static int count_subheaders(struct ctl_table *table)
1381{
1382 int has_files = 0;
1383 int nr_subheaders = 0;
1384 struct ctl_table *entry;
1385
1386
1387 if (!table || !table->procname)
1388 return 1;
1389
1390 for (entry = table; entry->procname; entry++) {
1391 if (entry->child)
1392 nr_subheaders += count_subheaders(entry->child);
1393 else
1394 has_files = 1;
1395 }
1396 return nr_subheaders + has_files;
1397}
1398
1399static int register_leaf_sysctl_tables(const char *path, char *pos,
1400 struct ctl_table_header ***subheader, struct ctl_table_set *set,
1401 struct ctl_table *table)
1402{
1403 struct ctl_table *ctl_table_arg = NULL;
1404 struct ctl_table *entry, *files;
1405 int nr_files = 0;
1406 int nr_dirs = 0;
1407 int err = -ENOMEM;
1408
1409 for (entry = table; entry->procname; entry++) {
1410 if (entry->child)
1411 nr_dirs++;
1412 else
1413 nr_files++;
1414 }
1415
1416 files = table;
1417
1418 if (nr_dirs && nr_files) {
1419 struct ctl_table *new;
1420 files = kzalloc(sizeof(struct ctl_table) * (nr_files + 1),
1421 GFP_KERNEL);
1422 if (!files)
1423 goto out;
1424
1425 ctl_table_arg = files;
1426 for (new = files, entry = table; entry->procname; entry++) {
1427 if (entry->child)
1428 continue;
1429 *new = *entry;
1430 new++;
1431 }
1432 }
1433
1434
1435 if (nr_files || !nr_dirs) {
1436 struct ctl_table_header *header;
1437 header = __register_sysctl_table(set, path, files);
1438 if (!header) {
1439 kfree(ctl_table_arg);
1440 goto out;
1441 }
1442
1443
1444 header->ctl_table_arg = ctl_table_arg;
1445 **subheader = header;
1446 (*subheader)++;
1447 }
1448
1449
1450 for (entry = table; entry->procname; entry++) {
1451 char *child_pos;
1452
1453 if (!entry->child)
1454 continue;
1455
1456 err = -ENAMETOOLONG;
1457 child_pos = append_path(path, pos, entry->procname);
1458 if (!child_pos)
1459 goto out;
1460
1461 err = register_leaf_sysctl_tables(path, child_pos, subheader,
1462 set, entry->child);
1463 pos[0] = '\0';
1464 if (err)
1465 goto out;
1466 }
1467 err = 0;
1468out:
1469
1470 return err;
1471}
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484struct ctl_table_header *__register_sysctl_paths(
1485 struct ctl_table_set *set,
1486 const struct ctl_path *path, struct ctl_table *table)
1487{
1488 struct ctl_table *ctl_table_arg = table;
1489 int nr_subheaders = count_subheaders(table);
1490 struct ctl_table_header *header = NULL, **subheaders, **subheader;
1491 const struct ctl_path *component;
1492 char *new_path, *pos;
1493
1494 pos = new_path = kmalloc(PATH_MAX, GFP_KERNEL);
1495 if (!new_path)
1496 return NULL;
1497
1498 pos[0] = '\0';
1499 for (component = path; component->procname; component++) {
1500 pos = append_path(new_path, pos, component->procname);
1501 if (!pos)
1502 goto out;
1503 }
1504 while (table->procname && table->child && !table[1].procname) {
1505 pos = append_path(new_path, pos, table->procname);
1506 if (!pos)
1507 goto out;
1508 table = table->child;
1509 }
1510 if (nr_subheaders == 1) {
1511 header = __register_sysctl_table(set, new_path, table);
1512 if (header)
1513 header->ctl_table_arg = ctl_table_arg;
1514 } else {
1515 header = kzalloc(sizeof(*header) +
1516 sizeof(*subheaders)*nr_subheaders, GFP_KERNEL);
1517 if (!header)
1518 goto out;
1519
1520 subheaders = (struct ctl_table_header **) (header + 1);
1521 subheader = subheaders;
1522 header->ctl_table_arg = ctl_table_arg;
1523
1524 if (register_leaf_sysctl_tables(new_path, pos, &subheader,
1525 set, table))
1526 goto err_register_leaves;
1527 }
1528
1529out:
1530 kfree(new_path);
1531 return header;
1532
1533err_register_leaves:
1534 while (subheader > subheaders) {
1535 struct ctl_table_header *subh = *(--subheader);
1536 struct ctl_table *table = subh->ctl_table_arg;
1537 unregister_sysctl_table(subh);
1538 kfree(table);
1539 }
1540 kfree(header);
1541 header = NULL;
1542 goto out;
1543}
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
1556 struct ctl_table *table)
1557{
1558 return __register_sysctl_paths(&sysctl_table_root.default_set,
1559 path, table);
1560}
1561EXPORT_SYMBOL(register_sysctl_paths);
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
1573{
1574 static const struct ctl_path null_path[] = { {} };
1575
1576 return register_sysctl_paths(null_path, table);
1577}
1578EXPORT_SYMBOL(register_sysctl_table);
1579
1580static void put_links(struct ctl_table_header *header)
1581{
1582 struct ctl_table_set *root_set = &sysctl_table_root.default_set;
1583 struct ctl_table_root *root = header->root;
1584 struct ctl_dir *parent = header->parent;
1585 struct ctl_dir *core_parent;
1586 struct ctl_table *entry;
1587
1588 if (header->set == root_set)
1589 return;
1590
1591 core_parent = xlate_dir(root_set, parent);
1592 if (IS_ERR(core_parent))
1593 return;
1594
1595 for (entry = header->ctl_table; entry->procname; entry++) {
1596 struct ctl_table_header *link_head;
1597 struct ctl_table *link;
1598 const char *name = entry->procname;
1599
1600 link = find_entry(&link_head, core_parent, name, strlen(name));
1601 if (link &&
1602 ((S_ISDIR(link->mode) && S_ISDIR(entry->mode)) ||
1603 (S_ISLNK(link->mode) && (link->data == root)))) {
1604 drop_sysctl_table(link_head);
1605 }
1606 else {
1607 pr_err("sysctl link missing during unregister: ");
1608 sysctl_print_dir(parent);
1609 pr_cont("/%s\n", name);
1610 }
1611 }
1612}
1613
1614static void drop_sysctl_table(struct ctl_table_header *header)
1615{
1616 struct ctl_dir *parent = header->parent;
1617
1618 if (--header->nreg)
1619 return;
1620
1621 put_links(header);
1622 start_unregistering(header);
1623 if (!--header->count)
1624 kfree_rcu(header, rcu);
1625
1626 if (parent)
1627 drop_sysctl_table(&parent->header);
1628}
1629
1630
1631
1632
1633
1634
1635
1636
1637void unregister_sysctl_table(struct ctl_table_header * header)
1638{
1639 int nr_subheaders;
1640 might_sleep();
1641
1642 if (header == NULL)
1643 return;
1644
1645 nr_subheaders = count_subheaders(header->ctl_table_arg);
1646 if (unlikely(nr_subheaders > 1)) {
1647 struct ctl_table_header **subheaders;
1648 int i;
1649
1650 subheaders = (struct ctl_table_header **)(header + 1);
1651 for (i = nr_subheaders -1; i >= 0; i--) {
1652 struct ctl_table_header *subh = subheaders[i];
1653 struct ctl_table *table = subh->ctl_table_arg;
1654 unregister_sysctl_table(subh);
1655 kfree(table);
1656 }
1657 kfree(header);
1658 return;
1659 }
1660
1661 spin_lock(&sysctl_lock);
1662 drop_sysctl_table(header);
1663 spin_unlock(&sysctl_lock);
1664}
1665EXPORT_SYMBOL(unregister_sysctl_table);
1666
1667void setup_sysctl_set(struct ctl_table_set *set,
1668 struct ctl_table_root *root,
1669 int (*is_seen)(struct ctl_table_set *))
1670{
1671 memset(set, 0, sizeof(*set));
1672 set->is_seen = is_seen;
1673 init_header(&set->dir.header, root, set, NULL, root_table);
1674}
1675
1676void retire_sysctl_set(struct ctl_table_set *set)
1677{
1678 WARN_ON(!RB_EMPTY_ROOT(&set->dir.root));
1679}
1680
1681int __init proc_sys_init(void)
1682{
1683 struct proc_dir_entry *proc_sys_root;
1684
1685 proc_sys_root = proc_mkdir("sys", NULL);
1686 proc_sys_root->proc_iops = &proc_sys_dir_operations;
1687 proc_sys_root->proc_fops = &proc_sys_dir_file_operations;
1688 proc_sys_root->nlink = 0;
1689
1690 return sysctl_init();
1691}
1692