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