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