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