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