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