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