1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/module.h>
22#include <linux/mm.h>
23#include <linux/swap.h>
24#include <linux/slab.h>
25#include <linux/sysctl.h>
26#include <linux/proc_fs.h>
27#include <linux/security.h>
28#include <linux/ctype.h>
29#include <linux/utsname.h>
30#include <linux/smp_lock.h>
31#include <linux/fs.h>
32#include <linux/init.h>
33#include <linux/kernel.h>
34#include <linux/kobject.h>
35#include <linux/net.h>
36#include <linux/sysrq.h>
37#include <linux/highuid.h>
38#include <linux/writeback.h>
39#include <linux/hugetlb.h>
40#include <linux/initrd.h>
41#include <linux/key.h>
42#include <linux/times.h>
43#include <linux/limits.h>
44#include <linux/dcache.h>
45#include <linux/syscalls.h>
46#include <linux/vmstat.h>
47#include <linux/nfs_fs.h>
48#include <linux/acpi.h>
49#include <linux/reboot.h>
50#include <linux/ftrace.h>
51
52#include <asm/uaccess.h>
53#include <asm/processor.h>
54
55#ifdef CONFIG_X86
56#include <asm/nmi.h>
57#include <asm/stacktrace.h>
58#include <asm/io.h>
59#endif
60
61static int deprecated_sysctl_warning(struct __sysctl_args *args);
62
63#if defined(CONFIG_SYSCTL)
64
65
66extern int C_A_D;
67extern int print_fatal_signals;
68extern int sysctl_overcommit_memory;
69extern int sysctl_overcommit_ratio;
70extern int sysctl_panic_on_oom;
71extern int sysctl_oom_kill_allocating_task;
72extern int sysctl_oom_dump_tasks;
73extern int max_threads;
74extern int core_uses_pid;
75extern int suid_dumpable;
76extern char core_pattern[];
77extern int pid_max;
78extern int min_free_kbytes;
79extern int pid_max_min, pid_max_max;
80extern int sysctl_drop_caches;
81extern int percpu_pagelist_fraction;
82extern int compat_log;
83extern int maps_protect;
84extern int latencytop_enabled;
85extern int sysctl_nr_open_min, sysctl_nr_open_max;
86#ifdef CONFIG_RCU_TORTURE_TEST
87extern int rcutorture_runnable;
88#endif
89
90
91#if defined(CONFIG_HIGHMEM) || defined(CONFIG_DETECT_SOFTLOCKUP)
92static int one = 1;
93#endif
94
95#ifdef CONFIG_DETECT_SOFTLOCKUP
96static int sixty = 60;
97static int neg_one = -1;
98#endif
99
100#ifdef CONFIG_MMU
101static int two = 2;
102#endif
103
104static int zero;
105static int one_hundred = 100;
106
107
108static int maxolduid = 65535;
109static int minolduid;
110static int min_percpu_pagelist_fract = 8;
111
112static int ngroups_max = NGROUPS_MAX;
113
114#ifdef CONFIG_MODULES
115extern char modprobe_path[];
116#endif
117#ifdef CONFIG_CHR_DEV_SG
118extern int sg_big_buff;
119#endif
120
121#ifdef __sparc__
122extern char reboot_command [];
123extern int stop_a_enabled;
124extern int scons_pwroff;
125#endif
126
127#ifdef __hppa__
128extern int pwrsw_enabled;
129extern int unaligned_enabled;
130#endif
131
132#ifdef CONFIG_S390
133#ifdef CONFIG_MATHEMU
134extern int sysctl_ieee_emulation_warnings;
135#endif
136extern int sysctl_userprocess_debug;
137extern int spin_retry;
138#endif
139
140#ifdef CONFIG_BSD_PROCESS_ACCT
141extern int acct_parm[];
142#endif
143
144#ifdef CONFIG_IA64
145extern int no_unaligned_warning;
146#endif
147
148#ifdef CONFIG_RT_MUTEXES
149extern int max_lock_depth;
150#endif
151
152#ifdef CONFIG_PROC_SYSCTL
153static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
154 void __user *buffer, size_t *lenp, loff_t *ppos);
155static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
156 void __user *buffer, size_t *lenp, loff_t *ppos);
157#endif
158
159static struct ctl_table root_table[];
160static struct ctl_table_root sysctl_table_root;
161static struct ctl_table_header root_table_header = {
162 .count = 1,
163 .ctl_table = root_table,
164 .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),
165 .root = &sysctl_table_root,
166 .set = &sysctl_table_root.default_set,
167};
168static struct ctl_table_root sysctl_table_root = {
169 .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
170 .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry),
171};
172
173static struct ctl_table kern_table[];
174static struct ctl_table vm_table[];
175static struct ctl_table fs_table[];
176static struct ctl_table debug_table[];
177static struct ctl_table dev_table[];
178extern struct ctl_table random_table[];
179#ifdef CONFIG_INOTIFY_USER
180extern struct ctl_table inotify_table[];
181#endif
182#ifdef CONFIG_EPOLL
183extern struct ctl_table epoll_table[];
184#endif
185
186#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
187int sysctl_legacy_va_layout;
188#endif
189
190extern int prove_locking;
191extern int lock_stat;
192
193
194
195static struct ctl_table root_table[] = {
196 {
197 .ctl_name = CTL_KERN,
198 .procname = "kernel",
199 .mode = 0555,
200 .child = kern_table,
201 },
202 {
203 .ctl_name = CTL_VM,
204 .procname = "vm",
205 .mode = 0555,
206 .child = vm_table,
207 },
208 {
209 .ctl_name = CTL_FS,
210 .procname = "fs",
211 .mode = 0555,
212 .child = fs_table,
213 },
214 {
215 .ctl_name = CTL_DEBUG,
216 .procname = "debug",
217 .mode = 0555,
218 .child = debug_table,
219 },
220 {
221 .ctl_name = CTL_DEV,
222 .procname = "dev",
223 .mode = 0555,
224 .child = dev_table,
225 },
226
227
228
229
230 { .ctl_name = 0 }
231};
232
233#ifdef CONFIG_SCHED_DEBUG
234static int min_sched_granularity_ns = 100000;
235static int max_sched_granularity_ns = NSEC_PER_SEC;
236static int min_wakeup_granularity_ns;
237static int max_wakeup_granularity_ns = NSEC_PER_SEC;
238#endif
239
240static struct ctl_table kern_table[] = {
241#ifdef CONFIG_SCHED_DEBUG
242 {
243 .ctl_name = CTL_UNNUMBERED,
244 .procname = "sched_min_granularity_ns",
245 .data = &sysctl_sched_min_granularity,
246 .maxlen = sizeof(unsigned int),
247 .mode = 0644,
248 .proc_handler = &sched_nr_latency_handler,
249 .strategy = &sysctl_intvec,
250 .extra1 = &min_sched_granularity_ns,
251 .extra2 = &max_sched_granularity_ns,
252 },
253 {
254 .ctl_name = CTL_UNNUMBERED,
255 .procname = "sched_latency_ns",
256 .data = &sysctl_sched_latency,
257 .maxlen = sizeof(unsigned int),
258 .mode = 0644,
259 .proc_handler = &sched_nr_latency_handler,
260 .strategy = &sysctl_intvec,
261 .extra1 = &min_sched_granularity_ns,
262 .extra2 = &max_sched_granularity_ns,
263 },
264 {
265 .ctl_name = CTL_UNNUMBERED,
266 .procname = "sched_wakeup_granularity_ns",
267 .data = &sysctl_sched_wakeup_granularity,
268 .maxlen = sizeof(unsigned int),
269 .mode = 0644,
270 .proc_handler = &proc_dointvec_minmax,
271 .strategy = &sysctl_intvec,
272 .extra1 = &min_wakeup_granularity_ns,
273 .extra2 = &max_wakeup_granularity_ns,
274 },
275 {
276 .ctl_name = CTL_UNNUMBERED,
277 .procname = "sched_shares_ratelimit",
278 .data = &sysctl_sched_shares_ratelimit,
279 .maxlen = sizeof(unsigned int),
280 .mode = 0644,
281 .proc_handler = &proc_dointvec,
282 },
283 {
284 .ctl_name = CTL_UNNUMBERED,
285 .procname = "sched_child_runs_first",
286 .data = &sysctl_sched_child_runs_first,
287 .maxlen = sizeof(unsigned int),
288 .mode = 0644,
289 .proc_handler = &proc_dointvec,
290 },
291 {
292 .ctl_name = CTL_UNNUMBERED,
293 .procname = "sched_features",
294 .data = &sysctl_sched_features,
295 .maxlen = sizeof(unsigned int),
296 .mode = 0644,
297 .proc_handler = &proc_dointvec,
298 },
299 {
300 .ctl_name = CTL_UNNUMBERED,
301 .procname = "sched_migration_cost",
302 .data = &sysctl_sched_migration_cost,
303 .maxlen = sizeof(unsigned int),
304 .mode = 0644,
305 .proc_handler = &proc_dointvec,
306 },
307 {
308 .ctl_name = CTL_UNNUMBERED,
309 .procname = "sched_nr_migrate",
310 .data = &sysctl_sched_nr_migrate,
311 .maxlen = sizeof(unsigned int),
312 .mode = 0644,
313 .proc_handler = &proc_dointvec,
314 },
315#endif
316 {
317 .ctl_name = CTL_UNNUMBERED,
318 .procname = "sched_rt_period_us",
319 .data = &sysctl_sched_rt_period,
320 .maxlen = sizeof(unsigned int),
321 .mode = 0644,
322 .proc_handler = &sched_rt_handler,
323 },
324 {
325 .ctl_name = CTL_UNNUMBERED,
326 .procname = "sched_rt_runtime_us",
327 .data = &sysctl_sched_rt_runtime,
328 .maxlen = sizeof(int),
329 .mode = 0644,
330 .proc_handler = &sched_rt_handler,
331 },
332 {
333 .ctl_name = CTL_UNNUMBERED,
334 .procname = "sched_compat_yield",
335 .data = &sysctl_sched_compat_yield,
336 .maxlen = sizeof(unsigned int),
337 .mode = 0644,
338 .proc_handler = &proc_dointvec,
339 },
340#ifdef CONFIG_PROVE_LOCKING
341 {
342 .ctl_name = CTL_UNNUMBERED,
343 .procname = "prove_locking",
344 .data = &prove_locking,
345 .maxlen = sizeof(int),
346 .mode = 0644,
347 .proc_handler = &proc_dointvec,
348 },
349#endif
350#ifdef CONFIG_LOCK_STAT
351 {
352 .ctl_name = CTL_UNNUMBERED,
353 .procname = "lock_stat",
354 .data = &lock_stat,
355 .maxlen = sizeof(int),
356 .mode = 0644,
357 .proc_handler = &proc_dointvec,
358 },
359#endif
360 {
361 .ctl_name = KERN_PANIC,
362 .procname = "panic",
363 .data = &panic_timeout,
364 .maxlen = sizeof(int),
365 .mode = 0644,
366 .proc_handler = &proc_dointvec,
367 },
368 {
369 .ctl_name = KERN_CORE_USES_PID,
370 .procname = "core_uses_pid",
371 .data = &core_uses_pid,
372 .maxlen = sizeof(int),
373 .mode = 0644,
374 .proc_handler = &proc_dointvec,
375 },
376 {
377 .ctl_name = KERN_CORE_PATTERN,
378 .procname = "core_pattern",
379 .data = core_pattern,
380 .maxlen = CORENAME_MAX_SIZE,
381 .mode = 0644,
382 .proc_handler = &proc_dostring,
383 .strategy = &sysctl_string,
384 },
385#ifdef CONFIG_PROC_SYSCTL
386 {
387 .procname = "tainted",
388 .data = &tainted,
389 .maxlen = sizeof(int),
390 .mode = 0644,
391 .proc_handler = &proc_dointvec_taint,
392 },
393#endif
394#ifdef CONFIG_LATENCYTOP
395 {
396 .procname = "latencytop",
397 .data = &latencytop_enabled,
398 .maxlen = sizeof(int),
399 .mode = 0644,
400 .proc_handler = &proc_dointvec,
401 },
402#endif
403#ifdef CONFIG_BLK_DEV_INITRD
404 {
405 .ctl_name = KERN_REALROOTDEV,
406 .procname = "real-root-dev",
407 .data = &real_root_dev,
408 .maxlen = sizeof(int),
409 .mode = 0644,
410 .proc_handler = &proc_dointvec,
411 },
412#endif
413 {
414 .ctl_name = CTL_UNNUMBERED,
415 .procname = "print-fatal-signals",
416 .data = &print_fatal_signals,
417 .maxlen = sizeof(int),
418 .mode = 0644,
419 .proc_handler = &proc_dointvec,
420 },
421#ifdef __sparc__
422 {
423 .ctl_name = KERN_SPARC_REBOOT,
424 .procname = "reboot-cmd",
425 .data = reboot_command,
426 .maxlen = 256,
427 .mode = 0644,
428 .proc_handler = &proc_dostring,
429 .strategy = &sysctl_string,
430 },
431 {
432 .ctl_name = KERN_SPARC_STOP_A,
433 .procname = "stop-a",
434 .data = &stop_a_enabled,
435 .maxlen = sizeof (int),
436 .mode = 0644,
437 .proc_handler = &proc_dointvec,
438 },
439 {
440 .ctl_name = KERN_SPARC_SCONS_PWROFF,
441 .procname = "scons-poweroff",
442 .data = &scons_pwroff,
443 .maxlen = sizeof (int),
444 .mode = 0644,
445 .proc_handler = &proc_dointvec,
446 },
447#endif
448#ifdef __hppa__
449 {
450 .ctl_name = KERN_HPPA_PWRSW,
451 .procname = "soft-power",
452 .data = &pwrsw_enabled,
453 .maxlen = sizeof (int),
454 .mode = 0644,
455 .proc_handler = &proc_dointvec,
456 },
457 {
458 .ctl_name = KERN_HPPA_UNALIGNED,
459 .procname = "unaligned-trap",
460 .data = &unaligned_enabled,
461 .maxlen = sizeof (int),
462 .mode = 0644,
463 .proc_handler = &proc_dointvec,
464 },
465#endif
466 {
467 .ctl_name = KERN_CTLALTDEL,
468 .procname = "ctrl-alt-del",
469 .data = &C_A_D,
470 .maxlen = sizeof(int),
471 .mode = 0644,
472 .proc_handler = &proc_dointvec,
473 },
474#ifdef CONFIG_FTRACE
475 {
476 .ctl_name = CTL_UNNUMBERED,
477 .procname = "ftrace_enabled",
478 .data = &ftrace_enabled,
479 .maxlen = sizeof(int),
480 .mode = 0644,
481 .proc_handler = &ftrace_enable_sysctl,
482 },
483#endif
484#ifdef CONFIG_MODULES
485 {
486 .ctl_name = KERN_MODPROBE,
487 .procname = "modprobe",
488 .data = &modprobe_path,
489 .maxlen = KMOD_PATH_LEN,
490 .mode = 0644,
491 .proc_handler = &proc_dostring,
492 .strategy = &sysctl_string,
493 },
494#endif
495#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
496 {
497 .ctl_name = KERN_HOTPLUG,
498 .procname = "hotplug",
499 .data = &uevent_helper,
500 .maxlen = UEVENT_HELPER_PATH_LEN,
501 .mode = 0644,
502 .proc_handler = &proc_dostring,
503 .strategy = &sysctl_string,
504 },
505#endif
506#ifdef CONFIG_CHR_DEV_SG
507 {
508 .ctl_name = KERN_SG_BIG_BUFF,
509 .procname = "sg-big-buff",
510 .data = &sg_big_buff,
511 .maxlen = sizeof (int),
512 .mode = 0444,
513 .proc_handler = &proc_dointvec,
514 },
515#endif
516#ifdef CONFIG_BSD_PROCESS_ACCT
517 {
518 .ctl_name = KERN_ACCT,
519 .procname = "acct",
520 .data = &acct_parm,
521 .maxlen = 3*sizeof(int),
522 .mode = 0644,
523 .proc_handler = &proc_dointvec,
524 },
525#endif
526#ifdef CONFIG_MAGIC_SYSRQ
527 {
528 .ctl_name = KERN_SYSRQ,
529 .procname = "sysrq",
530 .data = &__sysrq_enabled,
531 .maxlen = sizeof (int),
532 .mode = 0644,
533 .proc_handler = &proc_dointvec,
534 },
535#endif
536#ifdef CONFIG_PROC_SYSCTL
537 {
538 .procname = "cad_pid",
539 .data = NULL,
540 .maxlen = sizeof (int),
541 .mode = 0600,
542 .proc_handler = &proc_do_cad_pid,
543 },
544#endif
545 {
546 .ctl_name = KERN_MAX_THREADS,
547 .procname = "threads-max",
548 .data = &max_threads,
549 .maxlen = sizeof(int),
550 .mode = 0644,
551 .proc_handler = &proc_dointvec,
552 },
553 {
554 .ctl_name = KERN_RANDOM,
555 .procname = "random",
556 .mode = 0555,
557 .child = random_table,
558 },
559 {
560 .ctl_name = KERN_OVERFLOWUID,
561 .procname = "overflowuid",
562 .data = &overflowuid,
563 .maxlen = sizeof(int),
564 .mode = 0644,
565 .proc_handler = &proc_dointvec_minmax,
566 .strategy = &sysctl_intvec,
567 .extra1 = &minolduid,
568 .extra2 = &maxolduid,
569 },
570 {
571 .ctl_name = KERN_OVERFLOWGID,
572 .procname = "overflowgid",
573 .data = &overflowgid,
574 .maxlen = sizeof(int),
575 .mode = 0644,
576 .proc_handler = &proc_dointvec_minmax,
577 .strategy = &sysctl_intvec,
578 .extra1 = &minolduid,
579 .extra2 = &maxolduid,
580 },
581#ifdef CONFIG_S390
582#ifdef CONFIG_MATHEMU
583 {
584 .ctl_name = KERN_IEEE_EMULATION_WARNINGS,
585 .procname = "ieee_emulation_warnings",
586 .data = &sysctl_ieee_emulation_warnings,
587 .maxlen = sizeof(int),
588 .mode = 0644,
589 .proc_handler = &proc_dointvec,
590 },
591#endif
592 {
593 .ctl_name = KERN_S390_USER_DEBUG_LOGGING,
594 .procname = "userprocess_debug",
595 .data = &sysctl_userprocess_debug,
596 .maxlen = sizeof(int),
597 .mode = 0644,
598 .proc_handler = &proc_dointvec,
599 },
600#endif
601 {
602 .ctl_name = KERN_PIDMAX,
603 .procname = "pid_max",
604 .data = &pid_max,
605 .maxlen = sizeof (int),
606 .mode = 0644,
607 .proc_handler = &proc_dointvec_minmax,
608 .strategy = sysctl_intvec,
609 .extra1 = &pid_max_min,
610 .extra2 = &pid_max_max,
611 },
612 {
613 .ctl_name = KERN_PANIC_ON_OOPS,
614 .procname = "panic_on_oops",
615 .data = &panic_on_oops,
616 .maxlen = sizeof(int),
617 .mode = 0644,
618 .proc_handler = &proc_dointvec,
619 },
620#if defined CONFIG_PRINTK
621 {
622 .ctl_name = KERN_PRINTK,
623 .procname = "printk",
624 .data = &console_loglevel,
625 .maxlen = 4*sizeof(int),
626 .mode = 0644,
627 .proc_handler = &proc_dointvec,
628 },
629 {
630 .ctl_name = KERN_PRINTK_RATELIMIT,
631 .procname = "printk_ratelimit",
632 .data = &printk_ratelimit_state.interval,
633 .maxlen = sizeof(int),
634 .mode = 0644,
635 .proc_handler = &proc_dointvec_jiffies,
636 .strategy = &sysctl_jiffies,
637 },
638 {
639 .ctl_name = KERN_PRINTK_RATELIMIT_BURST,
640 .procname = "printk_ratelimit_burst",
641 .data = &printk_ratelimit_state.burst,
642 .maxlen = sizeof(int),
643 .mode = 0644,
644 .proc_handler = &proc_dointvec,
645 },
646#endif
647 {
648 .ctl_name = KERN_NGROUPS_MAX,
649 .procname = "ngroups_max",
650 .data = &ngroups_max,
651 .maxlen = sizeof (int),
652 .mode = 0444,
653 .proc_handler = &proc_dointvec,
654 },
655#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
656 {
657 .ctl_name = KERN_UNKNOWN_NMI_PANIC,
658 .procname = "unknown_nmi_panic",
659 .data = &unknown_nmi_panic,
660 .maxlen = sizeof (int),
661 .mode = 0644,
662 .proc_handler = &proc_dointvec,
663 },
664 {
665 .procname = "nmi_watchdog",
666 .data = &nmi_watchdog_enabled,
667 .maxlen = sizeof (int),
668 .mode = 0644,
669 .proc_handler = &proc_nmi_enabled,
670 },
671#endif
672#if defined(CONFIG_X86)
673 {
674 .ctl_name = KERN_PANIC_ON_NMI,
675 .procname = "panic_on_unrecovered_nmi",
676 .data = &panic_on_unrecovered_nmi,
677 .maxlen = sizeof(int),
678 .mode = 0644,
679 .proc_handler = &proc_dointvec,
680 },
681 {
682 .ctl_name = KERN_BOOTLOADER_TYPE,
683 .procname = "bootloader_type",
684 .data = &bootloader_type,
685 .maxlen = sizeof (int),
686 .mode = 0444,
687 .proc_handler = &proc_dointvec,
688 },
689 {
690 .ctl_name = CTL_UNNUMBERED,
691 .procname = "kstack_depth_to_print",
692 .data = &kstack_depth_to_print,
693 .maxlen = sizeof(int),
694 .mode = 0644,
695 .proc_handler = &proc_dointvec,
696 },
697 {
698 .ctl_name = CTL_UNNUMBERED,
699 .procname = "io_delay_type",
700 .data = &io_delay_type,
701 .maxlen = sizeof(int),
702 .mode = 0644,
703 .proc_handler = &proc_dointvec,
704 },
705#endif
706#if defined(CONFIG_MMU)
707 {
708 .ctl_name = KERN_RANDOMIZE,
709 .procname = "randomize_va_space",
710 .data = &randomize_va_space,
711 .maxlen = sizeof(int),
712 .mode = 0644,
713 .proc_handler = &proc_dointvec,
714 },
715#endif
716#if defined(CONFIG_S390) && defined(CONFIG_SMP)
717 {
718 .ctl_name = KERN_SPIN_RETRY,
719 .procname = "spin_retry",
720 .data = &spin_retry,
721 .maxlen = sizeof (int),
722 .mode = 0644,
723 .proc_handler = &proc_dointvec,
724 },
725#endif
726#if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86)
727 {
728 .procname = "acpi_video_flags",
729 .data = &acpi_realmode_flags,
730 .maxlen = sizeof (unsigned long),
731 .mode = 0644,
732 .proc_handler = &proc_doulongvec_minmax,
733 },
734#endif
735#ifdef CONFIG_IA64
736 {
737 .ctl_name = KERN_IA64_UNALIGNED,
738 .procname = "ignore-unaligned-usertrap",
739 .data = &no_unaligned_warning,
740 .maxlen = sizeof (int),
741 .mode = 0644,
742 .proc_handler = &proc_dointvec,
743 },
744#endif
745#ifdef CONFIG_DETECT_SOFTLOCKUP
746 {
747 .ctl_name = CTL_UNNUMBERED,
748 .procname = "softlockup_panic",
749 .data = &softlockup_panic,
750 .maxlen = sizeof(int),
751 .mode = 0644,
752 .proc_handler = &proc_dointvec_minmax,
753 .strategy = &sysctl_intvec,
754 .extra1 = &zero,
755 .extra2 = &one,
756 },
757 {
758 .ctl_name = CTL_UNNUMBERED,
759 .procname = "softlockup_thresh",
760 .data = &softlockup_thresh,
761 .maxlen = sizeof(int),
762 .mode = 0644,
763 .proc_handler = &proc_dointvec_minmax,
764 .strategy = &sysctl_intvec,
765 .extra1 = &neg_one,
766 .extra2 = &sixty,
767 },
768 {
769 .ctl_name = CTL_UNNUMBERED,
770 .procname = "hung_task_check_count",
771 .data = &sysctl_hung_task_check_count,
772 .maxlen = sizeof(unsigned long),
773 .mode = 0644,
774 .proc_handler = &proc_doulongvec_minmax,
775 .strategy = &sysctl_intvec,
776 },
777 {
778 .ctl_name = CTL_UNNUMBERED,
779 .procname = "hung_task_timeout_secs",
780 .data = &sysctl_hung_task_timeout_secs,
781 .maxlen = sizeof(unsigned long),
782 .mode = 0644,
783 .proc_handler = &proc_doulongvec_minmax,
784 .strategy = &sysctl_intvec,
785 },
786 {
787 .ctl_name = CTL_UNNUMBERED,
788 .procname = "hung_task_warnings",
789 .data = &sysctl_hung_task_warnings,
790 .maxlen = sizeof(unsigned long),
791 .mode = 0644,
792 .proc_handler = &proc_doulongvec_minmax,
793 .strategy = &sysctl_intvec,
794 },
795#endif
796#ifdef CONFIG_COMPAT
797 {
798 .ctl_name = KERN_COMPAT_LOG,
799 .procname = "compat-log",
800 .data = &compat_log,
801 .maxlen = sizeof (int),
802 .mode = 0644,
803 .proc_handler = &proc_dointvec,
804 },
805#endif
806#ifdef CONFIG_RT_MUTEXES
807 {
808 .ctl_name = KERN_MAX_LOCK_DEPTH,
809 .procname = "max_lock_depth",
810 .data = &max_lock_depth,
811 .maxlen = sizeof(int),
812 .mode = 0644,
813 .proc_handler = &proc_dointvec,
814 },
815#endif
816#ifdef CONFIG_PROC_FS
817 {
818 .ctl_name = CTL_UNNUMBERED,
819 .procname = "maps_protect",
820 .data = &maps_protect,
821 .maxlen = sizeof(int),
822 .mode = 0644,
823 .proc_handler = &proc_dointvec,
824 },
825#endif
826 {
827 .ctl_name = CTL_UNNUMBERED,
828 .procname = "poweroff_cmd",
829 .data = &poweroff_cmd,
830 .maxlen = POWEROFF_CMD_PATH_LEN,
831 .mode = 0644,
832 .proc_handler = &proc_dostring,
833 .strategy = &sysctl_string,
834 },
835#ifdef CONFIG_KEYS
836 {
837 .ctl_name = CTL_UNNUMBERED,
838 .procname = "keys",
839 .mode = 0555,
840 .child = key_sysctls,
841 },
842#endif
843#ifdef CONFIG_RCU_TORTURE_TEST
844 {
845 .ctl_name = CTL_UNNUMBERED,
846 .procname = "rcutorture_runnable",
847 .data = &rcutorture_runnable,
848 .maxlen = sizeof(int),
849 .mode = 0644,
850 .proc_handler = &proc_dointvec,
851 },
852#endif
853
854
855
856
857 { .ctl_name = 0 }
858};
859
860static struct ctl_table vm_table[] = {
861 {
862 .ctl_name = VM_OVERCOMMIT_MEMORY,
863 .procname = "overcommit_memory",
864 .data = &sysctl_overcommit_memory,
865 .maxlen = sizeof(sysctl_overcommit_memory),
866 .mode = 0644,
867 .proc_handler = &proc_dointvec,
868 },
869 {
870 .ctl_name = VM_PANIC_ON_OOM,
871 .procname = "panic_on_oom",
872 .data = &sysctl_panic_on_oom,
873 .maxlen = sizeof(sysctl_panic_on_oom),
874 .mode = 0644,
875 .proc_handler = &proc_dointvec,
876 },
877 {
878 .ctl_name = CTL_UNNUMBERED,
879 .procname = "oom_kill_allocating_task",
880 .data = &sysctl_oom_kill_allocating_task,
881 .maxlen = sizeof(sysctl_oom_kill_allocating_task),
882 .mode = 0644,
883 .proc_handler = &proc_dointvec,
884 },
885 {
886 .ctl_name = CTL_UNNUMBERED,
887 .procname = "oom_dump_tasks",
888 .data = &sysctl_oom_dump_tasks,
889 .maxlen = sizeof(sysctl_oom_dump_tasks),
890 .mode = 0644,
891 .proc_handler = &proc_dointvec,
892 },
893 {
894 .ctl_name = VM_OVERCOMMIT_RATIO,
895 .procname = "overcommit_ratio",
896 .data = &sysctl_overcommit_ratio,
897 .maxlen = sizeof(sysctl_overcommit_ratio),
898 .mode = 0644,
899 .proc_handler = &proc_dointvec,
900 },
901 {
902 .ctl_name = VM_PAGE_CLUSTER,
903 .procname = "page-cluster",
904 .data = &page_cluster,
905 .maxlen = sizeof(int),
906 .mode = 0644,
907 .proc_handler = &proc_dointvec,
908 },
909 {
910 .ctl_name = VM_DIRTY_BACKGROUND,
911 .procname = "dirty_background_ratio",
912 .data = &dirty_background_ratio,
913 .maxlen = sizeof(dirty_background_ratio),
914 .mode = 0644,
915 .proc_handler = &proc_dointvec_minmax,
916 .strategy = &sysctl_intvec,
917 .extra1 = &zero,
918 .extra2 = &one_hundred,
919 },
920 {
921 .ctl_name = VM_DIRTY_RATIO,
922 .procname = "dirty_ratio",
923 .data = &vm_dirty_ratio,
924 .maxlen = sizeof(vm_dirty_ratio),
925 .mode = 0644,
926 .proc_handler = &dirty_ratio_handler,
927 .strategy = &sysctl_intvec,
928 .extra1 = &zero,
929 .extra2 = &one_hundred,
930 },
931 {
932 .procname = "dirty_writeback_centisecs",
933 .data = &dirty_writeback_interval,
934 .maxlen = sizeof(dirty_writeback_interval),
935 .mode = 0644,
936 .proc_handler = &dirty_writeback_centisecs_handler,
937 },
938 {
939 .procname = "dirty_expire_centisecs",
940 .data = &dirty_expire_interval,
941 .maxlen = sizeof(dirty_expire_interval),
942 .mode = 0644,
943 .proc_handler = &proc_dointvec_userhz_jiffies,
944 },
945 {
946 .ctl_name = VM_NR_PDFLUSH_THREADS,
947 .procname = "nr_pdflush_threads",
948 .data = &nr_pdflush_threads,
949 .maxlen = sizeof nr_pdflush_threads,
950 .mode = 0444 ,
951 .proc_handler = &proc_dointvec,
952 },
953 {
954 .ctl_name = VM_SWAPPINESS,
955 .procname = "swappiness",
956 .data = &vm_swappiness,
957 .maxlen = sizeof(vm_swappiness),
958 .mode = 0644,
959 .proc_handler = &proc_dointvec_minmax,
960 .strategy = &sysctl_intvec,
961 .extra1 = &zero,
962 .extra2 = &one_hundred,
963 },
964#ifdef CONFIG_HUGETLB_PAGE
965 {
966 .procname = "nr_hugepages",
967 .data = NULL,
968 .maxlen = sizeof(unsigned long),
969 .mode = 0644,
970 .proc_handler = &hugetlb_sysctl_handler,
971 .extra1 = (void *)&hugetlb_zero,
972 .extra2 = (void *)&hugetlb_infinity,
973 },
974 {
975 .ctl_name = VM_HUGETLB_GROUP,
976 .procname = "hugetlb_shm_group",
977 .data = &sysctl_hugetlb_shm_group,
978 .maxlen = sizeof(gid_t),
979 .mode = 0644,
980 .proc_handler = &proc_dointvec,
981 },
982 {
983 .ctl_name = CTL_UNNUMBERED,
984 .procname = "hugepages_treat_as_movable",
985 .data = &hugepages_treat_as_movable,
986 .maxlen = sizeof(int),
987 .mode = 0644,
988 .proc_handler = &hugetlb_treat_movable_handler,
989 },
990 {
991 .ctl_name = CTL_UNNUMBERED,
992 .procname = "nr_overcommit_hugepages",
993 .data = NULL,
994 .maxlen = sizeof(unsigned long),
995 .mode = 0644,
996 .proc_handler = &hugetlb_overcommit_handler,
997 .extra1 = (void *)&hugetlb_zero,
998 .extra2 = (void *)&hugetlb_infinity,
999 },
1000#endif
1001 {
1002 .ctl_name = VM_LOWMEM_RESERVE_RATIO,
1003 .procname = "lowmem_reserve_ratio",
1004 .data = &sysctl_lowmem_reserve_ratio,
1005 .maxlen = sizeof(sysctl_lowmem_reserve_ratio),
1006 .mode = 0644,
1007 .proc_handler = &lowmem_reserve_ratio_sysctl_handler,
1008 .strategy = &sysctl_intvec,
1009 },
1010 {
1011 .ctl_name = VM_DROP_PAGECACHE,
1012 .procname = "drop_caches",
1013 .data = &sysctl_drop_caches,
1014 .maxlen = sizeof(int),
1015 .mode = 0644,
1016 .proc_handler = drop_caches_sysctl_handler,
1017 .strategy = &sysctl_intvec,
1018 },
1019 {
1020 .ctl_name = VM_MIN_FREE_KBYTES,
1021 .procname = "min_free_kbytes",
1022 .data = &min_free_kbytes,
1023 .maxlen = sizeof(min_free_kbytes),
1024 .mode = 0644,
1025 .proc_handler = &min_free_kbytes_sysctl_handler,
1026 .strategy = &sysctl_intvec,
1027 .extra1 = &zero,
1028 },
1029 {
1030 .ctl_name = VM_PERCPU_PAGELIST_FRACTION,
1031 .procname = "percpu_pagelist_fraction",
1032 .data = &percpu_pagelist_fraction,
1033 .maxlen = sizeof(percpu_pagelist_fraction),
1034 .mode = 0644,
1035 .proc_handler = &percpu_pagelist_fraction_sysctl_handler,
1036 .strategy = &sysctl_intvec,
1037 .extra1 = &min_percpu_pagelist_fract,
1038 },
1039#ifdef CONFIG_MMU
1040 {
1041 .ctl_name = VM_MAX_MAP_COUNT,
1042 .procname = "max_map_count",
1043 .data = &sysctl_max_map_count,
1044 .maxlen = sizeof(sysctl_max_map_count),
1045 .mode = 0644,
1046 .proc_handler = &proc_dointvec
1047 },
1048#endif
1049 {
1050 .ctl_name = VM_LAPTOP_MODE,
1051 .procname = "laptop_mode",
1052 .data = &laptop_mode,
1053 .maxlen = sizeof(laptop_mode),
1054 .mode = 0644,
1055 .proc_handler = &proc_dointvec_jiffies,
1056 .strategy = &sysctl_jiffies,
1057 },
1058 {
1059 .ctl_name = VM_BLOCK_DUMP,
1060 .procname = "block_dump",
1061 .data = &block_dump,
1062 .maxlen = sizeof(block_dump),
1063 .mode = 0644,
1064 .proc_handler = &proc_dointvec,
1065 .strategy = &sysctl_intvec,
1066 .extra1 = &zero,
1067 },
1068 {
1069 .ctl_name = VM_VFS_CACHE_PRESSURE,
1070 .procname = "vfs_cache_pressure",
1071 .data = &sysctl_vfs_cache_pressure,
1072 .maxlen = sizeof(sysctl_vfs_cache_pressure),
1073 .mode = 0644,
1074 .proc_handler = &proc_dointvec,
1075 .strategy = &sysctl_intvec,
1076 .extra1 = &zero,
1077 },
1078#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
1079 {
1080 .ctl_name = VM_LEGACY_VA_LAYOUT,
1081 .procname = "legacy_va_layout",
1082 .data = &sysctl_legacy_va_layout,
1083 .maxlen = sizeof(sysctl_legacy_va_layout),
1084 .mode = 0644,
1085 .proc_handler = &proc_dointvec,
1086 .strategy = &sysctl_intvec,
1087 .extra1 = &zero,
1088 },
1089#endif
1090#ifdef CONFIG_NUMA
1091 {
1092 .ctl_name = VM_ZONE_RECLAIM_MODE,
1093 .procname = "zone_reclaim_mode",
1094 .data = &zone_reclaim_mode,
1095 .maxlen = sizeof(zone_reclaim_mode),
1096 .mode = 0644,
1097 .proc_handler = &proc_dointvec,
1098 .strategy = &sysctl_intvec,
1099 .extra1 = &zero,
1100 },
1101 {
1102 .ctl_name = VM_MIN_UNMAPPED,
1103 .procname = "min_unmapped_ratio",
1104 .data = &sysctl_min_unmapped_ratio,
1105 .maxlen = sizeof(sysctl_min_unmapped_ratio),
1106 .mode = 0644,
1107 .proc_handler = &sysctl_min_unmapped_ratio_sysctl_handler,
1108 .strategy = &sysctl_intvec,
1109 .extra1 = &zero,
1110 .extra2 = &one_hundred,
1111 },
1112 {
1113 .ctl_name = VM_MIN_SLAB,
1114 .procname = "min_slab_ratio",
1115 .data = &sysctl_min_slab_ratio,
1116 .maxlen = sizeof(sysctl_min_slab_ratio),
1117 .mode = 0644,
1118 .proc_handler = &sysctl_min_slab_ratio_sysctl_handler,
1119 .strategy = &sysctl_intvec,
1120 .extra1 = &zero,
1121 .extra2 = &one_hundred,
1122 },
1123#endif
1124#ifdef CONFIG_SMP
1125 {
1126 .ctl_name = CTL_UNNUMBERED,
1127 .procname = "stat_interval",
1128 .data = &sysctl_stat_interval,
1129 .maxlen = sizeof(sysctl_stat_interval),
1130 .mode = 0644,
1131 .proc_handler = &proc_dointvec_jiffies,
1132 .strategy = &sysctl_jiffies,
1133 },
1134#endif
1135 {
1136 .ctl_name = CTL_UNNUMBERED,
1137 .procname = "mmap_min_addr",
1138 .data = &mmap_min_addr,
1139 .maxlen = sizeof(unsigned long),
1140 .mode = 0644,
1141 .proc_handler = &proc_doulongvec_minmax,
1142 },
1143#ifdef CONFIG_NUMA
1144 {
1145 .ctl_name = CTL_UNNUMBERED,
1146 .procname = "numa_zonelist_order",
1147 .data = &numa_zonelist_order,
1148 .maxlen = NUMA_ZONELIST_ORDER_LEN,
1149 .mode = 0644,
1150 .proc_handler = &numa_zonelist_order_handler,
1151 .strategy = &sysctl_string,
1152 },
1153#endif
1154#if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \
1155 (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
1156 {
1157 .ctl_name = VM_VDSO_ENABLED,
1158 .procname = "vdso_enabled",
1159 .data = &vdso_enabled,
1160 .maxlen = sizeof(vdso_enabled),
1161 .mode = 0644,
1162 .proc_handler = &proc_dointvec,
1163 .strategy = &sysctl_intvec,
1164 .extra1 = &zero,
1165 },
1166#endif
1167#ifdef CONFIG_HIGHMEM
1168 {
1169 .ctl_name = CTL_UNNUMBERED,
1170 .procname = "highmem_is_dirtyable",
1171 .data = &vm_highmem_is_dirtyable,
1172 .maxlen = sizeof(vm_highmem_is_dirtyable),
1173 .mode = 0644,
1174 .proc_handler = &proc_dointvec_minmax,
1175 .strategy = &sysctl_intvec,
1176 .extra1 = &zero,
1177 .extra2 = &one,
1178 },
1179#endif
1180
1181
1182
1183
1184 { .ctl_name = 0 }
1185};
1186
1187#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
1188static struct ctl_table binfmt_misc_table[] = {
1189 { .ctl_name = 0 }
1190};
1191#endif
1192
1193static struct ctl_table fs_table[] = {
1194 {
1195 .ctl_name = FS_NRINODE,
1196 .procname = "inode-nr",
1197 .data = &inodes_stat,
1198 .maxlen = 2*sizeof(int),
1199 .mode = 0444,
1200 .proc_handler = &proc_dointvec,
1201 },
1202 {
1203 .ctl_name = FS_STATINODE,
1204 .procname = "inode-state",
1205 .data = &inodes_stat,
1206 .maxlen = 7*sizeof(int),
1207 .mode = 0444,
1208 .proc_handler = &proc_dointvec,
1209 },
1210 {
1211 .procname = "file-nr",
1212 .data = &files_stat,
1213 .maxlen = 3*sizeof(int),
1214 .mode = 0444,
1215 .proc_handler = &proc_nr_files,
1216 },
1217 {
1218 .ctl_name = FS_MAXFILE,
1219 .procname = "file-max",
1220 .data = &files_stat.max_files,
1221 .maxlen = sizeof(int),
1222 .mode = 0644,
1223 .proc_handler = &proc_dointvec,
1224 },
1225 {
1226 .ctl_name = CTL_UNNUMBERED,
1227 .procname = "nr_open",
1228 .data = &sysctl_nr_open,
1229 .maxlen = sizeof(int),
1230 .mode = 0644,
1231 .proc_handler = &proc_dointvec_minmax,
1232 .extra1 = &sysctl_nr_open_min,
1233 .extra2 = &sysctl_nr_open_max,
1234 },
1235 {
1236 .ctl_name = FS_DENTRY,
1237 .procname = "dentry-state",
1238 .data = &dentry_stat,
1239 .maxlen = 6*sizeof(int),
1240 .mode = 0444,
1241 .proc_handler = &proc_dointvec,
1242 },
1243 {
1244 .ctl_name = FS_OVERFLOWUID,
1245 .procname = "overflowuid",
1246 .data = &fs_overflowuid,
1247 .maxlen = sizeof(int),
1248 .mode = 0644,
1249 .proc_handler = &proc_dointvec_minmax,
1250 .strategy = &sysctl_intvec,
1251 .extra1 = &minolduid,
1252 .extra2 = &maxolduid,
1253 },
1254 {
1255 .ctl_name = FS_OVERFLOWGID,
1256 .procname = "overflowgid",
1257 .data = &fs_overflowgid,
1258 .maxlen = sizeof(int),
1259 .mode = 0644,
1260 .proc_handler = &proc_dointvec_minmax,
1261 .strategy = &sysctl_intvec,
1262 .extra1 = &minolduid,
1263 .extra2 = &maxolduid,
1264 },
1265 {
1266 .ctl_name = FS_LEASES,
1267 .procname = "leases-enable",
1268 .data = &leases_enable,
1269 .maxlen = sizeof(int),
1270 .mode = 0644,
1271 .proc_handler = &proc_dointvec,
1272 },
1273#ifdef CONFIG_DNOTIFY
1274 {
1275 .ctl_name = FS_DIR_NOTIFY,
1276 .procname = "dir-notify-enable",
1277 .data = &dir_notify_enable,
1278 .maxlen = sizeof(int),
1279 .mode = 0644,
1280 .proc_handler = &proc_dointvec,
1281 },
1282#endif
1283#ifdef CONFIG_MMU
1284 {
1285 .ctl_name = FS_LEASE_TIME,
1286 .procname = "lease-break-time",
1287 .data = &lease_break_time,
1288 .maxlen = sizeof(int),
1289 .mode = 0644,
1290 .proc_handler = &proc_dointvec_minmax,
1291 .strategy = &sysctl_intvec,
1292 .extra1 = &zero,
1293 .extra2 = &two,
1294 },
1295 {
1296 .procname = "aio-nr",
1297 .data = &aio_nr,
1298 .maxlen = sizeof(aio_nr),
1299 .mode = 0444,
1300 .proc_handler = &proc_doulongvec_minmax,
1301 },
1302 {
1303 .procname = "aio-max-nr",
1304 .data = &aio_max_nr,
1305 .maxlen = sizeof(aio_max_nr),
1306 .mode = 0644,
1307 .proc_handler = &proc_doulongvec_minmax,
1308 },
1309#ifdef CONFIG_INOTIFY_USER
1310 {
1311 .ctl_name = FS_INOTIFY,
1312 .procname = "inotify",
1313 .mode = 0555,
1314 .child = inotify_table,
1315 },
1316#endif
1317#ifdef CONFIG_EPOLL
1318 {
1319 .procname = "epoll",
1320 .mode = 0555,
1321 .child = epoll_table,
1322 },
1323#endif
1324#endif
1325 {
1326 .ctl_name = KERN_SETUID_DUMPABLE,
1327 .procname = "suid_dumpable",
1328 .data = &suid_dumpable,
1329 .maxlen = sizeof(int),
1330 .mode = 0644,
1331 .proc_handler = &proc_dointvec,
1332 },
1333#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
1334 {
1335 .ctl_name = CTL_UNNUMBERED,
1336 .procname = "binfmt_misc",
1337 .mode = 0555,
1338 .child = binfmt_misc_table,
1339 },
1340#endif
1341
1342
1343
1344
1345 { .ctl_name = 0 }
1346};
1347
1348static struct ctl_table debug_table[] = {
1349#if defined(CONFIG_X86) || defined(CONFIG_PPC)
1350 {
1351 .ctl_name = CTL_UNNUMBERED,
1352 .procname = "exception-trace",
1353 .data = &show_unhandled_signals,
1354 .maxlen = sizeof(int),
1355 .mode = 0644,
1356 .proc_handler = proc_dointvec
1357 },
1358#endif
1359 { .ctl_name = 0 }
1360};
1361
1362static struct ctl_table dev_table[] = {
1363 { .ctl_name = 0 }
1364};
1365
1366static DEFINE_SPINLOCK(sysctl_lock);
1367
1368
1369static int use_table(struct ctl_table_header *p)
1370{
1371 if (unlikely(p->unregistering))
1372 return 0;
1373 p->used++;
1374 return 1;
1375}
1376
1377
1378static void unuse_table(struct ctl_table_header *p)
1379{
1380 if (!--p->used)
1381 if (unlikely(p->unregistering))
1382 complete(p->unregistering);
1383}
1384
1385
1386static void start_unregistering(struct ctl_table_header *p)
1387{
1388
1389
1390
1391
1392 if (unlikely(p->used)) {
1393 struct completion wait;
1394 init_completion(&wait);
1395 p->unregistering = &wait;
1396 spin_unlock(&sysctl_lock);
1397 wait_for_completion(&wait);
1398 spin_lock(&sysctl_lock);
1399 } else {
1400
1401 p->unregistering = ERR_PTR(-EINVAL);
1402 }
1403
1404
1405
1406
1407 list_del_init(&p->ctl_entry);
1408}
1409
1410void sysctl_head_get(struct ctl_table_header *head)
1411{
1412 spin_lock(&sysctl_lock);
1413 head->count++;
1414 spin_unlock(&sysctl_lock);
1415}
1416
1417void sysctl_head_put(struct ctl_table_header *head)
1418{
1419 spin_lock(&sysctl_lock);
1420 if (!--head->count)
1421 kfree(head);
1422 spin_unlock(&sysctl_lock);
1423}
1424
1425struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
1426{
1427 if (!head)
1428 BUG();
1429 spin_lock(&sysctl_lock);
1430 if (!use_table(head))
1431 head = ERR_PTR(-ENOENT);
1432 spin_unlock(&sysctl_lock);
1433 return head;
1434}
1435
1436void sysctl_head_finish(struct ctl_table_header *head)
1437{
1438 if (!head)
1439 return;
1440 spin_lock(&sysctl_lock);
1441 unuse_table(head);
1442 spin_unlock(&sysctl_lock);
1443}
1444
1445static struct ctl_table_set *
1446lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces)
1447{
1448 struct ctl_table_set *set = &root->default_set;
1449 if (root->lookup)
1450 set = root->lookup(root, namespaces);
1451 return set;
1452}
1453
1454static struct list_head *
1455lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
1456{
1457 struct ctl_table_set *set = lookup_header_set(root, namespaces);
1458 return &set->list;
1459}
1460
1461struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
1462 struct ctl_table_header *prev)
1463{
1464 struct ctl_table_root *root;
1465 struct list_head *header_list;
1466 struct ctl_table_header *head;
1467 struct list_head *tmp;
1468
1469 spin_lock(&sysctl_lock);
1470 if (prev) {
1471 head = prev;
1472 tmp = &prev->ctl_entry;
1473 unuse_table(prev);
1474 goto next;
1475 }
1476 tmp = &root_table_header.ctl_entry;
1477 for (;;) {
1478 head = list_entry(tmp, struct ctl_table_header, ctl_entry);
1479
1480 if (!use_table(head))
1481 goto next;
1482 spin_unlock(&sysctl_lock);
1483 return head;
1484 next:
1485 root = head->root;
1486 tmp = tmp->next;
1487 header_list = lookup_header_list(root, namespaces);
1488 if (tmp != header_list)
1489 continue;
1490
1491 do {
1492 root = list_entry(root->root_list.next,
1493 struct ctl_table_root, root_list);
1494 if (root == &sysctl_table_root)
1495 goto out;
1496 header_list = lookup_header_list(root, namespaces);
1497 } while (list_empty(header_list));
1498 tmp = header_list->next;
1499 }
1500out:
1501 spin_unlock(&sysctl_lock);
1502 return NULL;
1503}
1504
1505struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
1506{
1507 return __sysctl_head_next(current->nsproxy, prev);
1508}
1509
1510void register_sysctl_root(struct ctl_table_root *root)
1511{
1512 spin_lock(&sysctl_lock);
1513 list_add_tail(&root->root_list, &sysctl_table_root.root_list);
1514 spin_unlock(&sysctl_lock);
1515}
1516
1517#ifdef CONFIG_SYSCTL_SYSCALL
1518
1519static int do_sysctl_strategy(struct ctl_table_root *root,
1520 struct ctl_table *table,
1521 int __user *name, int nlen,
1522 void __user *oldval, size_t __user *oldlenp,
1523 void __user *newval, size_t newlen)
1524{
1525 int op = 0, rc;
1526
1527 if (oldval)
1528 op |= MAY_READ;
1529 if (newval)
1530 op |= MAY_WRITE;
1531 if (sysctl_perm(root, table, op))
1532 return -EPERM;
1533
1534 if (table->strategy) {
1535 rc = table->strategy(table, name, nlen, oldval, oldlenp,
1536 newval, newlen);
1537 if (rc < 0)
1538 return rc;
1539 if (rc > 0)
1540 return 0;
1541 }
1542
1543
1544
1545 if (table->data && table->maxlen) {
1546 rc = sysctl_data(table, name, nlen, oldval, oldlenp,
1547 newval, newlen);
1548 if (rc < 0)
1549 return rc;
1550 }
1551 return 0;
1552}
1553
1554static int parse_table(int __user *name, int nlen,
1555 void __user *oldval, size_t __user *oldlenp,
1556 void __user *newval, size_t newlen,
1557 struct ctl_table_root *root,
1558 struct ctl_table *table)
1559{
1560 int n;
1561repeat:
1562 if (!nlen)
1563 return -ENOTDIR;
1564 if (get_user(n, name))
1565 return -EFAULT;
1566 for ( ; table->ctl_name || table->procname; table++) {
1567 if (!table->ctl_name)
1568 continue;
1569 if (n == table->ctl_name) {
1570 int error;
1571 if (table->child) {
1572 if (sysctl_perm(root, table, MAY_EXEC))
1573 return -EPERM;
1574 name++;
1575 nlen--;
1576 table = table->child;
1577 goto repeat;
1578 }
1579 error = do_sysctl_strategy(root, table, name, nlen,
1580 oldval, oldlenp,
1581 newval, newlen);
1582 return error;
1583 }
1584 }
1585 return -ENOTDIR;
1586}
1587
1588int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp,
1589 void __user *newval, size_t newlen)
1590{
1591 struct ctl_table_header *head;
1592 int error = -ENOTDIR;
1593
1594 if (nlen <= 0 || nlen >= CTL_MAXNAME)
1595 return -ENOTDIR;
1596 if (oldval) {
1597 int old_len;
1598 if (!oldlenp || get_user(old_len, oldlenp))
1599 return -EFAULT;
1600 }
1601
1602 for (head = sysctl_head_next(NULL); head;
1603 head = sysctl_head_next(head)) {
1604 error = parse_table(name, nlen, oldval, oldlenp,
1605 newval, newlen,
1606 head->root, head->ctl_table);
1607 if (error != -ENOTDIR) {
1608 sysctl_head_finish(head);
1609 break;
1610 }
1611 }
1612 return error;
1613}
1614
1615SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args)
1616{
1617 struct __sysctl_args tmp;
1618 int error;
1619
1620 if (copy_from_user(&tmp, args, sizeof(tmp)))
1621 return -EFAULT;
1622
1623 error = deprecated_sysctl_warning(&tmp);
1624 if (error)
1625 goto out;
1626
1627 lock_kernel();
1628 error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
1629 tmp.newval, tmp.newlen);
1630 unlock_kernel();
1631out:
1632 return error;
1633}
1634#endif
1635
1636
1637
1638
1639
1640
1641static int test_perm(int mode, int op)
1642{
1643 if (!current->euid)
1644 mode >>= 6;
1645 else if (in_egroup_p(0))
1646 mode >>= 3;
1647 if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
1648 return 0;
1649 return -EACCES;
1650}
1651
1652int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
1653{
1654 int error;
1655 int mode;
1656
1657 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
1658 if (error)
1659 return error;
1660
1661 if (root->permissions)
1662 mode = root->permissions(root, current->nsproxy, table);
1663 else
1664 mode = table->mode;
1665
1666 return test_perm(mode, op);
1667}
1668
1669static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
1670{
1671 for (; table->ctl_name || table->procname; table++) {
1672 table->parent = parent;
1673 if (table->child)
1674 sysctl_set_parent(table, table->child);
1675 }
1676}
1677
1678static __init int sysctl_init(void)
1679{
1680 sysctl_set_parent(NULL, root_table);
1681#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
1682 {
1683 int err;
1684 err = sysctl_check_table(current->nsproxy, root_table);
1685 }
1686#endif
1687 return 0;
1688}
1689
1690core_initcall(sysctl_init);
1691
1692static struct ctl_table *is_branch_in(struct ctl_table *branch,
1693 struct ctl_table *table)
1694{
1695 struct ctl_table *p;
1696 const char *s = branch->procname;
1697
1698
1699 if (!s || !branch->child)
1700 return NULL;
1701
1702
1703 if (branch[1].procname || branch[1].ctl_name)
1704 return NULL;
1705
1706
1707 for (p = table; p->procname || p->ctl_name; p++) {
1708 if (!p->child)
1709 continue;
1710 if (p->procname && strcmp(p->procname, s) == 0)
1711 return p;
1712 }
1713 return NULL;
1714}
1715
1716
1717static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)
1718{
1719 struct ctl_table *to = p->ctl_table, *by = q->ctl_table;
1720 struct ctl_table *next;
1721 int is_better = 0;
1722 int not_in_parent = !p->attached_by;
1723
1724 while ((next = is_branch_in(by, to)) != NULL) {
1725 if (by == q->attached_by)
1726 is_better = 1;
1727 if (to == p->attached_by)
1728 not_in_parent = 1;
1729 by = by->child;
1730 to = next->child;
1731 }
1732
1733 if (is_better && not_in_parent) {
1734 q->attached_by = by;
1735 q->attached_to = to;
1736 q->parent = p;
1737 }
1738}
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811struct ctl_table_header *__register_sysctl_paths(
1812 struct ctl_table_root *root,
1813 struct nsproxy *namespaces,
1814 const struct ctl_path *path, struct ctl_table *table)
1815{
1816 struct ctl_table_header *header;
1817 struct ctl_table *new, **prevp;
1818 unsigned int n, npath;
1819 struct ctl_table_set *set;
1820
1821
1822 for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath)
1823 ;
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833 header = kzalloc(sizeof(struct ctl_table_header) +
1834 (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
1835 if (!header)
1836 return NULL;
1837
1838 new = (struct ctl_table *) (header + 1);
1839
1840
1841 prevp = &header->ctl_table;
1842 for (n = 0; n < npath; ++n, ++path) {
1843
1844 new->procname = path->procname;
1845 new->ctl_name = path->ctl_name;
1846 new->mode = 0555;
1847
1848 *prevp = new;
1849 prevp = &new->child;
1850
1851 new += 2;
1852 }
1853 *prevp = table;
1854 header->ctl_table_arg = table;
1855
1856 INIT_LIST_HEAD(&header->ctl_entry);
1857 header->used = 0;
1858 header->unregistering = NULL;
1859 header->root = root;
1860 sysctl_set_parent(NULL, header->ctl_table);
1861 header->count = 1;
1862#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
1863 if (sysctl_check_table(namespaces, header->ctl_table)) {
1864 kfree(header);
1865 return NULL;
1866 }
1867#endif
1868 spin_lock(&sysctl_lock);
1869 header->set = lookup_header_set(root, namespaces);
1870 header->attached_by = header->ctl_table;
1871 header->attached_to = root_table;
1872 header->parent = &root_table_header;
1873 for (set = header->set; set; set = set->parent) {
1874 struct ctl_table_header *p;
1875 list_for_each_entry(p, &set->list, ctl_entry) {
1876 if (p->unregistering)
1877 continue;
1878 try_attach(p, header);
1879 }
1880 }
1881 header->parent->count++;
1882 list_add_tail(&header->ctl_entry, &header->set->list);
1883 spin_unlock(&sysctl_lock);
1884
1885 return header;
1886}
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
1899 struct ctl_table *table)
1900{
1901 return __register_sysctl_paths(&sysctl_table_root, current->nsproxy,
1902 path, table);
1903}
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
1915{
1916 static const struct ctl_path null_path[] = { {} };
1917
1918 return register_sysctl_paths(null_path, table);
1919}
1920
1921
1922
1923
1924
1925
1926
1927
1928void unregister_sysctl_table(struct ctl_table_header * header)
1929{
1930 might_sleep();
1931
1932 if (header == NULL)
1933 return;
1934
1935 spin_lock(&sysctl_lock);
1936 start_unregistering(header);
1937 if (!--header->parent->count) {
1938 WARN_ON(1);
1939 kfree(header->parent);
1940 }
1941 if (!--header->count)
1942 kfree(header);
1943 spin_unlock(&sysctl_lock);
1944}
1945
1946int sysctl_is_seen(struct ctl_table_header *p)
1947{
1948 struct ctl_table_set *set = p->set;
1949 int res;
1950 spin_lock(&sysctl_lock);
1951 if (p->unregistering)
1952 res = 0;
1953 else if (!set->is_seen)
1954 res = 1;
1955 else
1956 res = set->is_seen(set);
1957 spin_unlock(&sysctl_lock);
1958 return res;
1959}
1960
1961void setup_sysctl_set(struct ctl_table_set *p,
1962 struct ctl_table_set *parent,
1963 int (*is_seen)(struct ctl_table_set *))
1964{
1965 INIT_LIST_HEAD(&p->list);
1966 p->parent = parent ? parent : &sysctl_table_root.default_set;
1967 p->is_seen = is_seen;
1968}
1969
1970#else
1971struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
1972{
1973 return NULL;
1974}
1975
1976struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
1977 struct ctl_table *table)
1978{
1979 return NULL;
1980}
1981
1982void unregister_sysctl_table(struct ctl_table_header * table)
1983{
1984}
1985
1986void setup_sysctl_set(struct ctl_table_set *p,
1987 struct ctl_table_set *parent,
1988 int (*is_seen)(struct ctl_table_set *))
1989{
1990}
1991
1992void sysctl_head_put(struct ctl_table_header *head)
1993{
1994}
1995
1996#endif
1997
1998
1999
2000
2001
2002#ifdef CONFIG_PROC_SYSCTL
2003
2004static int _proc_do_string(void* data, int maxlen, int write,
2005 struct file *filp, void __user *buffer,
2006 size_t *lenp, loff_t *ppos)
2007{
2008 size_t len;
2009 char __user *p;
2010 char c;
2011
2012 if (!data || !maxlen || !*lenp) {
2013 *lenp = 0;
2014 return 0;
2015 }
2016
2017 if (write) {
2018 len = 0;
2019 p = buffer;
2020 while (len < *lenp) {
2021 if (get_user(c, p++))
2022 return -EFAULT;
2023 if (c == 0 || c == '\n')
2024 break;
2025 len++;
2026 }
2027 if (len >= maxlen)
2028 len = maxlen-1;
2029 if(copy_from_user(data, buffer, len))
2030 return -EFAULT;
2031 ((char *) data)[len] = 0;
2032 *ppos += *lenp;
2033 } else {
2034 len = strlen(data);
2035 if (len > maxlen)
2036 len = maxlen;
2037
2038 if (*ppos > len) {
2039 *lenp = 0;
2040 return 0;
2041 }
2042
2043 data += *ppos;
2044 len -= *ppos;
2045
2046 if (len > *lenp)
2047 len = *lenp;
2048 if (len)
2049 if(copy_to_user(buffer, data, len))
2050 return -EFAULT;
2051 if (len < *lenp) {
2052 if(put_user('\n', ((char __user *) buffer) + len))
2053 return -EFAULT;
2054 len++;
2055 }
2056 *lenp = len;
2057 *ppos += len;
2058 }
2059 return 0;
2060}
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080int proc_dostring(struct ctl_table *table, int write, struct file *filp,
2081 void __user *buffer, size_t *lenp, loff_t *ppos)
2082{
2083 return _proc_do_string(table->data, table->maxlen, write, filp,
2084 buffer, lenp, ppos);
2085}
2086
2087
2088static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
2089 int *valp,
2090 int write, void *data)
2091{
2092 if (write) {
2093 *valp = *negp ? -*lvalp : *lvalp;
2094 } else {
2095 int val = *valp;
2096 if (val < 0) {
2097 *negp = -1;
2098 *lvalp = (unsigned long)-val;
2099 } else {
2100 *negp = 0;
2101 *lvalp = (unsigned long)val;
2102 }
2103 }
2104 return 0;
2105}
2106
2107static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
2108 int write, struct file *filp, void __user *buffer,
2109 size_t *lenp, loff_t *ppos,
2110 int (*conv)(int *negp, unsigned long *lvalp, int *valp,
2111 int write, void *data),
2112 void *data)
2113{
2114#define TMPBUFLEN 21
2115 int *i, vleft, first=1, neg, val;
2116 unsigned long lval;
2117 size_t left, len;
2118
2119 char buf[TMPBUFLEN], *p;
2120 char __user *s = buffer;
2121
2122 if (!tbl_data || !table->maxlen || !*lenp ||
2123 (*ppos && !write)) {
2124 *lenp = 0;
2125 return 0;
2126 }
2127
2128 i = (int *) tbl_data;
2129 vleft = table->maxlen / sizeof(*i);
2130 left = *lenp;
2131
2132 if (!conv)
2133 conv = do_proc_dointvec_conv;
2134
2135 for (; left && vleft--; i++, first=0) {
2136 if (write) {
2137 while (left) {
2138 char c;
2139 if (get_user(c, s))
2140 return -EFAULT;
2141 if (!isspace(c))
2142 break;
2143 left--;
2144 s++;
2145 }
2146 if (!left)
2147 break;
2148 neg = 0;
2149 len = left;
2150 if (len > sizeof(buf) - 1)
2151 len = sizeof(buf) - 1;
2152 if (copy_from_user(buf, s, len))
2153 return -EFAULT;
2154 buf[len] = 0;
2155 p = buf;
2156 if (*p == '-' && left > 1) {
2157 neg = 1;
2158 p++;
2159 }
2160 if (*p < '0' || *p > '9')
2161 break;
2162
2163 lval = simple_strtoul(p, &p, 0);
2164
2165 len = p-buf;
2166 if ((len < left) && *p && !isspace(*p))
2167 break;
2168 if (neg)
2169 val = -val;
2170 s += len;
2171 left -= len;
2172
2173 if (conv(&neg, &lval, i, 1, data))
2174 break;
2175 } else {
2176 p = buf;
2177 if (!first)
2178 *p++ = '\t';
2179
2180 if (conv(&neg, &lval, i, 0, data))
2181 break;
2182
2183 sprintf(p, "%s%lu", neg ? "-" : "", lval);
2184 len = strlen(buf);
2185 if (len > left)
2186 len = left;
2187 if(copy_to_user(s, buf, len))
2188 return -EFAULT;
2189 left -= len;
2190 s += len;
2191 }
2192 }
2193
2194 if (!write && !first && left) {
2195 if(put_user('\n', s))
2196 return -EFAULT;
2197 left--, s++;
2198 }
2199 if (write) {
2200 while (left) {
2201 char c;
2202 if (get_user(c, s++))
2203 return -EFAULT;
2204 if (!isspace(c))
2205 break;
2206 left--;
2207 }
2208 }
2209 if (write && first)
2210 return -EINVAL;
2211 *lenp -= left;
2212 *ppos += *lenp;
2213 return 0;
2214#undef TMPBUFLEN
2215}
2216
2217static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp,
2218 void __user *buffer, size_t *lenp, loff_t *ppos,
2219 int (*conv)(int *negp, unsigned long *lvalp, int *valp,
2220 int write, void *data),
2221 void *data)
2222{
2223 return __do_proc_dointvec(table->data, table, write, filp,
2224 buffer, lenp, ppos, conv, data);
2225}
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
2242 void __user *buffer, size_t *lenp, loff_t *ppos)
2243{
2244 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
2245 NULL,NULL);
2246}
2247
2248#define OP_SET 0
2249#define OP_AND 1
2250#define OP_OR 2
2251
2252static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
2253 int *valp,
2254 int write, void *data)
2255{
2256 int op = *(int *)data;
2257 if (write) {
2258 int val = *negp ? -*lvalp : *lvalp;
2259 switch(op) {
2260 case OP_SET: *valp = val; break;
2261 case OP_AND: *valp &= val; break;
2262 case OP_OR: *valp |= val; break;
2263 }
2264 } else {
2265 int val = *valp;
2266 if (val < 0) {
2267 *negp = -1;
2268 *lvalp = (unsigned long)-val;
2269 } else {
2270 *negp = 0;
2271 *lvalp = (unsigned long)val;
2272 }
2273 }
2274 return 0;
2275}
2276
2277
2278
2279
2280static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
2281 void __user *buffer, size_t *lenp, loff_t *ppos)
2282{
2283 int op;
2284
2285 if (write && !capable(CAP_SYS_ADMIN))
2286 return -EPERM;
2287
2288 op = OP_OR;
2289 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
2290 do_proc_dointvec_bset_conv,&op);
2291}
2292
2293struct do_proc_dointvec_minmax_conv_param {
2294 int *min;
2295 int *max;
2296};
2297
2298static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,
2299 int *valp,
2300 int write, void *data)
2301{
2302 struct do_proc_dointvec_minmax_conv_param *param = data;
2303 if (write) {
2304 int val = *negp ? -*lvalp : *lvalp;
2305 if ((param->min && *param->min > val) ||
2306 (param->max && *param->max < val))
2307 return -EINVAL;
2308 *valp = val;
2309 } else {
2310 int val = *valp;
2311 if (val < 0) {
2312 *negp = -1;
2313 *lvalp = (unsigned long)-val;
2314 } else {
2315 *negp = 0;
2316 *lvalp = (unsigned long)val;
2317 }
2318 }
2319 return 0;
2320}
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
2340 void __user *buffer, size_t *lenp, loff_t *ppos)
2341{
2342 struct do_proc_dointvec_minmax_conv_param param = {
2343 .min = (int *) table->extra1,
2344 .max = (int *) table->extra2,
2345 };
2346 return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
2347 do_proc_dointvec_minmax_conv, ¶m);
2348}
2349
2350static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
2351 struct file *filp,
2352 void __user *buffer,
2353 size_t *lenp, loff_t *ppos,
2354 unsigned long convmul,
2355 unsigned long convdiv)
2356{
2357#define TMPBUFLEN 21
2358 unsigned long *i, *min, *max, val;
2359 int vleft, first=1, neg;
2360 size_t len, left;
2361 char buf[TMPBUFLEN], *p;
2362 char __user *s = buffer;
2363
2364 if (!data || !table->maxlen || !*lenp ||
2365 (*ppos && !write)) {
2366 *lenp = 0;
2367 return 0;
2368 }
2369
2370 i = (unsigned long *) data;
2371 min = (unsigned long *) table->extra1;
2372 max = (unsigned long *) table->extra2;
2373 vleft = table->maxlen / sizeof(unsigned long);
2374 left = *lenp;
2375
2376 for (; left && vleft--; i++, min++, max++, first=0) {
2377 if (write) {
2378 while (left) {
2379 char c;
2380 if (get_user(c, s))
2381 return -EFAULT;
2382 if (!isspace(c))
2383 break;
2384 left--;
2385 s++;
2386 }
2387 if (!left)
2388 break;
2389 neg = 0;
2390 len = left;
2391 if (len > TMPBUFLEN-1)
2392 len = TMPBUFLEN-1;
2393 if (copy_from_user(buf, s, len))
2394 return -EFAULT;
2395 buf[len] = 0;
2396 p = buf;
2397 if (*p == '-' && left > 1) {
2398 neg = 1;
2399 p++;
2400 }
2401 if (*p < '0' || *p > '9')
2402 break;
2403 val = simple_strtoul(p, &p, 0) * convmul / convdiv ;
2404 len = p-buf;
2405 if ((len < left) && *p && !isspace(*p))
2406 break;
2407 if (neg)
2408 val = -val;
2409 s += len;
2410 left -= len;
2411
2412 if(neg)
2413 continue;
2414 if ((min && val < *min) || (max && val > *max))
2415 continue;
2416 *i = val;
2417 } else {
2418 p = buf;
2419 if (!first)
2420 *p++ = '\t';
2421 sprintf(p, "%lu", convdiv * (*i) / convmul);
2422 len = strlen(buf);
2423 if (len > left)
2424 len = left;
2425 if(copy_to_user(s, buf, len))
2426 return -EFAULT;
2427 left -= len;
2428 s += len;
2429 }
2430 }
2431
2432 if (!write && !first && left) {
2433 if(put_user('\n', s))
2434 return -EFAULT;
2435 left--, s++;
2436 }
2437 if (write) {
2438 while (left) {
2439 char c;
2440 if (get_user(c, s++))
2441 return -EFAULT;
2442 if (!isspace(c))
2443 break;
2444 left--;
2445 }
2446 }
2447 if (write && first)
2448 return -EINVAL;
2449 *lenp -= left;
2450 *ppos += *lenp;
2451 return 0;
2452#undef TMPBUFLEN
2453}
2454
2455static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
2456 struct file *filp,
2457 void __user *buffer,
2458 size_t *lenp, loff_t *ppos,
2459 unsigned long convmul,
2460 unsigned long convdiv)
2461{
2462 return __do_proc_doulongvec_minmax(table->data, table, write,
2463 filp, buffer, lenp, ppos, convmul, convdiv);
2464}
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
2484 void __user *buffer, size_t *lenp, loff_t *ppos)
2485{
2486 return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l);
2487}
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
2508 struct file *filp,
2509 void __user *buffer,
2510 size_t *lenp, loff_t *ppos)
2511{
2512 return do_proc_doulongvec_minmax(table, write, filp, buffer,
2513 lenp, ppos, HZ, 1000l);
2514}
2515
2516
2517static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp,
2518 int *valp,
2519 int write, void *data)
2520{
2521 if (write) {
2522 if (*lvalp > LONG_MAX / HZ)
2523 return 1;
2524 *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ);
2525 } else {
2526 int val = *valp;
2527 unsigned long lval;
2528 if (val < 0) {
2529 *negp = -1;
2530 lval = (unsigned long)-val;
2531 } else {
2532 *negp = 0;
2533 lval = (unsigned long)val;
2534 }
2535 *lvalp = lval / HZ;
2536 }
2537 return 0;
2538}
2539
2540static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp,
2541 int *valp,
2542 int write, void *data)
2543{
2544 if (write) {
2545 if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ)
2546 return 1;
2547 *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp);
2548 } else {
2549 int val = *valp;
2550 unsigned long lval;
2551 if (val < 0) {
2552 *negp = -1;
2553 lval = (unsigned long)-val;
2554 } else {
2555 *negp = 0;
2556 lval = (unsigned long)val;
2557 }
2558 *lvalp = jiffies_to_clock_t(lval);
2559 }
2560 return 0;
2561}
2562
2563static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,
2564 int *valp,
2565 int write, void *data)
2566{
2567 if (write) {
2568 *valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp);
2569 } else {
2570 int val = *valp;
2571 unsigned long lval;
2572 if (val < 0) {
2573 *negp = -1;
2574 lval = (unsigned long)-val;
2575 } else {
2576 *negp = 0;
2577 lval = (unsigned long)val;
2578 }
2579 *lvalp = jiffies_to_msecs(lval);
2580 }
2581 return 0;
2582}
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
2601 void __user *buffer, size_t *lenp, loff_t *ppos)
2602{
2603 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
2604 do_proc_dointvec_jiffies_conv,NULL);
2605}
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
2624 void __user *buffer, size_t *lenp, loff_t *ppos)
2625{
2626 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
2627 do_proc_dointvec_userhz_jiffies_conv,NULL);
2628}
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
2648 void __user *buffer, size_t *lenp, loff_t *ppos)
2649{
2650 return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
2651 do_proc_dointvec_ms_jiffies_conv, NULL);
2652}
2653
2654static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
2655 void __user *buffer, size_t *lenp, loff_t *ppos)
2656{
2657 struct pid *new_pid;
2658 pid_t tmp;
2659 int r;
2660
2661 tmp = pid_vnr(cad_pid);
2662
2663 r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
2664 lenp, ppos, NULL, NULL);
2665 if (r || !write)
2666 return r;
2667
2668 new_pid = find_get_pid(tmp);
2669 if (!new_pid)
2670 return -ESRCH;
2671
2672 put_pid(xchg(&cad_pid, new_pid));
2673 return 0;
2674}
2675
2676#else
2677
2678int proc_dostring(struct ctl_table *table, int write, struct file *filp,
2679 void __user *buffer, size_t *lenp, loff_t *ppos)
2680{
2681 return -ENOSYS;
2682}
2683
2684int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
2685 void __user *buffer, size_t *lenp, loff_t *ppos)
2686{
2687 return -ENOSYS;
2688}
2689
2690int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
2691 void __user *buffer, size_t *lenp, loff_t *ppos)
2692{
2693 return -ENOSYS;
2694}
2695
2696int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
2697 void __user *buffer, size_t *lenp, loff_t *ppos)
2698{
2699 return -ENOSYS;
2700}
2701
2702int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
2703 void __user *buffer, size_t *lenp, loff_t *ppos)
2704{
2705 return -ENOSYS;
2706}
2707
2708int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
2709 void __user *buffer, size_t *lenp, loff_t *ppos)
2710{
2711 return -ENOSYS;
2712}
2713
2714int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
2715 void __user *buffer, size_t *lenp, loff_t *ppos)
2716{
2717 return -ENOSYS;
2718}
2719
2720int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
2721 struct file *filp,
2722 void __user *buffer,
2723 size_t *lenp, loff_t *ppos)
2724{
2725 return -ENOSYS;
2726}
2727
2728
2729#endif
2730
2731
2732#ifdef CONFIG_SYSCTL_SYSCALL
2733
2734
2735
2736
2737
2738int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
2739 void __user *oldval, size_t __user *oldlenp,
2740 void __user *newval, size_t newlen)
2741{
2742 size_t len;
2743
2744
2745 if (!table->data || !table->maxlen)
2746 return -ENOTDIR;
2747
2748 if (oldval && oldlenp) {
2749 if (get_user(len, oldlenp))
2750 return -EFAULT;
2751 if (len) {
2752 if (len > table->maxlen)
2753 len = table->maxlen;
2754 if (copy_to_user(oldval, table->data, len))
2755 return -EFAULT;
2756 if (put_user(len, oldlenp))
2757 return -EFAULT;
2758 }
2759 }
2760
2761 if (newval && newlen) {
2762 if (newlen > table->maxlen)
2763 newlen = table->maxlen;
2764
2765 if (copy_from_user(table->data, newval, newlen))
2766 return -EFAULT;
2767 }
2768 return 1;
2769}
2770
2771
2772int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
2773 void __user *oldval, size_t __user *oldlenp,
2774 void __user *newval, size_t newlen)
2775{
2776 if (!table->data || !table->maxlen)
2777 return -ENOTDIR;
2778
2779 if (oldval && oldlenp) {
2780 size_t bufsize;
2781 if (get_user(bufsize, oldlenp))
2782 return -EFAULT;
2783 if (bufsize) {
2784 size_t len = strlen(table->data), copied;
2785
2786
2787 if (len > table->maxlen)
2788 len = table->maxlen;
2789
2790
2791 copied = (len >= bufsize) ? bufsize - 1 : len;
2792
2793 if (copy_to_user(oldval, table->data, copied) ||
2794 put_user(0, (char __user *)(oldval + copied)))
2795 return -EFAULT;
2796 if (put_user(len, oldlenp))
2797 return -EFAULT;
2798 }
2799 }
2800 if (newval && newlen) {
2801 size_t len = newlen;
2802 if (len > table->maxlen)
2803 len = table->maxlen;
2804 if(copy_from_user(table->data, newval, len))
2805 return -EFAULT;
2806 if (len == table->maxlen)
2807 len--;
2808 ((char *) table->data)[len] = 0;
2809 }
2810 return 1;
2811}
2812
2813
2814
2815
2816
2817
2818int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
2819 void __user *oldval, size_t __user *oldlenp,
2820 void __user *newval, size_t newlen)
2821{
2822
2823 if (newval && newlen) {
2824 int __user *vec = (int __user *) newval;
2825 int *min = (int *) table->extra1;
2826 int *max = (int *) table->extra2;
2827 size_t length;
2828 int i;
2829
2830 if (newlen % sizeof(int) != 0)
2831 return -EINVAL;
2832
2833 if (!table->extra1 && !table->extra2)
2834 return 0;
2835
2836 if (newlen > table->maxlen)
2837 newlen = table->maxlen;
2838 length = newlen / sizeof(int);
2839
2840 for (i = 0; i < length; i++) {
2841 int value;
2842 if (get_user(value, vec + i))
2843 return -EFAULT;
2844 if (min && value < min[i])
2845 return -EINVAL;
2846 if (max && value > max[i])
2847 return -EINVAL;
2848 }
2849 }
2850 return 0;
2851}
2852
2853
2854int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
2855 void __user *oldval, size_t __user *oldlenp,
2856 void __user *newval, size_t newlen)
2857{
2858 if (oldval && oldlenp) {
2859 size_t olen;
2860
2861 if (get_user(olen, oldlenp))
2862 return -EFAULT;
2863 if (olen) {
2864 int val;
2865
2866 if (olen < sizeof(int))
2867 return -EINVAL;
2868
2869 val = *(int *)(table->data) / HZ;
2870 if (put_user(val, (int __user *)oldval))
2871 return -EFAULT;
2872 if (put_user(sizeof(int), oldlenp))
2873 return -EFAULT;
2874 }
2875 }
2876 if (newval && newlen) {
2877 int new;
2878 if (newlen != sizeof(int))
2879 return -EINVAL;
2880 if (get_user(new, (int __user *)newval))
2881 return -EFAULT;
2882 *(int *)(table->data) = new*HZ;
2883 }
2884 return 1;
2885}
2886
2887
2888int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
2889 void __user *oldval, size_t __user *oldlenp,
2890 void __user *newval, size_t newlen)
2891{
2892 if (oldval && oldlenp) {
2893 size_t olen;
2894
2895 if (get_user(olen, oldlenp))
2896 return -EFAULT;
2897 if (olen) {
2898 int val;
2899
2900 if (olen < sizeof(int))
2901 return -EINVAL;
2902
2903 val = jiffies_to_msecs(*(int *)(table->data));
2904 if (put_user(val, (int __user *)oldval))
2905 return -EFAULT;
2906 if (put_user(sizeof(int), oldlenp))
2907 return -EFAULT;
2908 }
2909 }
2910 if (newval && newlen) {
2911 int new;
2912 if (newlen != sizeof(int))
2913 return -EINVAL;
2914 if (get_user(new, (int __user *)newval))
2915 return -EFAULT;
2916 *(int *)(table->data) = msecs_to_jiffies(new);
2917 }
2918 return 1;
2919}
2920
2921
2922
2923#else
2924
2925
2926SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args)
2927{
2928 struct __sysctl_args tmp;
2929 int error;
2930
2931 if (copy_from_user(&tmp, args, sizeof(tmp)))
2932 return -EFAULT;
2933
2934 error = deprecated_sysctl_warning(&tmp);
2935
2936
2937 if (!error)
2938 error = -ENOSYS;
2939
2940 return error;
2941}
2942
2943int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
2944 void __user *oldval, size_t __user *oldlenp,
2945 void __user *newval, size_t newlen)
2946{
2947 return -ENOSYS;
2948}
2949
2950int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
2951 void __user *oldval, size_t __user *oldlenp,
2952 void __user *newval, size_t newlen)
2953{
2954 return -ENOSYS;
2955}
2956
2957int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
2958 void __user *oldval, size_t __user *oldlenp,
2959 void __user *newval, size_t newlen)
2960{
2961 return -ENOSYS;
2962}
2963
2964int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
2965 void __user *oldval, size_t __user *oldlenp,
2966 void __user *newval, size_t newlen)
2967{
2968 return -ENOSYS;
2969}
2970
2971int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
2972 void __user *oldval, size_t __user *oldlenp,
2973 void __user *newval, size_t newlen)
2974{
2975 return -ENOSYS;
2976}
2977
2978#endif
2979
2980static int deprecated_sysctl_warning(struct __sysctl_args *args)
2981{
2982 static int msg_count;
2983 int name[CTL_MAXNAME];
2984 int i;
2985
2986
2987 if (args->nlen < 0 || args->nlen > CTL_MAXNAME)
2988 return -ENOTDIR;
2989
2990
2991 for (i = 0; i < args->nlen; i++)
2992 if (get_user(name[i], args->name + i))
2993 return -EFAULT;
2994
2995
2996 if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
2997 return 0;
2998
2999 if (msg_count < 5) {
3000 msg_count++;
3001 printk(KERN_INFO
3002 "warning: process `%s' used the deprecated sysctl "
3003 "system call with ", current->comm);
3004 for (i = 0; i < args->nlen; i++)
3005 printk("%d.", name[i]);
3006 printk("\n");
3007 }
3008 return 0;
3009}
3010
3011
3012
3013
3014
3015EXPORT_SYMBOL(proc_dointvec);
3016EXPORT_SYMBOL(proc_dointvec_jiffies);
3017EXPORT_SYMBOL(proc_dointvec_minmax);
3018EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
3019EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
3020EXPORT_SYMBOL(proc_dostring);
3021EXPORT_SYMBOL(proc_doulongvec_minmax);
3022EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
3023EXPORT_SYMBOL(register_sysctl_table);
3024EXPORT_SYMBOL(register_sysctl_paths);
3025EXPORT_SYMBOL(sysctl_intvec);
3026EXPORT_SYMBOL(sysctl_jiffies);
3027EXPORT_SYMBOL(sysctl_ms_jiffies);
3028EXPORT_SYMBOL(sysctl_string);
3029EXPORT_SYMBOL(sysctl_data);
3030EXPORT_SYMBOL(unregister_sysctl_table);
3031