blob: 6c37048b9db9954bb7498ddfaa258a5b3af30e5f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#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>
Andrew Morgan72c2d582007-10-18 03:05:59 -070027#include <linux/security.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/ctype.h>
29#include <linux/utsname.h>
Vegard Nossumdfec0722008-04-04 00:51:41 +020030#include <linux/kmemcheck.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/smp_lock.h>
Adrian Bunk62239ac2007-07-17 04:03:45 -070032#include <linux/fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/init.h>
34#include <linux/kernel.h>
Kay Sievers0296b222005-11-11 05:33:52 +010035#include <linux/kobject.h>
Arnaldo Carvalho de Melo20380732005-08-16 02:18:02 -030036#include <linux/net.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <linux/sysrq.h>
38#include <linux/highuid.h>
39#include <linux/writeback.h>
Ingo Molnar3fff4c42009-09-22 16:18:09 +020040#include <linux/ratelimit.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/hugetlb.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <linux/initrd.h>
David Howells0b77f5b2008-04-29 01:01:32 -070043#include <linux/key.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <linux/times.h>
45#include <linux/limits.h>
46#include <linux/dcache.h>
47#include <linux/syscalls.h>
Adrian Bunkc748e132008-07-23 21:27:03 -070048#include <linux/vmstat.h>
Pavel Machekc255d842006-02-20 18:27:58 -080049#include <linux/nfs_fs.h>
50#include <linux/acpi.h>
Jeremy Fitzhardinge10a0a8d2007-07-17 18:37:02 -070051#include <linux/reboot.h>
Steven Rostedtb0fc4942008-05-12 21:20:43 +020052#include <linux/ftrace.h>
David Howells12e22c52009-04-03 16:42:35 +010053#include <linux/slow-work.h>
Peter Zijlstra1ccd1542009-04-09 10:53:45 +020054#include <linux/perf_counter.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
56#include <asm/uaccess.h>
57#include <asm/processor.h>
58
Andi Kleen29cbc782006-09-30 01:47:55 +020059#ifdef CONFIG_X86
60#include <asm/nmi.h>
Chuck Ebbert0741f4d2006-12-07 02:14:11 +010061#include <asm/stacktrace.h>
Ingo Molnar6e7c4022008-01-30 13:30:05 +010062#include <asm/io.h>
Andi Kleen29cbc782006-09-30 01:47:55 +020063#endif
64
Eric W. Biederman7058cb02007-10-18 03:05:58 -070065static int deprecated_sysctl_warning(struct __sysctl_args *args);
66
Linus Torvalds1da177e2005-04-16 15:20:36 -070067#if defined(CONFIG_SYSCTL)
68
69/* External variables not in a header file. */
70extern int C_A_D;
Ingo Molnar45807a12007-07-15 23:40:10 -070071extern int print_fatal_signals;
Linus Torvalds1da177e2005-04-16 15:20:36 -070072extern int sysctl_overcommit_memory;
73extern int sysctl_overcommit_ratio;
KAMEZAWA Hiroyukifadd8fb2006-06-23 02:03:13 -070074extern int sysctl_panic_on_oom;
David Rientjesfe071d72007-10-16 23:25:56 -070075extern int sysctl_oom_kill_allocating_task;
David Rientjesfef1bdd2008-02-07 00:14:07 -080076extern int sysctl_oom_dump_tasks;
Linus Torvalds1da177e2005-04-16 15:20:36 -070077extern int max_threads;
Linus Torvalds1da177e2005-04-16 15:20:36 -070078extern int core_uses_pid;
Alan Coxd6e71142005-06-23 00:09:43 -070079extern int suid_dumpable;
Linus Torvalds1da177e2005-04-16 15:20:36 -070080extern char core_pattern[];
Linus Torvalds1da177e2005-04-16 15:20:36 -070081extern int pid_max;
82extern int min_free_kbytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -070083extern int pid_max_min, pid_max_max;
Andrew Morton9d0243b2006-01-08 01:00:39 -080084extern int sysctl_drop_caches;
Rohit Seth8ad4b1f2006-01-08 01:00:40 -080085extern int percpu_pagelist_fraction;
Andi Kleenbebfa102006-06-26 13:56:52 +020086extern int compat_log;
Arjan van de Ven97455122008-01-25 21:08:34 +010087extern int latencytop_enabled;
Al Viroeceea0b2008-05-10 10:08:32 -040088extern int sysctl_nr_open_min, sysctl_nr_open_max;
Paul Mundtdd8632a2009-01-08 12:04:47 +000089#ifndef CONFIG_MMU
90extern int sysctl_nr_trim_pages;
91#endif
Paul E. McKenney31a72bc2008-06-18 09:26:49 -070092#ifdef CONFIG_RCU_TORTURE_TEST
93extern int rcutorture_runnable;
94#endif /* #ifdef CONFIG_RCU_TORTURE_TEST */
Jens Axboecb684b52009-09-15 21:53:11 +020095#ifdef CONFIG_BLOCK
Jens Axboe5e605b62009-08-05 09:07:21 +020096extern int blk_iopoll_enabled;
Jens Axboecb684b52009-09-15 21:53:11 +020097#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -070099/* Constants used for minimum and maximum */
Bron Gondwana195cf4532008-02-04 22:29:20 -0800100#ifdef CONFIG_DETECT_SOFTLOCKUP
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700101static int sixty = 60;
Dimitri Sivanich9383d962008-05-12 21:21:14 +0200102static int neg_one = -1;
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700103#endif
104
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700105static int zero;
Linus Torvaldscd5f9a42009-04-06 13:38:46 -0700106static int __maybe_unused one = 1;
107static int __maybe_unused two = 2;
Sven Wegenerfc3501d2009-02-11 13:04:23 -0800108static unsigned long one_ul = 1;
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700109static int one_hundred = 100;
110
Andrea Righi9e4a5bd2009-04-30 15:08:57 -0700111/* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
112static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
113
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
115static int maxolduid = 65535;
116static int minolduid;
Rohit Seth8ad4b1f2006-01-08 01:00:40 -0800117static int min_percpu_pagelist_fract = 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
119static int ngroups_max = NGROUPS_MAX;
120
Johannes Berga1ef5ad2008-07-08 19:00:17 +0200121#ifdef CONFIG_MODULES
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122extern char modprobe_path[];
Kees Cook3d433212009-04-02 15:49:29 -0700123extern int modules_disabled;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125#ifdef CONFIG_CHR_DEV_SG
126extern int sg_big_buff;
127#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128
David S. Miller72c57ed2008-09-11 23:29:54 -0700129#ifdef CONFIG_SPARC
David S. Miller17f04fb2008-09-11 23:33:53 -0700130#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131#endif
132
David S. Miller08714202008-11-16 23:49:24 -0800133#ifdef CONFIG_SPARC64
134extern int sysctl_tsb_ratio;
135#endif
136
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137#ifdef __hppa__
138extern int pwrsw_enabled;
139extern int unaligned_enabled;
140#endif
141
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800142#ifdef CONFIG_S390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143#ifdef CONFIG_MATHEMU
144extern int sysctl_ieee_emulation_warnings;
145#endif
146extern int sysctl_userprocess_debug;
Martin Schwidefsky951f22d2005-07-27 11:44:57 -0700147extern int spin_retry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148#endif
149
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150#ifdef CONFIG_BSD_PROCESS_ACCT
151extern int acct_parm[];
152#endif
153
Jes Sorensend2b176e2006-02-28 09:42:23 -0800154#ifdef CONFIG_IA64
155extern int no_unaligned_warning;
Doug Chapman88fc2412009-01-15 10:38:56 -0800156extern int unaligned_dump_stack;
Jes Sorensend2b176e2006-02-28 09:42:23 -0800157#endif
158
Ingo Molnar3fff4c42009-09-22 16:18:09 +0200159extern struct ratelimit_state printk_ratelimit_state;
160
Ingo Molnar23f78d4a2006-06-27 02:54:53 -0700161#ifdef CONFIG_RT_MUTEXES
162extern int max_lock_depth;
163#endif
164
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700165#ifdef CONFIG_PROC_SYSCTL
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700166static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700167 void __user *buffer, size_t *lenp, loff_t *ppos);
Andi Kleen25ddbb12008-10-15 22:01:41 -0700168static int proc_taint(struct ctl_table *table, int write, struct file *filp,
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800169 void __user *buffer, size_t *lenp, loff_t *ppos);
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700170#endif
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700171
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700172static struct ctl_table root_table[];
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100173static struct ctl_table_root sysctl_table_root;
174static struct ctl_table_header root_table_header = {
Al Virob380b0d2008-09-04 17:05:57 +0100175 .count = 1,
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100176 .ctl_table = root_table,
Al Viro73455092008-07-14 21:22:20 -0400177 .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100178 .root = &sysctl_table_root,
Al Viro73455092008-07-14 21:22:20 -0400179 .set = &sysctl_table_root.default_set,
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100180};
181static struct ctl_table_root sysctl_table_root = {
182 .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
Al Viro73455092008-07-14 21:22:20 -0400183 .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry),
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100184};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700186static struct ctl_table kern_table[];
187static struct ctl_table vm_table[];
188static struct ctl_table fs_table[];
189static struct ctl_table debug_table[];
190static struct ctl_table dev_table[];
191extern struct ctl_table random_table[];
Amy Griffis2d9048e2006-06-01 13:10:59 -0700192#ifdef CONFIG_INOTIFY_USER
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700193extern struct ctl_table inotify_table[];
Robert Love0399cb02005-07-13 12:38:18 -0400194#endif
Davide Libenzi7ef99642008-12-01 13:13:55 -0800195#ifdef CONFIG_EPOLL
196extern struct ctl_table epoll_table[];
197#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198
199#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
200int sysctl_legacy_va_layout;
201#endif
202
Peter Zijlstraf20786f2007-07-19 01:48:56 -0700203extern int prove_locking;
204extern int lock_stat;
Eric W. Biederman9bc9a6b2006-12-08 02:39:56 -0800205
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206/* The default sysctl tables: */
207
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700208static struct ctl_table root_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 {
210 .ctl_name = CTL_KERN,
211 .procname = "kernel",
212 .mode = 0555,
213 .child = kern_table,
214 },
215 {
216 .ctl_name = CTL_VM,
217 .procname = "vm",
218 .mode = 0555,
219 .child = vm_table,
220 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 .ctl_name = CTL_FS,
223 .procname = "fs",
224 .mode = 0555,
225 .child = fs_table,
226 },
227 {
228 .ctl_name = CTL_DEBUG,
229 .procname = "debug",
230 .mode = 0555,
231 .child = debug_table,
232 },
233 {
234 .ctl_name = CTL_DEV,
235 .procname = "dev",
236 .mode = 0555,
237 .child = dev_table,
238 },
Andrew Morton2be7fe02007-07-15 23:41:21 -0700239/*
240 * NOTE: do not add new entries to this table unless you have read
241 * Documentation/sysctl/ctl_unnumbered.txt
242 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 { .ctl_name = 0 }
244};
245
Ingo Molnar77e54a12007-07-09 18:52:00 +0200246#ifdef CONFIG_SCHED_DEBUG
Eric Dumazet73c4efd2007-12-18 15:21:13 +0100247static int min_sched_granularity_ns = 100000; /* 100 usecs */
248static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */
249static int min_wakeup_granularity_ns; /* 0 usecs */
250static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */
Ingo Molnar77e54a12007-07-09 18:52:00 +0200251#endif
252
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700253static struct ctl_table kern_table[] = {
Mike Galbraith2bba22c2009-09-09 15:41:37 +0200254 {
255 .ctl_name = CTL_UNNUMBERED,
256 .procname = "sched_child_runs_first",
257 .data = &sysctl_sched_child_runs_first,
258 .maxlen = sizeof(unsigned int),
259 .mode = 0644,
260 .proc_handler = &proc_dointvec,
261 },
Ingo Molnar77e54a12007-07-09 18:52:00 +0200262#ifdef CONFIG_SCHED_DEBUG
263 {
264 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstrab2be5e92007-11-09 22:39:37 +0100265 .procname = "sched_min_granularity_ns",
266 .data = &sysctl_sched_min_granularity,
Ingo Molnar77e54a12007-07-09 18:52:00 +0200267 .maxlen = sizeof(unsigned int),
268 .mode = 0644,
Peter Zijlstrab2be5e92007-11-09 22:39:37 +0100269 .proc_handler = &sched_nr_latency_handler,
270 .strategy = &sysctl_intvec,
271 .extra1 = &min_sched_granularity_ns,
272 .extra2 = &max_sched_granularity_ns,
Ingo Molnar77e54a12007-07-09 18:52:00 +0200273 },
274 {
275 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra21805082007-08-25 18:41:53 +0200276 .procname = "sched_latency_ns",
277 .data = &sysctl_sched_latency,
278 .maxlen = sizeof(unsigned int),
279 .mode = 0644,
Peter Zijlstrab2be5e92007-11-09 22:39:37 +0100280 .proc_handler = &sched_nr_latency_handler,
Peter Zijlstra21805082007-08-25 18:41:53 +0200281 .strategy = &sysctl_intvec,
282 .extra1 = &min_sched_granularity_ns,
283 .extra2 = &max_sched_granularity_ns,
284 },
285 {
286 .ctl_name = CTL_UNNUMBERED,
Ingo Molnar77e54a12007-07-09 18:52:00 +0200287 .procname = "sched_wakeup_granularity_ns",
288 .data = &sysctl_sched_wakeup_granularity,
289 .maxlen = sizeof(unsigned int),
290 .mode = 0644,
291 .proc_handler = &proc_dointvec_minmax,
292 .strategy = &sysctl_intvec,
293 .extra1 = &min_wakeup_granularity_ns,
294 .extra2 = &max_wakeup_granularity_ns,
295 },
296 {
297 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra2398f2c2008-06-27 13:41:35 +0200298 .procname = "sched_shares_ratelimit",
299 .data = &sysctl_sched_shares_ratelimit,
300 .maxlen = sizeof(unsigned int),
301 .mode = 0644,
302 .proc_handler = &proc_dointvec,
303 },
304 {
305 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstraffda12a2008-10-17 19:27:02 +0200306 .procname = "sched_shares_thresh",
307 .data = &sysctl_sched_shares_thresh,
308 .maxlen = sizeof(unsigned int),
309 .mode = 0644,
310 .proc_handler = &proc_dointvec_minmax,
311 .strategy = &sysctl_intvec,
312 .extra1 = &zero,
313 },
314 {
315 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra1fc84aa2007-08-25 18:41:52 +0200316 .procname = "sched_features",
317 .data = &sysctl_sched_features,
318 .maxlen = sizeof(unsigned int),
319 .mode = 0644,
320 .proc_handler = &proc_dointvec,
321 },
Ingo Molnarda84d962007-10-15 17:00:18 +0200322 {
323 .ctl_name = CTL_UNNUMBERED,
324 .procname = "sched_migration_cost",
325 .data = &sysctl_sched_migration_cost,
326 .maxlen = sizeof(unsigned int),
327 .mode = 0644,
328 .proc_handler = &proc_dointvec,
329 },
Peter Zijlstrab82d9fd2007-11-09 22:39:39 +0100330 {
331 .ctl_name = CTL_UNNUMBERED,
332 .procname = "sched_nr_migrate",
333 .data = &sysctl_sched_nr_migrate,
334 .maxlen = sizeof(unsigned int),
Peter Zijlstrafa85ae22008-01-25 21:08:29 +0100335 .mode = 0644,
336 .proc_handler = &proc_dointvec,
337 },
Arun R Bharadwajcd1bb942009-04-16 12:15:34 +0530338 {
339 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstrae9e92502009-09-01 10:34:37 +0200340 .procname = "sched_time_avg",
341 .data = &sysctl_sched_time_avg,
342 .maxlen = sizeof(unsigned int),
343 .mode = 0644,
344 .proc_handler = &proc_dointvec,
345 },
346 {
347 .ctl_name = CTL_UNNUMBERED,
Arun R Bharadwajcd1bb942009-04-16 12:15:34 +0530348 .procname = "timer_migration",
349 .data = &sysctl_timer_migration,
350 .maxlen = sizeof(unsigned int),
351 .mode = 0644,
Arun R Bharadwajbfdb4d92009-06-23 10:00:58 +0530352 .proc_handler = &proc_dointvec_minmax,
353 .strategy = &sysctl_intvec,
354 .extra1 = &zero,
355 .extra2 = &one,
Arun R Bharadwajcd1bb942009-04-16 12:15:34 +0530356 },
Peter Zijlstra1fc84aa2007-08-25 18:41:52 +0200357#endif
Ingo Molnar1799e352007-09-19 23:34:46 +0200358 {
359 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra9f0c1e52008-02-13 15:45:39 +0100360 .procname = "sched_rt_period_us",
361 .data = &sysctl_sched_rt_period,
362 .maxlen = sizeof(unsigned int),
363 .mode = 0644,
Peter Zijlstrad0b27fa2008-04-19 19:44:57 +0200364 .proc_handler = &sched_rt_handler,
Peter Zijlstra9f0c1e52008-02-13 15:45:39 +0100365 },
366 {
367 .ctl_name = CTL_UNNUMBERED,
368 .procname = "sched_rt_runtime_us",
369 .data = &sysctl_sched_rt_runtime,
370 .maxlen = sizeof(int),
371 .mode = 0644,
Peter Zijlstrad0b27fa2008-04-19 19:44:57 +0200372 .proc_handler = &sched_rt_handler,
Peter Zijlstra9f0c1e52008-02-13 15:45:39 +0100373 },
374 {
375 .ctl_name = CTL_UNNUMBERED,
Ingo Molnar1799e352007-09-19 23:34:46 +0200376 .procname = "sched_compat_yield",
377 .data = &sysctl_sched_compat_yield,
378 .maxlen = sizeof(unsigned int),
379 .mode = 0644,
380 .proc_handler = &proc_dointvec,
381 },
Peter Zijlstraf20786f2007-07-19 01:48:56 -0700382#ifdef CONFIG_PROVE_LOCKING
383 {
384 .ctl_name = CTL_UNNUMBERED,
385 .procname = "prove_locking",
386 .data = &prove_locking,
387 .maxlen = sizeof(int),
388 .mode = 0644,
389 .proc_handler = &proc_dointvec,
390 },
391#endif
392#ifdef CONFIG_LOCK_STAT
393 {
394 .ctl_name = CTL_UNNUMBERED,
395 .procname = "lock_stat",
396 .data = &lock_stat,
397 .maxlen = sizeof(int),
398 .mode = 0644,
399 .proc_handler = &proc_dointvec,
400 },
401#endif
Ingo Molnar77e54a12007-07-09 18:52:00 +0200402 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 .ctl_name = KERN_PANIC,
404 .procname = "panic",
405 .data = &panic_timeout,
406 .maxlen = sizeof(int),
407 .mode = 0644,
408 .proc_handler = &proc_dointvec,
409 },
410 {
411 .ctl_name = KERN_CORE_USES_PID,
412 .procname = "core_uses_pid",
413 .data = &core_uses_pid,
414 .maxlen = sizeof(int),
415 .mode = 0644,
416 .proc_handler = &proc_dointvec,
417 },
418 {
419 .ctl_name = KERN_CORE_PATTERN,
420 .procname = "core_pattern",
421 .data = core_pattern,
Dan Aloni71ce92f2007-05-16 22:11:16 -0700422 .maxlen = CORENAME_MAX_SIZE,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 .mode = 0644,
424 .proc_handler = &proc_dostring,
425 .strategy = &sysctl_string,
426 },
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800427#ifdef CONFIG_PROC_SYSCTL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 .procname = "tainted",
Andi Kleen25ddbb12008-10-15 22:01:41 -0700430 .maxlen = sizeof(long),
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800431 .mode = 0644,
Andi Kleen25ddbb12008-10-15 22:01:41 -0700432 .proc_handler = &proc_taint,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 },
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800434#endif
Arjan van de Ven97455122008-01-25 21:08:34 +0100435#ifdef CONFIG_LATENCYTOP
436 {
437 .procname = "latencytop",
438 .data = &latencytop_enabled,
439 .maxlen = sizeof(int),
440 .mode = 0644,
441 .proc_handler = &proc_dointvec,
442 },
443#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444#ifdef CONFIG_BLK_DEV_INITRD
445 {
446 .ctl_name = KERN_REALROOTDEV,
447 .procname = "real-root-dev",
448 .data = &real_root_dev,
449 .maxlen = sizeof(int),
450 .mode = 0644,
451 .proc_handler = &proc_dointvec,
452 },
453#endif
Ingo Molnar45807a12007-07-15 23:40:10 -0700454 {
455 .ctl_name = CTL_UNNUMBERED,
456 .procname = "print-fatal-signals",
457 .data = &print_fatal_signals,
458 .maxlen = sizeof(int),
459 .mode = 0644,
460 .proc_handler = &proc_dointvec,
461 },
David S. Miller72c57ed2008-09-11 23:29:54 -0700462#ifdef CONFIG_SPARC
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 {
464 .ctl_name = KERN_SPARC_REBOOT,
465 .procname = "reboot-cmd",
466 .data = reboot_command,
467 .maxlen = 256,
468 .mode = 0644,
469 .proc_handler = &proc_dostring,
470 .strategy = &sysctl_string,
471 },
472 {
473 .ctl_name = KERN_SPARC_STOP_A,
474 .procname = "stop-a",
475 .data = &stop_a_enabled,
476 .maxlen = sizeof (int),
477 .mode = 0644,
478 .proc_handler = &proc_dointvec,
479 },
480 {
481 .ctl_name = KERN_SPARC_SCONS_PWROFF,
482 .procname = "scons-poweroff",
483 .data = &scons_pwroff,
484 .maxlen = sizeof (int),
485 .mode = 0644,
486 .proc_handler = &proc_dointvec,
487 },
488#endif
David S. Miller08714202008-11-16 23:49:24 -0800489#ifdef CONFIG_SPARC64
490 {
491 .ctl_name = CTL_UNNUMBERED,
492 .procname = "tsb-ratio",
493 .data = &sysctl_tsb_ratio,
494 .maxlen = sizeof (int),
495 .mode = 0644,
496 .proc_handler = &proc_dointvec,
497 },
498#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499#ifdef __hppa__
500 {
501 .ctl_name = KERN_HPPA_PWRSW,
502 .procname = "soft-power",
503 .data = &pwrsw_enabled,
504 .maxlen = sizeof (int),
505 .mode = 0644,
506 .proc_handler = &proc_dointvec,
507 },
508 {
509 .ctl_name = KERN_HPPA_UNALIGNED,
510 .procname = "unaligned-trap",
511 .data = &unaligned_enabled,
512 .maxlen = sizeof (int),
513 .mode = 0644,
514 .proc_handler = &proc_dointvec,
515 },
516#endif
517 {
518 .ctl_name = KERN_CTLALTDEL,
519 .procname = "ctrl-alt-del",
520 .data = &C_A_D,
521 .maxlen = sizeof(int),
522 .mode = 0644,
523 .proc_handler = &proc_dointvec,
524 },
Steven Rostedt606576c2008-10-06 19:06:12 -0400525#ifdef CONFIG_FUNCTION_TRACER
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200526 {
527 .ctl_name = CTL_UNNUMBERED,
528 .procname = "ftrace_enabled",
529 .data = &ftrace_enabled,
530 .maxlen = sizeof(int),
531 .mode = 0644,
532 .proc_handler = &ftrace_enable_sysctl,
533 },
534#endif
Steven Rostedtf38f1d22008-12-16 23:06:40 -0500535#ifdef CONFIG_STACK_TRACER
536 {
537 .ctl_name = CTL_UNNUMBERED,
538 .procname = "stack_tracer_enabled",
539 .data = &stack_tracer_enabled,
540 .maxlen = sizeof(int),
541 .mode = 0644,
542 .proc_handler = &stack_trace_sysctl,
543 },
544#endif
Steven Rostedt944ac422008-10-23 19:26:08 -0400545#ifdef CONFIG_TRACING
546 {
547 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra3299b4d2008-11-04 11:58:21 +0100548 .procname = "ftrace_dump_on_oops",
Steven Rostedt944ac422008-10-23 19:26:08 -0400549 .data = &ftrace_dump_on_oops,
550 .maxlen = sizeof(int),
551 .mode = 0644,
552 .proc_handler = &proc_dointvec,
553 },
554#endif
Johannes Berga1ef5ad2008-07-08 19:00:17 +0200555#ifdef CONFIG_MODULES
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 {
557 .ctl_name = KERN_MODPROBE,
558 .procname = "modprobe",
559 .data = &modprobe_path,
560 .maxlen = KMOD_PATH_LEN,
561 .mode = 0644,
562 .proc_handler = &proc_dostring,
563 .strategy = &sysctl_string,
564 },
Kees Cook3d433212009-04-02 15:49:29 -0700565 {
566 .ctl_name = CTL_UNNUMBERED,
567 .procname = "modules_disabled",
568 .data = &modules_disabled,
569 .maxlen = sizeof(int),
570 .mode = 0644,
571 /* only handle a transition from default "0" to "1" */
572 .proc_handler = &proc_dointvec_minmax,
573 .extra1 = &one,
574 .extra2 = &one,
575 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576#endif
Andrew Morton57ae2502006-06-23 02:05:47 -0700577#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 {
579 .ctl_name = KERN_HOTPLUG,
580 .procname = "hotplug",
Kay Sievers312c0042005-11-16 09:00:00 +0100581 .data = &uevent_helper,
582 .maxlen = UEVENT_HELPER_PATH_LEN,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 .mode = 0644,
584 .proc_handler = &proc_dostring,
585 .strategy = &sysctl_string,
586 },
587#endif
588#ifdef CONFIG_CHR_DEV_SG
589 {
590 .ctl_name = KERN_SG_BIG_BUFF,
591 .procname = "sg-big-buff",
592 .data = &sg_big_buff,
593 .maxlen = sizeof (int),
594 .mode = 0444,
595 .proc_handler = &proc_dointvec,
596 },
597#endif
598#ifdef CONFIG_BSD_PROCESS_ACCT
599 {
600 .ctl_name = KERN_ACCT,
601 .procname = "acct",
602 .data = &acct_parm,
603 .maxlen = 3*sizeof(int),
604 .mode = 0644,
605 .proc_handler = &proc_dointvec,
606 },
607#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608#ifdef CONFIG_MAGIC_SYSRQ
609 {
610 .ctl_name = KERN_SYSRQ,
611 .procname = "sysrq",
Ingo Molnar5d6f6472006-12-13 00:34:36 -0800612 .data = &__sysrq_enabled,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 .maxlen = sizeof (int),
614 .mode = 0644,
615 .proc_handler = &proc_dointvec,
616 },
617#endif
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700618#ifdef CONFIG_PROC_SYSCTL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 .procname = "cad_pid",
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700621 .data = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 .maxlen = sizeof (int),
623 .mode = 0600,
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700624 .proc_handler = &proc_do_cad_pid,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 },
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700626#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 {
628 .ctl_name = KERN_MAX_THREADS,
629 .procname = "threads-max",
630 .data = &max_threads,
631 .maxlen = sizeof(int),
632 .mode = 0644,
633 .proc_handler = &proc_dointvec,
634 },
635 {
636 .ctl_name = KERN_RANDOM,
637 .procname = "random",
638 .mode = 0555,
639 .child = random_table,
640 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 {
642 .ctl_name = KERN_OVERFLOWUID,
643 .procname = "overflowuid",
644 .data = &overflowuid,
645 .maxlen = sizeof(int),
646 .mode = 0644,
647 .proc_handler = &proc_dointvec_minmax,
648 .strategy = &sysctl_intvec,
649 .extra1 = &minolduid,
650 .extra2 = &maxolduid,
651 },
652 {
653 .ctl_name = KERN_OVERFLOWGID,
654 .procname = "overflowgid",
655 .data = &overflowgid,
656 .maxlen = sizeof(int),
657 .mode = 0644,
658 .proc_handler = &proc_dointvec_minmax,
659 .strategy = &sysctl_intvec,
660 .extra1 = &minolduid,
661 .extra2 = &maxolduid,
662 },
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800663#ifdef CONFIG_S390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664#ifdef CONFIG_MATHEMU
665 {
666 .ctl_name = KERN_IEEE_EMULATION_WARNINGS,
667 .procname = "ieee_emulation_warnings",
668 .data = &sysctl_ieee_emulation_warnings,
669 .maxlen = sizeof(int),
670 .mode = 0644,
671 .proc_handler = &proc_dointvec,
672 },
673#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 {
675 .ctl_name = KERN_S390_USER_DEBUG_LOGGING,
676 .procname = "userprocess_debug",
677 .data = &sysctl_userprocess_debug,
678 .maxlen = sizeof(int),
679 .mode = 0644,
680 .proc_handler = &proc_dointvec,
681 },
682#endif
683 {
684 .ctl_name = KERN_PIDMAX,
685 .procname = "pid_max",
686 .data = &pid_max,
687 .maxlen = sizeof (int),
688 .mode = 0644,
689 .proc_handler = &proc_dointvec_minmax,
690 .strategy = sysctl_intvec,
691 .extra1 = &pid_max_min,
692 .extra2 = &pid_max_max,
693 },
694 {
695 .ctl_name = KERN_PANIC_ON_OOPS,
696 .procname = "panic_on_oops",
697 .data = &panic_on_oops,
698 .maxlen = sizeof(int),
699 .mode = 0644,
700 .proc_handler = &proc_dointvec,
701 },
Joe Perches7ef3d2f2008-02-08 04:21:25 -0800702#if defined CONFIG_PRINTK
703 {
704 .ctl_name = KERN_PRINTK,
705 .procname = "printk",
706 .data = &console_loglevel,
707 .maxlen = 4*sizeof(int),
708 .mode = 0644,
709 .proc_handler = &proc_dointvec,
710 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 {
712 .ctl_name = KERN_PRINTK_RATELIMIT,
713 .procname = "printk_ratelimit",
Dave Young717115e2008-07-25 01:45:58 -0700714 .data = &printk_ratelimit_state.interval,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 .maxlen = sizeof(int),
716 .mode = 0644,
717 .proc_handler = &proc_dointvec_jiffies,
718 .strategy = &sysctl_jiffies,
719 },
720 {
721 .ctl_name = KERN_PRINTK_RATELIMIT_BURST,
722 .procname = "printk_ratelimit_burst",
Dave Young717115e2008-07-25 01:45:58 -0700723 .data = &printk_ratelimit_state.burst,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 .maxlen = sizeof(int),
725 .mode = 0644,
726 .proc_handler = &proc_dointvec,
727 },
Joe Perches7ef3d2f2008-02-08 04:21:25 -0800728#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 {
730 .ctl_name = KERN_NGROUPS_MAX,
731 .procname = "ngroups_max",
732 .data = &ngroups_max,
733 .maxlen = sizeof (int),
734 .mode = 0444,
735 .proc_handler = &proc_dointvec,
736 },
737#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
738 {
739 .ctl_name = KERN_UNKNOWN_NMI_PANIC,
740 .procname = "unknown_nmi_panic",
741 .data = &unknown_nmi_panic,
742 .maxlen = sizeof (int),
743 .mode = 0644,
Don Zickus2fbe7b22006-09-26 10:52:27 +0200744 .proc_handler = &proc_dointvec,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 },
Don Zickus407984f2006-09-26 10:52:27 +0200746 {
Don Zickus407984f2006-09-26 10:52:27 +0200747 .procname = "nmi_watchdog",
748 .data = &nmi_watchdog_enabled,
749 .maxlen = sizeof (int),
750 .mode = 0644,
751 .proc_handler = &proc_nmi_enabled,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 },
753#endif
754#if defined(CONFIG_X86)
755 {
Don Zickus8da5add2006-09-26 10:52:27 +0200756 .ctl_name = KERN_PANIC_ON_NMI,
757 .procname = "panic_on_unrecovered_nmi",
758 .data = &panic_on_unrecovered_nmi,
759 .maxlen = sizeof(int),
760 .mode = 0644,
761 .proc_handler = &proc_dointvec,
762 },
763 {
Kurt Garloff5211a242009-06-24 14:32:11 -0700764 .ctl_name = CTL_UNNUMBERED,
765 .procname = "panic_on_io_nmi",
766 .data = &panic_on_io_nmi,
767 .maxlen = sizeof(int),
768 .mode = 0644,
769 .proc_handler = &proc_dointvec,
770 },
771 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 .ctl_name = KERN_BOOTLOADER_TYPE,
773 .procname = "bootloader_type",
774 .data = &bootloader_type,
775 .maxlen = sizeof (int),
776 .mode = 0444,
777 .proc_handler = &proc_dointvec,
778 },
Chuck Ebbert0741f4d2006-12-07 02:14:11 +0100779 {
780 .ctl_name = CTL_UNNUMBERED,
H. Peter Anvin50312962009-05-07 16:54:11 -0700781 .procname = "bootloader_version",
782 .data = &bootloader_version,
783 .maxlen = sizeof (int),
784 .mode = 0444,
785 .proc_handler = &proc_dointvec,
786 },
787 {
788 .ctl_name = CTL_UNNUMBERED,
Chuck Ebbert0741f4d2006-12-07 02:14:11 +0100789 .procname = "kstack_depth_to_print",
790 .data = &kstack_depth_to_print,
791 .maxlen = sizeof(int),
792 .mode = 0644,
793 .proc_handler = &proc_dointvec,
794 },
Ingo Molnar6e7c4022008-01-30 13:30:05 +0100795 {
796 .ctl_name = CTL_UNNUMBERED,
797 .procname = "io_delay_type",
798 .data = &io_delay_type,
799 .maxlen = sizeof(int),
800 .mode = 0644,
801 .proc_handler = &proc_dointvec,
802 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803#endif
Luke Yang7a9166e2006-02-20 18:28:07 -0800804#if defined(CONFIG_MMU)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 {
806 .ctl_name = KERN_RANDOMIZE,
807 .procname = "randomize_va_space",
808 .data = &randomize_va_space,
809 .maxlen = sizeof(int),
810 .mode = 0644,
811 .proc_handler = &proc_dointvec,
812 },
Luke Yang7a9166e2006-02-20 18:28:07 -0800813#endif
Martin Schwidefsky0152fb32006-01-14 13:21:00 -0800814#if defined(CONFIG_S390) && defined(CONFIG_SMP)
Martin Schwidefsky951f22d2005-07-27 11:44:57 -0700815 {
816 .ctl_name = KERN_SPIN_RETRY,
817 .procname = "spin_retry",
818 .data = &spin_retry,
819 .maxlen = sizeof (int),
820 .mode = 0644,
821 .proc_handler = &proc_dointvec,
822 },
823#endif
Len Brown673d5b42007-07-28 03:33:16 -0400824#if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86)
Pavel Machekc255d842006-02-20 18:27:58 -0800825 {
Pavel Machekc255d842006-02-20 18:27:58 -0800826 .procname = "acpi_video_flags",
Pavel Machek77afcf72007-07-19 01:47:41 -0700827 .data = &acpi_realmode_flags,
Pavel Machekc255d842006-02-20 18:27:58 -0800828 .maxlen = sizeof (unsigned long),
829 .mode = 0644,
Stefan Seyfried7f99f062006-03-02 02:54:34 -0800830 .proc_handler = &proc_doulongvec_minmax,
Pavel Machekc255d842006-02-20 18:27:58 -0800831 },
832#endif
Jes Sorensend2b176e2006-02-28 09:42:23 -0800833#ifdef CONFIG_IA64
834 {
835 .ctl_name = KERN_IA64_UNALIGNED,
836 .procname = "ignore-unaligned-usertrap",
837 .data = &no_unaligned_warning,
838 .maxlen = sizeof (int),
839 .mode = 0644,
840 .proc_handler = &proc_dointvec,
841 },
Doug Chapman88fc2412009-01-15 10:38:56 -0800842 {
843 .ctl_name = CTL_UNNUMBERED,
844 .procname = "unaligned-dump-stack",
845 .data = &unaligned_dump_stack,
846 .maxlen = sizeof (int),
847 .mode = 0644,
848 .proc_handler = &proc_dointvec,
849 },
Jes Sorensend2b176e2006-02-28 09:42:23 -0800850#endif
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700851#ifdef CONFIG_DETECT_SOFTLOCKUP
852 {
853 .ctl_name = CTL_UNNUMBERED,
Ingo Molnar9c44bc02008-05-12 21:21:04 +0200854 .procname = "softlockup_panic",
855 .data = &softlockup_panic,
856 .maxlen = sizeof(int),
857 .mode = 0644,
Hiroshi Shimamoto4dca10a2008-07-07 18:37:04 -0700858 .proc_handler = &proc_dointvec_minmax,
Ingo Molnar9c44bc02008-05-12 21:21:04 +0200859 .strategy = &sysctl_intvec,
860 .extra1 = &zero,
861 .extra2 = &one,
862 },
863 {
864 .ctl_name = CTL_UNNUMBERED,
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700865 .procname = "softlockup_thresh",
866 .data = &softlockup_thresh,
Dimitri Sivanich9383d962008-05-12 21:21:14 +0200867 .maxlen = sizeof(int),
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700868 .mode = 0644,
Mandeep Singh Bainesbaf48f62009-01-12 21:15:17 -0800869 .proc_handler = &proc_dosoftlockup_thresh,
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700870 .strategy = &sysctl_intvec,
Dimitri Sivanich9383d962008-05-12 21:21:14 +0200871 .extra1 = &neg_one,
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700872 .extra2 = &sixty,
873 },
Mandeep Singh Bainese162b392009-01-15 11:08:40 -0800874#endif
875#ifdef CONFIG_DETECT_HUNG_TASK
876 {
877 .ctl_name = CTL_UNNUMBERED,
878 .procname = "hung_task_panic",
879 .data = &sysctl_hung_task_panic,
880 .maxlen = sizeof(int),
881 .mode = 0644,
882 .proc_handler = &proc_dointvec_minmax,
883 .strategy = &sysctl_intvec,
884 .extra1 = &zero,
885 .extra2 = &one,
886 },
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100887 {
888 .ctl_name = CTL_UNNUMBERED,
889 .procname = "hung_task_check_count",
890 .data = &sysctl_hung_task_check_count,
Ingo Molnar90739082008-01-25 21:08:34 +0100891 .maxlen = sizeof(unsigned long),
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100892 .mode = 0644,
Ingo Molnar90739082008-01-25 21:08:34 +0100893 .proc_handler = &proc_doulongvec_minmax,
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100894 .strategy = &sysctl_intvec,
895 },
896 {
897 .ctl_name = CTL_UNNUMBERED,
898 .procname = "hung_task_timeout_secs",
899 .data = &sysctl_hung_task_timeout_secs,
Ingo Molnar90739082008-01-25 21:08:34 +0100900 .maxlen = sizeof(unsigned long),
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100901 .mode = 0644,
Mandeep Singh Bainese162b392009-01-15 11:08:40 -0800902 .proc_handler = &proc_dohung_task_timeout_secs,
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100903 .strategy = &sysctl_intvec,
904 },
905 {
906 .ctl_name = CTL_UNNUMBERED,
907 .procname = "hung_task_warnings",
908 .data = &sysctl_hung_task_warnings,
Ingo Molnar90739082008-01-25 21:08:34 +0100909 .maxlen = sizeof(unsigned long),
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100910 .mode = 0644,
Ingo Molnar90739082008-01-25 21:08:34 +0100911 .proc_handler = &proc_doulongvec_minmax,
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100912 .strategy = &sysctl_intvec,
913 },
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700914#endif
Andi Kleenbebfa102006-06-26 13:56:52 +0200915#ifdef CONFIG_COMPAT
916 {
917 .ctl_name = KERN_COMPAT_LOG,
918 .procname = "compat-log",
919 .data = &compat_log,
920 .maxlen = sizeof (int),
921 .mode = 0644,
922 .proc_handler = &proc_dointvec,
923 },
924#endif
Ingo Molnar23f78d4a2006-06-27 02:54:53 -0700925#ifdef CONFIG_RT_MUTEXES
926 {
927 .ctl_name = KERN_MAX_LOCK_DEPTH,
928 .procname = "max_lock_depth",
929 .data = &max_lock_depth,
930 .maxlen = sizeof(int),
931 .mode = 0644,
932 .proc_handler = &proc_dointvec,
933 },
934#endif
Jeremy Fitzhardinge10a0a8d2007-07-17 18:37:02 -0700935 {
936 .ctl_name = CTL_UNNUMBERED,
937 .procname = "poweroff_cmd",
938 .data = &poweroff_cmd,
939 .maxlen = POWEROFF_CMD_PATH_LEN,
940 .mode = 0644,
941 .proc_handler = &proc_dostring,
942 .strategy = &sysctl_string,
943 },
David Howells0b77f5b2008-04-29 01:01:32 -0700944#ifdef CONFIG_KEYS
945 {
946 .ctl_name = CTL_UNNUMBERED,
947 .procname = "keys",
948 .mode = 0555,
949 .child = key_sysctls,
950 },
951#endif
Paul E. McKenney31a72bc2008-06-18 09:26:49 -0700952#ifdef CONFIG_RCU_TORTURE_TEST
953 {
954 .ctl_name = CTL_UNNUMBERED,
955 .procname = "rcutorture_runnable",
956 .data = &rcutorture_runnable,
957 .maxlen = sizeof(int),
958 .mode = 0644,
959 .proc_handler = &proc_dointvec,
960 },
961#endif
David Howells12e22c52009-04-03 16:42:35 +0100962#ifdef CONFIG_SLOW_WORK
963 {
964 .ctl_name = CTL_UNNUMBERED,
965 .procname = "slow-work",
966 .mode = 0555,
967 .child = slow_work_sysctls,
968 },
969#endif
Peter Zijlstra1ccd1542009-04-09 10:53:45 +0200970#ifdef CONFIG_PERF_COUNTERS
971 {
972 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra07647712009-06-11 11:18:36 +0200973 .procname = "perf_counter_paranoid",
974 .data = &sysctl_perf_counter_paranoid,
975 .maxlen = sizeof(sysctl_perf_counter_paranoid),
Peter Zijlstra1ccd1542009-04-09 10:53:45 +0200976 .mode = 0644,
977 .proc_handler = &proc_dointvec,
978 },
Peter Zijlstrac5078f72009-05-05 17:50:24 +0200979 {
980 .ctl_name = CTL_UNNUMBERED,
981 .procname = "perf_counter_mlock_kb",
982 .data = &sysctl_perf_counter_mlock,
983 .maxlen = sizeof(sysctl_perf_counter_mlock),
984 .mode = 0644,
985 .proc_handler = &proc_dointvec,
986 },
Peter Zijlstraa78ac322009-05-25 17:39:05 +0200987 {
988 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstradf58ab22009-06-11 11:25:05 +0200989 .procname = "perf_counter_max_sample_rate",
990 .data = &sysctl_perf_counter_sample_rate,
991 .maxlen = sizeof(sysctl_perf_counter_sample_rate),
Peter Zijlstraa78ac322009-05-25 17:39:05 +0200992 .mode = 0644,
993 .proc_handler = &proc_dointvec,
994 },
Peter Zijlstra1ccd1542009-04-09 10:53:45 +0200995#endif
Vegard Nossumdfec0722008-04-04 00:51:41 +0200996#ifdef CONFIG_KMEMCHECK
997 {
998 .ctl_name = CTL_UNNUMBERED,
999 .procname = "kmemcheck",
1000 .data = &kmemcheck_enabled,
1001 .maxlen = sizeof(int),
1002 .mode = 0644,
1003 .proc_handler = &proc_dointvec,
1004 },
1005#endif
Jens Axboecb684b52009-09-15 21:53:11 +02001006#ifdef CONFIG_BLOCK
Jens Axboe5e605b62009-08-05 09:07:21 +02001007 {
1008 .ctl_name = CTL_UNNUMBERED,
1009 .procname = "blk_iopoll",
1010 .data = &blk_iopoll_enabled,
1011 .maxlen = sizeof(int),
1012 .mode = 0644,
1013 .proc_handler = &proc_dointvec,
1014 },
Jens Axboecb684b52009-09-15 21:53:11 +02001015#endif
Andrew Mortoned2c12f2007-07-19 01:50:35 -07001016/*
1017 * NOTE: do not add new entries to this table unless you have read
1018 * Documentation/sysctl/ctl_unnumbered.txt
1019 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 { .ctl_name = 0 }
1021};
1022
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001023static struct ctl_table vm_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 {
1025 .ctl_name = VM_OVERCOMMIT_MEMORY,
1026 .procname = "overcommit_memory",
1027 .data = &sysctl_overcommit_memory,
1028 .maxlen = sizeof(sysctl_overcommit_memory),
1029 .mode = 0644,
1030 .proc_handler = &proc_dointvec,
1031 },
1032 {
KAMEZAWA Hiroyukifadd8fb2006-06-23 02:03:13 -07001033 .ctl_name = VM_PANIC_ON_OOM,
1034 .procname = "panic_on_oom",
1035 .data = &sysctl_panic_on_oom,
1036 .maxlen = sizeof(sysctl_panic_on_oom),
1037 .mode = 0644,
1038 .proc_handler = &proc_dointvec,
1039 },
1040 {
David Rientjesfe071d72007-10-16 23:25:56 -07001041 .ctl_name = CTL_UNNUMBERED,
1042 .procname = "oom_kill_allocating_task",
1043 .data = &sysctl_oom_kill_allocating_task,
1044 .maxlen = sizeof(sysctl_oom_kill_allocating_task),
1045 .mode = 0644,
1046 .proc_handler = &proc_dointvec,
1047 },
1048 {
David Rientjesfef1bdd2008-02-07 00:14:07 -08001049 .ctl_name = CTL_UNNUMBERED,
1050 .procname = "oom_dump_tasks",
1051 .data = &sysctl_oom_dump_tasks,
1052 .maxlen = sizeof(sysctl_oom_dump_tasks),
1053 .mode = 0644,
1054 .proc_handler = &proc_dointvec,
1055 },
1056 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 .ctl_name = VM_OVERCOMMIT_RATIO,
1058 .procname = "overcommit_ratio",
1059 .data = &sysctl_overcommit_ratio,
1060 .maxlen = sizeof(sysctl_overcommit_ratio),
1061 .mode = 0644,
1062 .proc_handler = &proc_dointvec,
1063 },
1064 {
1065 .ctl_name = VM_PAGE_CLUSTER,
1066 .procname = "page-cluster",
1067 .data = &page_cluster,
1068 .maxlen = sizeof(int),
1069 .mode = 0644,
1070 .proc_handler = &proc_dointvec,
1071 },
1072 {
1073 .ctl_name = VM_DIRTY_BACKGROUND,
1074 .procname = "dirty_background_ratio",
1075 .data = &dirty_background_ratio,
1076 .maxlen = sizeof(dirty_background_ratio),
1077 .mode = 0644,
David Rientjes2da02992009-01-06 14:39:31 -08001078 .proc_handler = &dirty_background_ratio_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 .strategy = &sysctl_intvec,
1080 .extra1 = &zero,
1081 .extra2 = &one_hundred,
1082 },
1083 {
David Rientjes2da02992009-01-06 14:39:31 -08001084 .ctl_name = CTL_UNNUMBERED,
1085 .procname = "dirty_background_bytes",
1086 .data = &dirty_background_bytes,
1087 .maxlen = sizeof(dirty_background_bytes),
1088 .mode = 0644,
1089 .proc_handler = &dirty_background_bytes_handler,
1090 .strategy = &sysctl_intvec,
Sven Wegenerfc3501d2009-02-11 13:04:23 -08001091 .extra1 = &one_ul,
David Rientjes2da02992009-01-06 14:39:31 -08001092 },
1093 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 .ctl_name = VM_DIRTY_RATIO,
1095 .procname = "dirty_ratio",
1096 .data = &vm_dirty_ratio,
1097 .maxlen = sizeof(vm_dirty_ratio),
1098 .mode = 0644,
Peter Zijlstra04fbfdc2007-10-16 23:25:50 -07001099 .proc_handler = &dirty_ratio_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 .strategy = &sysctl_intvec,
1101 .extra1 = &zero,
1102 .extra2 = &one_hundred,
1103 },
1104 {
David Rientjes2da02992009-01-06 14:39:31 -08001105 .ctl_name = CTL_UNNUMBERED,
1106 .procname = "dirty_bytes",
1107 .data = &vm_dirty_bytes,
1108 .maxlen = sizeof(vm_dirty_bytes),
1109 .mode = 0644,
1110 .proc_handler = &dirty_bytes_handler,
1111 .strategy = &sysctl_intvec,
Andrea Righi9e4a5bd2009-04-30 15:08:57 -07001112 .extra1 = &dirty_bytes_min,
David Rientjes2da02992009-01-06 14:39:31 -08001113 },
1114 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 .procname = "dirty_writeback_centisecs",
Bart Samwelf6ef9432006-03-24 03:15:48 -08001116 .data = &dirty_writeback_interval,
1117 .maxlen = sizeof(dirty_writeback_interval),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 .mode = 0644,
1119 .proc_handler = &dirty_writeback_centisecs_handler,
1120 },
1121 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 .procname = "dirty_expire_centisecs",
Bart Samwelf6ef9432006-03-24 03:15:48 -08001123 .data = &dirty_expire_interval,
1124 .maxlen = sizeof(dirty_expire_interval),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 .mode = 0644,
Alexey Dobriyan704503d2009-03-31 15:23:18 -07001126 .proc_handler = &proc_dointvec,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 },
1128 {
1129 .ctl_name = VM_NR_PDFLUSH_THREADS,
1130 .procname = "nr_pdflush_threads",
1131 .data = &nr_pdflush_threads,
1132 .maxlen = sizeof nr_pdflush_threads,
1133 .mode = 0444 /* read-only*/,
1134 .proc_handler = &proc_dointvec,
1135 },
1136 {
1137 .ctl_name = VM_SWAPPINESS,
1138 .procname = "swappiness",
1139 .data = &vm_swappiness,
1140 .maxlen = sizeof(vm_swappiness),
1141 .mode = 0644,
1142 .proc_handler = &proc_dointvec_minmax,
1143 .strategy = &sysctl_intvec,
1144 .extra1 = &zero,
1145 .extra2 = &one_hundred,
1146 },
1147#ifdef CONFIG_HUGETLB_PAGE
1148 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 .procname = "nr_hugepages",
Andi Kleene5ff2152008-07-23 21:27:42 -07001150 .data = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 .maxlen = sizeof(unsigned long),
1152 .mode = 0644,
1153 .proc_handler = &hugetlb_sysctl_handler,
1154 .extra1 = (void *)&hugetlb_zero,
1155 .extra2 = (void *)&hugetlb_infinity,
1156 },
1157 {
1158 .ctl_name = VM_HUGETLB_GROUP,
1159 .procname = "hugetlb_shm_group",
1160 .data = &sysctl_hugetlb_shm_group,
1161 .maxlen = sizeof(gid_t),
1162 .mode = 0644,
1163 .proc_handler = &proc_dointvec,
1164 },
Mel Gorman396faf02007-07-17 04:03:13 -07001165 {
1166 .ctl_name = CTL_UNNUMBERED,
1167 .procname = "hugepages_treat_as_movable",
1168 .data = &hugepages_treat_as_movable,
1169 .maxlen = sizeof(int),
1170 .mode = 0644,
1171 .proc_handler = &hugetlb_treat_movable_handler,
1172 },
Adam Litke54f9f802007-10-16 01:26:20 -07001173 {
1174 .ctl_name = CTL_UNNUMBERED,
Nishanth Aravamudand1c3fb12007-12-17 16:20:12 -08001175 .procname = "nr_overcommit_hugepages",
Andi Kleene5ff2152008-07-23 21:27:42 -07001176 .data = NULL,
1177 .maxlen = sizeof(unsigned long),
Nishanth Aravamudand1c3fb12007-12-17 16:20:12 -08001178 .mode = 0644,
Nishanth Aravamudana3d0c6a2008-02-08 04:18:18 -08001179 .proc_handler = &hugetlb_overcommit_handler,
Andi Kleene5ff2152008-07-23 21:27:42 -07001180 .extra1 = (void *)&hugetlb_zero,
1181 .extra2 = (void *)&hugetlb_infinity,
Nishanth Aravamudand1c3fb12007-12-17 16:20:12 -08001182 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183#endif
1184 {
1185 .ctl_name = VM_LOWMEM_RESERVE_RATIO,
1186 .procname = "lowmem_reserve_ratio",
1187 .data = &sysctl_lowmem_reserve_ratio,
1188 .maxlen = sizeof(sysctl_lowmem_reserve_ratio),
1189 .mode = 0644,
1190 .proc_handler = &lowmem_reserve_ratio_sysctl_handler,
1191 .strategy = &sysctl_intvec,
1192 },
1193 {
Andrew Morton9d0243b2006-01-08 01:00:39 -08001194 .ctl_name = VM_DROP_PAGECACHE,
1195 .procname = "drop_caches",
1196 .data = &sysctl_drop_caches,
1197 .maxlen = sizeof(int),
1198 .mode = 0644,
1199 .proc_handler = drop_caches_sysctl_handler,
1200 .strategy = &sysctl_intvec,
1201 },
1202 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 .ctl_name = VM_MIN_FREE_KBYTES,
1204 .procname = "min_free_kbytes",
1205 .data = &min_free_kbytes,
1206 .maxlen = sizeof(min_free_kbytes),
1207 .mode = 0644,
1208 .proc_handler = &min_free_kbytes_sysctl_handler,
1209 .strategy = &sysctl_intvec,
1210 .extra1 = &zero,
1211 },
Rohit Seth8ad4b1f2006-01-08 01:00:40 -08001212 {
1213 .ctl_name = VM_PERCPU_PAGELIST_FRACTION,
1214 .procname = "percpu_pagelist_fraction",
1215 .data = &percpu_pagelist_fraction,
1216 .maxlen = sizeof(percpu_pagelist_fraction),
1217 .mode = 0644,
1218 .proc_handler = &percpu_pagelist_fraction_sysctl_handler,
1219 .strategy = &sysctl_intvec,
1220 .extra1 = &min_percpu_pagelist_fract,
1221 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222#ifdef CONFIG_MMU
1223 {
1224 .ctl_name = VM_MAX_MAP_COUNT,
1225 .procname = "max_map_count",
1226 .data = &sysctl_max_map_count,
1227 .maxlen = sizeof(sysctl_max_map_count),
1228 .mode = 0644,
1229 .proc_handler = &proc_dointvec
1230 },
Paul Mundtdd8632a2009-01-08 12:04:47 +00001231#else
1232 {
1233 .ctl_name = CTL_UNNUMBERED,
1234 .procname = "nr_trim_pages",
1235 .data = &sysctl_nr_trim_pages,
1236 .maxlen = sizeof(sysctl_nr_trim_pages),
1237 .mode = 0644,
1238 .proc_handler = &proc_dointvec_minmax,
1239 .strategy = &sysctl_intvec,
1240 .extra1 = &zero,
1241 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242#endif
1243 {
1244 .ctl_name = VM_LAPTOP_MODE,
1245 .procname = "laptop_mode",
1246 .data = &laptop_mode,
1247 .maxlen = sizeof(laptop_mode),
1248 .mode = 0644,
Bart Samweled5b43f2006-03-24 03:15:49 -08001249 .proc_handler = &proc_dointvec_jiffies,
1250 .strategy = &sysctl_jiffies,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251 },
1252 {
1253 .ctl_name = VM_BLOCK_DUMP,
1254 .procname = "block_dump",
1255 .data = &block_dump,
1256 .maxlen = sizeof(block_dump),
1257 .mode = 0644,
1258 .proc_handler = &proc_dointvec,
1259 .strategy = &sysctl_intvec,
1260 .extra1 = &zero,
1261 },
1262 {
1263 .ctl_name = VM_VFS_CACHE_PRESSURE,
1264 .procname = "vfs_cache_pressure",
1265 .data = &sysctl_vfs_cache_pressure,
1266 .maxlen = sizeof(sysctl_vfs_cache_pressure),
1267 .mode = 0644,
1268 .proc_handler = &proc_dointvec,
1269 .strategy = &sysctl_intvec,
1270 .extra1 = &zero,
1271 },
1272#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
1273 {
1274 .ctl_name = VM_LEGACY_VA_LAYOUT,
1275 .procname = "legacy_va_layout",
1276 .data = &sysctl_legacy_va_layout,
1277 .maxlen = sizeof(sysctl_legacy_va_layout),
1278 .mode = 0644,
1279 .proc_handler = &proc_dointvec,
1280 .strategy = &sysctl_intvec,
1281 .extra1 = &zero,
1282 },
1283#endif
Christoph Lameter17436602006-01-18 17:42:32 -08001284#ifdef CONFIG_NUMA
1285 {
1286 .ctl_name = VM_ZONE_RECLAIM_MODE,
1287 .procname = "zone_reclaim_mode",
1288 .data = &zone_reclaim_mode,
1289 .maxlen = sizeof(zone_reclaim_mode),
1290 .mode = 0644,
1291 .proc_handler = &proc_dointvec,
Christoph Lameterc84db232006-02-01 03:05:29 -08001292 .strategy = &sysctl_intvec,
1293 .extra1 = &zero,
Christoph Lameter17436602006-01-18 17:42:32 -08001294 },
Christoph Lameter96146342006-07-03 00:24:13 -07001295 {
1296 .ctl_name = VM_MIN_UNMAPPED,
1297 .procname = "min_unmapped_ratio",
1298 .data = &sysctl_min_unmapped_ratio,
1299 .maxlen = sizeof(sysctl_min_unmapped_ratio),
1300 .mode = 0644,
1301 .proc_handler = &sysctl_min_unmapped_ratio_sysctl_handler,
1302 .strategy = &sysctl_intvec,
1303 .extra1 = &zero,
1304 .extra2 = &one_hundred,
1305 },
Christoph Lameter0ff38492006-09-25 23:31:52 -07001306 {
1307 .ctl_name = VM_MIN_SLAB,
1308 .procname = "min_slab_ratio",
1309 .data = &sysctl_min_slab_ratio,
1310 .maxlen = sizeof(sysctl_min_slab_ratio),
1311 .mode = 0644,
1312 .proc_handler = &sysctl_min_slab_ratio_sysctl_handler,
1313 .strategy = &sysctl_intvec,
1314 .extra1 = &zero,
1315 .extra2 = &one_hundred,
1316 },
Christoph Lameter17436602006-01-18 17:42:32 -08001317#endif
Christoph Lameter77461ab2007-05-09 02:35:13 -07001318#ifdef CONFIG_SMP
1319 {
1320 .ctl_name = CTL_UNNUMBERED,
1321 .procname = "stat_interval",
1322 .data = &sysctl_stat_interval,
1323 .maxlen = sizeof(sysctl_stat_interval),
1324 .mode = 0644,
1325 .proc_handler = &proc_dointvec_jiffies,
1326 .strategy = &sysctl_jiffies,
1327 },
1328#endif
Eric Parised032182007-06-28 15:55:21 -04001329 {
1330 .ctl_name = CTL_UNNUMBERED,
1331 .procname = "mmap_min_addr",
Eric Paris788084a2009-07-31 12:54:11 -04001332 .data = &dac_mmap_min_addr,
1333 .maxlen = sizeof(unsigned long),
Eric Parised032182007-06-28 15:55:21 -04001334 .mode = 0644,
Eric Paris788084a2009-07-31 12:54:11 -04001335 .proc_handler = &mmap_min_addr_handler,
Eric Parised032182007-06-28 15:55:21 -04001336 },
KAMEZAWA Hiroyukif0c0b2b2007-07-15 23:38:01 -07001337#ifdef CONFIG_NUMA
1338 {
1339 .ctl_name = CTL_UNNUMBERED,
1340 .procname = "numa_zonelist_order",
1341 .data = &numa_zonelist_order,
1342 .maxlen = NUMA_ZONELIST_ORDER_LEN,
1343 .mode = 0644,
1344 .proc_handler = &numa_zonelist_order_handler,
1345 .strategy = &sysctl_string,
1346 },
1347#endif
Al Viro2b8232c2007-10-13 08:16:04 +01001348#if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \
Paul Mundt5c36e652007-03-01 10:07:42 +09001349 (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
Ingo Molnare6e54942006-06-27 02:53:50 -07001350 {
1351 .ctl_name = VM_VDSO_ENABLED,
1352 .procname = "vdso_enabled",
1353 .data = &vdso_enabled,
1354 .maxlen = sizeof(vdso_enabled),
1355 .mode = 0644,
1356 .proc_handler = &proc_dointvec,
1357 .strategy = &sysctl_intvec,
1358 .extra1 = &zero,
1359 },
1360#endif
Bron Gondwana195cf4532008-02-04 22:29:20 -08001361#ifdef CONFIG_HIGHMEM
1362 {
1363 .ctl_name = CTL_UNNUMBERED,
1364 .procname = "highmem_is_dirtyable",
1365 .data = &vm_highmem_is_dirtyable,
1366 .maxlen = sizeof(vm_highmem_is_dirtyable),
1367 .mode = 0644,
1368 .proc_handler = &proc_dointvec_minmax,
1369 .strategy = &sysctl_intvec,
1370 .extra1 = &zero,
1371 .extra2 = &one,
1372 },
1373#endif
Peter Zijlstra4be6f6b2009-04-13 14:39:33 -07001374 {
1375 .ctl_name = CTL_UNNUMBERED,
1376 .procname = "scan_unevictable_pages",
1377 .data = &scan_unevictable_pages,
1378 .maxlen = sizeof(scan_unevictable_pages),
1379 .mode = 0644,
1380 .proc_handler = &scan_unevictable_handler,
1381 },
Andrew Morton2be7fe02007-07-15 23:41:21 -07001382/*
1383 * NOTE: do not add new entries to this table unless you have read
1384 * Documentation/sysctl/ctl_unnumbered.txt
1385 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 { .ctl_name = 0 }
1387};
1388
Eric W. Biederman2abc26f2007-02-14 00:34:07 -08001389#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001390static struct ctl_table binfmt_misc_table[] = {
Eric W. Biederman2abc26f2007-02-14 00:34:07 -08001391 { .ctl_name = 0 }
1392};
1393#endif
1394
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001395static struct ctl_table fs_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 {
1397 .ctl_name = FS_NRINODE,
1398 .procname = "inode-nr",
1399 .data = &inodes_stat,
1400 .maxlen = 2*sizeof(int),
1401 .mode = 0444,
1402 .proc_handler = &proc_dointvec,
1403 },
1404 {
1405 .ctl_name = FS_STATINODE,
1406 .procname = "inode-state",
1407 .data = &inodes_stat,
1408 .maxlen = 7*sizeof(int),
1409 .mode = 0444,
1410 .proc_handler = &proc_dointvec,
1411 },
1412 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 .procname = "file-nr",
1414 .data = &files_stat,
1415 .maxlen = 3*sizeof(int),
1416 .mode = 0444,
Dipankar Sarma529bf6b2006-03-07 21:55:35 -08001417 .proc_handler = &proc_nr_files,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 },
1419 {
1420 .ctl_name = FS_MAXFILE,
1421 .procname = "file-max",
1422 .data = &files_stat.max_files,
1423 .maxlen = sizeof(int),
1424 .mode = 0644,
1425 .proc_handler = &proc_dointvec,
1426 },
1427 {
Eric Dumazet9cfe0152008-02-06 01:37:16 -08001428 .ctl_name = CTL_UNNUMBERED,
1429 .procname = "nr_open",
1430 .data = &sysctl_nr_open,
1431 .maxlen = sizeof(int),
1432 .mode = 0644,
Al Viroeceea0b2008-05-10 10:08:32 -04001433 .proc_handler = &proc_dointvec_minmax,
1434 .extra1 = &sysctl_nr_open_min,
1435 .extra2 = &sysctl_nr_open_max,
Eric Dumazet9cfe0152008-02-06 01:37:16 -08001436 },
1437 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438 .ctl_name = FS_DENTRY,
1439 .procname = "dentry-state",
1440 .data = &dentry_stat,
1441 .maxlen = 6*sizeof(int),
1442 .mode = 0444,
1443 .proc_handler = &proc_dointvec,
1444 },
1445 {
1446 .ctl_name = FS_OVERFLOWUID,
1447 .procname = "overflowuid",
1448 .data = &fs_overflowuid,
1449 .maxlen = sizeof(int),
1450 .mode = 0644,
1451 .proc_handler = &proc_dointvec_minmax,
1452 .strategy = &sysctl_intvec,
1453 .extra1 = &minolduid,
1454 .extra2 = &maxolduid,
1455 },
1456 {
1457 .ctl_name = FS_OVERFLOWGID,
1458 .procname = "overflowgid",
1459 .data = &fs_overflowgid,
1460 .maxlen = sizeof(int),
1461 .mode = 0644,
1462 .proc_handler = &proc_dointvec_minmax,
1463 .strategy = &sysctl_intvec,
1464 .extra1 = &minolduid,
1465 .extra2 = &maxolduid,
1466 },
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001467#ifdef CONFIG_FILE_LOCKING
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 {
1469 .ctl_name = FS_LEASES,
1470 .procname = "leases-enable",
1471 .data = &leases_enable,
1472 .maxlen = sizeof(int),
1473 .mode = 0644,
1474 .proc_handler = &proc_dointvec,
1475 },
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001476#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477#ifdef CONFIG_DNOTIFY
1478 {
1479 .ctl_name = FS_DIR_NOTIFY,
1480 .procname = "dir-notify-enable",
1481 .data = &dir_notify_enable,
1482 .maxlen = sizeof(int),
1483 .mode = 0644,
1484 .proc_handler = &proc_dointvec,
1485 },
1486#endif
1487#ifdef CONFIG_MMU
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001488#ifdef CONFIG_FILE_LOCKING
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 {
1490 .ctl_name = FS_LEASE_TIME,
1491 .procname = "lease-break-time",
1492 .data = &lease_break_time,
1493 .maxlen = sizeof(int),
1494 .mode = 0644,
Matthew Wilcox8e654fb2009-04-02 16:58:33 -07001495 .proc_handler = &proc_dointvec,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 },
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001497#endif
Thomas Petazzoniebf3f092008-10-15 22:05:12 -07001498#ifdef CONFIG_AIO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500 .procname = "aio-nr",
1501 .data = &aio_nr,
1502 .maxlen = sizeof(aio_nr),
1503 .mode = 0444,
Zach Brownd55b5fd2005-11-07 00:59:31 -08001504 .proc_handler = &proc_doulongvec_minmax,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505 },
1506 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 .procname = "aio-max-nr",
1508 .data = &aio_max_nr,
1509 .maxlen = sizeof(aio_max_nr),
1510 .mode = 0644,
Zach Brownd55b5fd2005-11-07 00:59:31 -08001511 .proc_handler = &proc_doulongvec_minmax,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 },
Thomas Petazzoniebf3f092008-10-15 22:05:12 -07001513#endif /* CONFIG_AIO */
Amy Griffis2d9048e2006-06-01 13:10:59 -07001514#ifdef CONFIG_INOTIFY_USER
Robert Love0399cb02005-07-13 12:38:18 -04001515 {
1516 .ctl_name = FS_INOTIFY,
1517 .procname = "inotify",
1518 .mode = 0555,
1519 .child = inotify_table,
1520 },
1521#endif
Davide Libenzi7ef99642008-12-01 13:13:55 -08001522#ifdef CONFIG_EPOLL
1523 {
1524 .procname = "epoll",
1525 .mode = 0555,
1526 .child = epoll_table,
1527 },
1528#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529#endif
Alan Coxd6e71142005-06-23 00:09:43 -07001530 {
1531 .ctl_name = KERN_SETUID_DUMPABLE,
1532 .procname = "suid_dumpable",
1533 .data = &suid_dumpable,
1534 .maxlen = sizeof(int),
1535 .mode = 0644,
Matthew Wilcox8e654fb2009-04-02 16:58:33 -07001536 .proc_handler = &proc_dointvec_minmax,
1537 .strategy = &sysctl_intvec,
1538 .extra1 = &zero,
1539 .extra2 = &two,
Alan Coxd6e71142005-06-23 00:09:43 -07001540 },
Eric W. Biederman2abc26f2007-02-14 00:34:07 -08001541#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
1542 {
1543 .ctl_name = CTL_UNNUMBERED,
1544 .procname = "binfmt_misc",
1545 .mode = 0555,
1546 .child = binfmt_misc_table,
1547 },
1548#endif
Andrew Morton2be7fe02007-07-15 23:41:21 -07001549/*
1550 * NOTE: do not add new entries to this table unless you have read
1551 * Documentation/sysctl/ctl_unnumbered.txt
1552 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 { .ctl_name = 0 }
1554};
1555
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001556static struct ctl_table debug_table[] = {
Olof Johanssond0c3d532007-10-12 10:20:07 +10001557#if defined(CONFIG_X86) || defined(CONFIG_PPC)
Masoud Asgharifard Sharbianiabd4f752007-07-22 11:12:28 +02001558 {
1559 .ctl_name = CTL_UNNUMBERED,
1560 .procname = "exception-trace",
1561 .data = &show_unhandled_signals,
1562 .maxlen = sizeof(int),
1563 .mode = 0644,
1564 .proc_handler = proc_dointvec
1565 },
1566#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 { .ctl_name = 0 }
1568};
1569
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001570static struct ctl_table dev_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571 { .ctl_name = 0 }
Robert Love0eeca282005-07-12 17:06:03 -04001572};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573
Al Viro330d57f2005-11-04 10:18:40 +00001574static DEFINE_SPINLOCK(sysctl_lock);
1575
1576/* called under sysctl_lock */
1577static int use_table(struct ctl_table_header *p)
1578{
1579 if (unlikely(p->unregistering))
1580 return 0;
1581 p->used++;
1582 return 1;
1583}
1584
1585/* called under sysctl_lock */
1586static void unuse_table(struct ctl_table_header *p)
1587{
1588 if (!--p->used)
1589 if (unlikely(p->unregistering))
1590 complete(p->unregistering);
1591}
1592
1593/* called under sysctl_lock, will reacquire if has to wait */
1594static void start_unregistering(struct ctl_table_header *p)
1595{
1596 /*
1597 * if p->used is 0, nobody will ever touch that entry again;
1598 * we'll eliminate all paths to it before dropping sysctl_lock
1599 */
1600 if (unlikely(p->used)) {
1601 struct completion wait;
1602 init_completion(&wait);
1603 p->unregistering = &wait;
1604 spin_unlock(&sysctl_lock);
1605 wait_for_completion(&wait);
1606 spin_lock(&sysctl_lock);
Al Virof7e6ced2008-07-15 01:44:23 -04001607 } else {
1608 /* anything non-NULL; we'll never dereference it */
1609 p->unregistering = ERR_PTR(-EINVAL);
Al Viro330d57f2005-11-04 10:18:40 +00001610 }
1611 /*
1612 * do not remove from the list until nobody holds it; walking the
1613 * list in do_sysctl() relies on that.
1614 */
1615 list_del_init(&p->ctl_entry);
1616}
1617
Al Virof7e6ced2008-07-15 01:44:23 -04001618void sysctl_head_get(struct ctl_table_header *head)
1619{
1620 spin_lock(&sysctl_lock);
1621 head->count++;
1622 spin_unlock(&sysctl_lock);
1623}
1624
1625void sysctl_head_put(struct ctl_table_header *head)
1626{
1627 spin_lock(&sysctl_lock);
1628 if (!--head->count)
1629 kfree(head);
1630 spin_unlock(&sysctl_lock);
1631}
1632
1633struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
1634{
1635 if (!head)
1636 BUG();
1637 spin_lock(&sysctl_lock);
1638 if (!use_table(head))
1639 head = ERR_PTR(-ENOENT);
1640 spin_unlock(&sysctl_lock);
1641 return head;
1642}
1643
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001644void sysctl_head_finish(struct ctl_table_header *head)
1645{
1646 if (!head)
1647 return;
1648 spin_lock(&sysctl_lock);
1649 unuse_table(head);
1650 spin_unlock(&sysctl_lock);
1651}
1652
Al Viro73455092008-07-14 21:22:20 -04001653static struct ctl_table_set *
1654lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces)
1655{
1656 struct ctl_table_set *set = &root->default_set;
1657 if (root->lookup)
1658 set = root->lookup(root, namespaces);
1659 return set;
1660}
1661
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001662static struct list_head *
1663lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001664{
Al Viro73455092008-07-14 21:22:20 -04001665 struct ctl_table_set *set = lookup_header_set(root, namespaces);
1666 return &set->list;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001667}
1668
1669struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
1670 struct ctl_table_header *prev)
1671{
1672 struct ctl_table_root *root;
1673 struct list_head *header_list;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001674 struct ctl_table_header *head;
1675 struct list_head *tmp;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001676
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001677 spin_lock(&sysctl_lock);
1678 if (prev) {
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001679 head = prev;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001680 tmp = &prev->ctl_entry;
1681 unuse_table(prev);
1682 goto next;
1683 }
1684 tmp = &root_table_header.ctl_entry;
1685 for (;;) {
1686 head = list_entry(tmp, struct ctl_table_header, ctl_entry);
1687
1688 if (!use_table(head))
1689 goto next;
1690 spin_unlock(&sysctl_lock);
1691 return head;
1692 next:
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001693 root = head->root;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001694 tmp = tmp->next;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001695 header_list = lookup_header_list(root, namespaces);
1696 if (tmp != header_list)
1697 continue;
1698
1699 do {
1700 root = list_entry(root->root_list.next,
1701 struct ctl_table_root, root_list);
1702 if (root == &sysctl_table_root)
1703 goto out;
1704 header_list = lookup_header_list(root, namespaces);
1705 } while (list_empty(header_list));
1706 tmp = header_list->next;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001707 }
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001708out:
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001709 spin_unlock(&sysctl_lock);
1710 return NULL;
1711}
1712
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001713struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
1714{
1715 return __sysctl_head_next(current->nsproxy, prev);
1716}
1717
1718void register_sysctl_root(struct ctl_table_root *root)
1719{
1720 spin_lock(&sysctl_lock);
1721 list_add_tail(&root->root_list, &sysctl_table_root.root_list);
1722 spin_unlock(&sysctl_lock);
1723}
1724
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07001725#ifdef CONFIG_SYSCTL_SYSCALL
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001726/* Perform the actual read/write of a sysctl table entry. */
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001727static int do_sysctl_strategy(struct ctl_table_root *root,
1728 struct ctl_table *table,
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001729 void __user *oldval, size_t __user *oldlenp,
1730 void __user *newval, size_t newlen)
1731{
1732 int op = 0, rc;
1733
1734 if (oldval)
Al Viroe6305c42008-07-15 21:03:57 -04001735 op |= MAY_READ;
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001736 if (newval)
Al Viroe6305c42008-07-15 21:03:57 -04001737 op |= MAY_WRITE;
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001738 if (sysctl_perm(root, table, op))
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001739 return -EPERM;
1740
1741 if (table->strategy) {
Alexey Dobriyanf221e722008-10-15 22:04:23 -07001742 rc = table->strategy(table, oldval, oldlenp, newval, newlen);
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001743 if (rc < 0)
1744 return rc;
1745 if (rc > 0)
1746 return 0;
1747 }
1748
1749 /* If there is no strategy routine, or if the strategy returns
1750 * zero, proceed with automatic r/w */
1751 if (table->data && table->maxlen) {
Alexey Dobriyanf221e722008-10-15 22:04:23 -07001752 rc = sysctl_data(table, oldval, oldlenp, newval, newlen);
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001753 if (rc < 0)
1754 return rc;
1755 }
1756 return 0;
1757}
1758
1759static int parse_table(int __user *name, int nlen,
1760 void __user *oldval, size_t __user *oldlenp,
1761 void __user *newval, size_t newlen,
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001762 struct ctl_table_root *root,
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001763 struct ctl_table *table)
1764{
1765 int n;
1766repeat:
1767 if (!nlen)
1768 return -ENOTDIR;
1769 if (get_user(n, name))
1770 return -EFAULT;
1771 for ( ; table->ctl_name || table->procname; table++) {
1772 if (!table->ctl_name)
1773 continue;
1774 if (n == table->ctl_name) {
1775 int error;
1776 if (table->child) {
Al Viroe6305c42008-07-15 21:03:57 -04001777 if (sysctl_perm(root, table, MAY_EXEC))
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001778 return -EPERM;
1779 name++;
1780 nlen--;
1781 table = table->child;
1782 goto repeat;
1783 }
Alexey Dobriyanf221e722008-10-15 22:04:23 -07001784 error = do_sysctl_strategy(root, table,
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001785 oldval, oldlenp,
1786 newval, newlen);
1787 return error;
1788 }
1789 }
1790 return -ENOTDIR;
1791}
1792
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp,
1794 void __user *newval, size_t newlen)
1795{
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001796 struct ctl_table_header *head;
Al Viro330d57f2005-11-04 10:18:40 +00001797 int error = -ENOTDIR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798
1799 if (nlen <= 0 || nlen >= CTL_MAXNAME)
1800 return -ENOTDIR;
1801 if (oldval) {
1802 int old_len;
1803 if (!oldlenp || get_user(old_len, oldlenp))
1804 return -EFAULT;
1805 }
Al Viro330d57f2005-11-04 10:18:40 +00001806
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001807 for (head = sysctl_head_next(NULL); head;
1808 head = sysctl_head_next(head)) {
Al Viro330d57f2005-11-04 10:18:40 +00001809 error = parse_table(name, nlen, oldval, oldlenp,
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001810 newval, newlen,
1811 head->root, head->ctl_table);
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001812 if (error != -ENOTDIR) {
1813 sysctl_head_finish(head);
Al Viro330d57f2005-11-04 10:18:40 +00001814 break;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001815 }
1816 }
Al Viro330d57f2005-11-04 10:18:40 +00001817 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818}
1819
Heiko Carstens1e7bfb22009-01-14 14:14:29 +01001820SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821{
1822 struct __sysctl_args tmp;
1823 int error;
1824
1825 if (copy_from_user(&tmp, args, sizeof(tmp)))
1826 return -EFAULT;
1827
Eric W. Biederman7058cb02007-10-18 03:05:58 -07001828 error = deprecated_sysctl_warning(&tmp);
1829 if (error)
1830 goto out;
1831
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 lock_kernel();
1833 error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
1834 tmp.newval, tmp.newlen);
1835 unlock_kernel();
Eric W. Biederman7058cb02007-10-18 03:05:58 -07001836out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 return error;
1838}
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07001839#endif /* CONFIG_SYSCTL_SYSCALL */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840
1841/*
Eric W. Biederman1ff007e2007-02-14 00:34:11 -08001842 * sysctl_perm does NOT grant the superuser all rights automatically, because
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 * some sysctl variables are readonly even to root.
1844 */
1845
1846static int test_perm(int mode, int op)
1847{
David Howells76aac0e2008-11-14 10:39:12 +11001848 if (!current_euid())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 mode >>= 6;
1850 else if (in_egroup_p(0))
1851 mode >>= 3;
Al Viroe6305c42008-07-15 21:03:57 -04001852 if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 return 0;
1854 return -EACCES;
1855}
1856
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001857int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858{
1859 int error;
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001860 int mode;
1861
Al Viroe6305c42008-07-15 21:03:57 -04001862 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 if (error)
1864 return error;
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001865
1866 if (root->permissions)
1867 mode = root->permissions(root, current->nsproxy, table);
1868 else
1869 mode = table->mode;
1870
1871 return test_perm(mode, op);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872}
1873
Eric W. Biedermand912b0c2007-02-14 00:34:13 -08001874static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
1875{
1876 for (; table->ctl_name || table->procname; table++) {
1877 table->parent = parent;
1878 if (table->child)
1879 sysctl_set_parent(table, table->child);
1880 }
1881}
1882
1883static __init int sysctl_init(void)
1884{
1885 sysctl_set_parent(NULL, root_table);
Holger Schurig88f458e2008-04-29 01:02:36 -07001886#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
1887 {
1888 int err;
1889 err = sysctl_check_table(current->nsproxy, root_table);
1890 }
1891#endif
Eric W. Biedermand912b0c2007-02-14 00:34:13 -08001892 return 0;
1893}
1894
1895core_initcall(sysctl_init);
1896
Al Virobfbcf032008-07-27 06:31:22 +01001897static struct ctl_table *is_branch_in(struct ctl_table *branch,
1898 struct ctl_table *table)
Al Viroae7edec2008-07-15 06:33:31 -04001899{
1900 struct ctl_table *p;
1901 const char *s = branch->procname;
1902
1903 /* branch should have named subdirectory as its first element */
1904 if (!s || !branch->child)
Al Virobfbcf032008-07-27 06:31:22 +01001905 return NULL;
Al Viroae7edec2008-07-15 06:33:31 -04001906
1907 /* ... and nothing else */
1908 if (branch[1].procname || branch[1].ctl_name)
Al Virobfbcf032008-07-27 06:31:22 +01001909 return NULL;
Al Viroae7edec2008-07-15 06:33:31 -04001910
1911 /* table should contain subdirectory with the same name */
1912 for (p = table; p->procname || p->ctl_name; p++) {
1913 if (!p->child)
1914 continue;
1915 if (p->procname && strcmp(p->procname, s) == 0)
Al Virobfbcf032008-07-27 06:31:22 +01001916 return p;
Al Viroae7edec2008-07-15 06:33:31 -04001917 }
Al Virobfbcf032008-07-27 06:31:22 +01001918 return NULL;
Al Viroae7edec2008-07-15 06:33:31 -04001919}
1920
1921/* see if attaching q to p would be an improvement */
1922static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)
1923{
1924 struct ctl_table *to = p->ctl_table, *by = q->ctl_table;
Al Virobfbcf032008-07-27 06:31:22 +01001925 struct ctl_table *next;
Al Viroae7edec2008-07-15 06:33:31 -04001926 int is_better = 0;
1927 int not_in_parent = !p->attached_by;
1928
Al Virobfbcf032008-07-27 06:31:22 +01001929 while ((next = is_branch_in(by, to)) != NULL) {
Al Viroae7edec2008-07-15 06:33:31 -04001930 if (by == q->attached_by)
1931 is_better = 1;
1932 if (to == p->attached_by)
1933 not_in_parent = 1;
1934 by = by->child;
Al Virobfbcf032008-07-27 06:31:22 +01001935 to = next->child;
Al Viroae7edec2008-07-15 06:33:31 -04001936 }
1937
1938 if (is_better && not_in_parent) {
1939 q->attached_by = by;
1940 q->attached_to = to;
1941 q->parent = p;
1942 }
1943}
1944
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945/**
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001946 * __register_sysctl_paths - register a sysctl hierarchy
1947 * @root: List of sysctl headers to register on
1948 * @namespaces: Data to compute which lists of sysctl entries are visible
Eric W. Biederman29e796f2007-11-30 23:50:18 +11001949 * @path: The path to the directory the sysctl table is in.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 * @table: the top-level table structure
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951 *
1952 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
Eric W. Biederman29e796f2007-11-30 23:50:18 +11001953 * array. A completely 0 filled entry terminates the table.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954 *
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001955 * The members of the &struct ctl_table structure are used as follows:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 *
1957 * ctl_name - This is the numeric sysctl value used by sysctl(2). The number
1958 * must be unique within that level of sysctl
1959 *
1960 * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
1961 * enter a sysctl file
1962 *
1963 * data - a pointer to data for use by proc_handler
1964 *
1965 * maxlen - the maximum size in bytes of the data
1966 *
1967 * mode - the file permissions for the /proc/sys file, and for sysctl(2)
1968 *
1969 * child - a pointer to the child sysctl table if this entry is a directory, or
1970 * %NULL.
1971 *
1972 * proc_handler - the text handler routine (described below)
1973 *
1974 * strategy - the strategy routine (described below)
1975 *
1976 * de - for internal use by the sysctl routines
1977 *
1978 * extra1, extra2 - extra pointers usable by the proc handler routines
1979 *
1980 * Leaf nodes in the sysctl tree will be represented by a single file
1981 * under /proc; non-leaf nodes will be represented by directories.
1982 *
1983 * sysctl(2) can automatically manage read and write requests through
1984 * the sysctl table. The data and maxlen fields of the ctl_table
1985 * struct enable minimal validation of the values being written to be
1986 * performed, and the mode field allows minimal authentication.
1987 *
1988 * More sophisticated management can be enabled by the provision of a
1989 * strategy routine with the table entry. This will be called before
1990 * any automatic read or write of the data is performed.
1991 *
1992 * The strategy routine may return
1993 *
1994 * < 0 - Error occurred (error is passed to user process)
1995 *
1996 * 0 - OK - proceed with automatic read or write.
1997 *
1998 * > 0 - OK - read or write has been done by the strategy routine, so
1999 * return immediately.
2000 *
2001 * There must be a proc_handler routine for any terminal nodes
2002 * mirrored under /proc/sys (non-terminals are handled by a built-in
2003 * directory handler). Several default handlers are available to
2004 * cover common cases -
2005 *
2006 * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
2007 * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(),
2008 * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax()
2009 *
2010 * It is the handler's job to read the input buffer from user memory
2011 * and process it. The handler should return 0 on success.
2012 *
2013 * This routine returns %NULL on a failure to register, and a pointer
2014 * to the table header on success.
2015 */
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002016struct ctl_table_header *__register_sysctl_paths(
2017 struct ctl_table_root *root,
2018 struct nsproxy *namespaces,
2019 const struct ctl_path *path, struct ctl_table *table)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020{
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002021 struct ctl_table_header *header;
2022 struct ctl_table *new, **prevp;
2023 unsigned int n, npath;
Al Viroae7edec2008-07-15 06:33:31 -04002024 struct ctl_table_set *set;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002025
2026 /* Count the path components */
2027 for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath)
2028 ;
2029
2030 /*
2031 * For each path component, allocate a 2-element ctl_table array.
2032 * The first array element will be filled with the sysctl entry
2033 * for this, the second will be the sentinel (ctl_name == 0).
2034 *
2035 * We allocate everything in one go so that we don't have to
2036 * worry about freeing additional memory in unregister_sysctl_table.
2037 */
2038 header = kzalloc(sizeof(struct ctl_table_header) +
2039 (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
2040 if (!header)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 return NULL;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002042
2043 new = (struct ctl_table *) (header + 1);
2044
2045 /* Now connect the dots */
2046 prevp = &header->ctl_table;
2047 for (n = 0; n < npath; ++n, ++path) {
2048 /* Copy the procname */
2049 new->procname = path->procname;
2050 new->ctl_name = path->ctl_name;
2051 new->mode = 0555;
2052
2053 *prevp = new;
2054 prevp = &new->child;
2055
2056 new += 2;
2057 }
2058 *prevp = table;
Eric W. Biederman23eb06d2007-11-30 23:52:10 +11002059 header->ctl_table_arg = table;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002060
2061 INIT_LIST_HEAD(&header->ctl_entry);
2062 header->used = 0;
2063 header->unregistering = NULL;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002064 header->root = root;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002065 sysctl_set_parent(NULL, header->ctl_table);
Al Virof7e6ced2008-07-15 01:44:23 -04002066 header->count = 1;
Holger Schurig88f458e2008-04-29 01:02:36 -07002067#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002068 if (sysctl_check_table(namespaces, header->ctl_table)) {
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002069 kfree(header);
Eric W. Biedermanfc6cd252007-10-18 03:05:54 -07002070 return NULL;
2071 }
Holger Schurig88f458e2008-04-29 01:02:36 -07002072#endif
Al Viro330d57f2005-11-04 10:18:40 +00002073 spin_lock(&sysctl_lock);
Al Viro73455092008-07-14 21:22:20 -04002074 header->set = lookup_header_set(root, namespaces);
Al Viroae7edec2008-07-15 06:33:31 -04002075 header->attached_by = header->ctl_table;
2076 header->attached_to = root_table;
2077 header->parent = &root_table_header;
2078 for (set = header->set; set; set = set->parent) {
2079 struct ctl_table_header *p;
2080 list_for_each_entry(p, &set->list, ctl_entry) {
2081 if (p->unregistering)
2082 continue;
2083 try_attach(p, header);
2084 }
2085 }
2086 header->parent->count++;
Al Viro73455092008-07-14 21:22:20 -04002087 list_add_tail(&header->ctl_entry, &header->set->list);
Al Viro330d57f2005-11-04 10:18:40 +00002088 spin_unlock(&sysctl_lock);
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002089
2090 return header;
2091}
2092
2093/**
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002094 * register_sysctl_table_path - register a sysctl table hierarchy
2095 * @path: The path to the directory the sysctl table is in.
2096 * @table: the top-level table structure
2097 *
2098 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
2099 * array. A completely 0 filled entry terminates the table.
2100 *
2101 * See __register_sysctl_paths for more details.
2102 */
2103struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
2104 struct ctl_table *table)
2105{
2106 return __register_sysctl_paths(&sysctl_table_root, current->nsproxy,
2107 path, table);
2108}
2109
2110/**
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002111 * register_sysctl_table - register a sysctl table hierarchy
2112 * @table: the top-level table structure
2113 *
2114 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
2115 * array. A completely 0 filled entry terminates the table.
2116 *
2117 * See register_sysctl_paths for more details.
2118 */
2119struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
2120{
2121 static const struct ctl_path null_path[] = { {} };
2122
2123 return register_sysctl_paths(null_path, table);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124}
2125
2126/**
2127 * unregister_sysctl_table - unregister a sysctl table hierarchy
2128 * @header: the header returned from register_sysctl_table
2129 *
2130 * Unregisters the sysctl table and all children. proc entries may not
2131 * actually be removed until they are no longer used by anyone.
2132 */
2133void unregister_sysctl_table(struct ctl_table_header * header)
2134{
Al Viro330d57f2005-11-04 10:18:40 +00002135 might_sleep();
Pavel Emelyanovf1dad162007-12-04 23:45:24 -08002136
2137 if (header == NULL)
2138 return;
2139
Al Viro330d57f2005-11-04 10:18:40 +00002140 spin_lock(&sysctl_lock);
2141 start_unregistering(header);
Al Viroae7edec2008-07-15 06:33:31 -04002142 if (!--header->parent->count) {
2143 WARN_ON(1);
2144 kfree(header->parent);
2145 }
Al Virof7e6ced2008-07-15 01:44:23 -04002146 if (!--header->count)
2147 kfree(header);
Al Viro330d57f2005-11-04 10:18:40 +00002148 spin_unlock(&sysctl_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002149}
2150
Al Viro9043476f2008-07-15 08:54:06 -04002151int sysctl_is_seen(struct ctl_table_header *p)
2152{
2153 struct ctl_table_set *set = p->set;
2154 int res;
2155 spin_lock(&sysctl_lock);
2156 if (p->unregistering)
2157 res = 0;
2158 else if (!set->is_seen)
2159 res = 1;
2160 else
2161 res = set->is_seen(set);
2162 spin_unlock(&sysctl_lock);
2163 return res;
2164}
2165
Al Viro73455092008-07-14 21:22:20 -04002166void setup_sysctl_set(struct ctl_table_set *p,
2167 struct ctl_table_set *parent,
2168 int (*is_seen)(struct ctl_table_set *))
2169{
2170 INIT_LIST_HEAD(&p->list);
2171 p->parent = parent ? parent : &sysctl_table_root.default_set;
2172 p->is_seen = is_seen;
2173}
2174
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002175#else /* !CONFIG_SYSCTL */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002176struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002177{
2178 return NULL;
2179}
2180
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002181struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
2182 struct ctl_table *table)
2183{
2184 return NULL;
2185}
2186
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002187void unregister_sysctl_table(struct ctl_table_header * table)
2188{
2189}
2190
Al Viro73455092008-07-14 21:22:20 -04002191void setup_sysctl_set(struct ctl_table_set *p,
2192 struct ctl_table_set *parent,
2193 int (*is_seen)(struct ctl_table_set *))
2194{
2195}
2196
Al Virof7e6ced2008-07-15 01:44:23 -04002197void sysctl_head_put(struct ctl_table_header *head)
2198{
2199}
2200
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002201#endif /* CONFIG_SYSCTL */
2202
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203/*
2204 * /proc/sys support
2205 */
2206
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002207#ifdef CONFIG_PROC_SYSCTL
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208
Adrian Bunkb1ba4dd2006-10-02 02:18:05 -07002209static int _proc_do_string(void* data, int maxlen, int write,
2210 struct file *filp, void __user *buffer,
2211 size_t *lenp, loff_t *ppos)
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002212{
2213 size_t len;
2214 char __user *p;
2215 char c;
Oleg Nesterov8d060872007-02-10 01:46:38 -08002216
2217 if (!data || !maxlen || !*lenp) {
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002218 *lenp = 0;
2219 return 0;
2220 }
Oleg Nesterov8d060872007-02-10 01:46:38 -08002221
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002222 if (write) {
2223 len = 0;
2224 p = buffer;
2225 while (len < *lenp) {
2226 if (get_user(c, p++))
2227 return -EFAULT;
2228 if (c == 0 || c == '\n')
2229 break;
2230 len++;
2231 }
2232 if (len >= maxlen)
2233 len = maxlen-1;
2234 if(copy_from_user(data, buffer, len))
2235 return -EFAULT;
2236 ((char *) data)[len] = 0;
2237 *ppos += *lenp;
2238 } else {
2239 len = strlen(data);
2240 if (len > maxlen)
2241 len = maxlen;
Oleg Nesterov8d060872007-02-10 01:46:38 -08002242
2243 if (*ppos > len) {
2244 *lenp = 0;
2245 return 0;
2246 }
2247
2248 data += *ppos;
2249 len -= *ppos;
2250
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002251 if (len > *lenp)
2252 len = *lenp;
2253 if (len)
2254 if(copy_to_user(buffer, data, len))
2255 return -EFAULT;
2256 if (len < *lenp) {
2257 if(put_user('\n', ((char __user *) buffer) + len))
2258 return -EFAULT;
2259 len++;
2260 }
2261 *lenp = len;
2262 *ppos += len;
2263 }
2264 return 0;
2265}
2266
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267/**
2268 * proc_dostring - read a string sysctl
2269 * @table: the sysctl table
2270 * @write: %TRUE if this is a write to the sysctl file
2271 * @filp: the file structure
2272 * @buffer: the user buffer
2273 * @lenp: the size of the user buffer
2274 * @ppos: file position
2275 *
2276 * Reads/writes a string from/to the user buffer. If the kernel
2277 * buffer provided is not large enough to hold the string, the
2278 * string is truncated. The copied string is %NULL-terminated.
2279 * If the string is being read by the user process, it is copied
2280 * and a newline '\n' is added. It is truncated if the buffer is
2281 * not large enough.
2282 *
2283 * Returns 0 on success.
2284 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002285int proc_dostring(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286 void __user *buffer, size_t *lenp, loff_t *ppos)
2287{
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002288 return _proc_do_string(table->data, table->maxlen, write, filp,
2289 buffer, lenp, ppos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290}
2291
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292
2293static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
2294 int *valp,
2295 int write, void *data)
2296{
2297 if (write) {
2298 *valp = *negp ? -*lvalp : *lvalp;
2299 } else {
2300 int val = *valp;
2301 if (val < 0) {
2302 *negp = -1;
2303 *lvalp = (unsigned long)-val;
2304 } else {
2305 *negp = 0;
2306 *lvalp = (unsigned long)val;
2307 }
2308 }
2309 return 0;
2310}
2311
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002312static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002313 int write, struct file *filp, void __user *buffer,
2314 size_t *lenp, loff_t *ppos,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315 int (*conv)(int *negp, unsigned long *lvalp, int *valp,
2316 int write, void *data),
2317 void *data)
2318{
2319#define TMPBUFLEN 21
Sukanto Ghosh7338f292009-06-17 16:27:50 -07002320 int *i, vleft, first = 1, neg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321 unsigned long lval;
2322 size_t left, len;
2323
2324 char buf[TMPBUFLEN], *p;
2325 char __user *s = buffer;
2326
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002327 if (!tbl_data || !table->maxlen || !*lenp ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328 (*ppos && !write)) {
2329 *lenp = 0;
2330 return 0;
2331 }
2332
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002333 i = (int *) tbl_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002334 vleft = table->maxlen / sizeof(*i);
2335 left = *lenp;
2336
2337 if (!conv)
2338 conv = do_proc_dointvec_conv;
2339
2340 for (; left && vleft--; i++, first=0) {
2341 if (write) {
2342 while (left) {
2343 char c;
2344 if (get_user(c, s))
2345 return -EFAULT;
2346 if (!isspace(c))
2347 break;
2348 left--;
2349 s++;
2350 }
2351 if (!left)
2352 break;
2353 neg = 0;
2354 len = left;
2355 if (len > sizeof(buf) - 1)
2356 len = sizeof(buf) - 1;
2357 if (copy_from_user(buf, s, len))
2358 return -EFAULT;
2359 buf[len] = 0;
2360 p = buf;
2361 if (*p == '-' && left > 1) {
2362 neg = 1;
BP, Praveenbd9b0ba2006-12-06 20:39:09 -08002363 p++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364 }
2365 if (*p < '0' || *p > '9')
2366 break;
2367
2368 lval = simple_strtoul(p, &p, 0);
2369
2370 len = p-buf;
2371 if ((len < left) && *p && !isspace(*p))
2372 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002373 s += len;
2374 left -= len;
2375
2376 if (conv(&neg, &lval, i, 1, data))
2377 break;
2378 } else {
2379 p = buf;
2380 if (!first)
2381 *p++ = '\t';
2382
2383 if (conv(&neg, &lval, i, 0, data))
2384 break;
2385
2386 sprintf(p, "%s%lu", neg ? "-" : "", lval);
2387 len = strlen(buf);
2388 if (len > left)
2389 len = left;
2390 if(copy_to_user(s, buf, len))
2391 return -EFAULT;
2392 left -= len;
2393 s += len;
2394 }
2395 }
2396
2397 if (!write && !first && left) {
2398 if(put_user('\n', s))
2399 return -EFAULT;
2400 left--, s++;
2401 }
2402 if (write) {
2403 while (left) {
2404 char c;
2405 if (get_user(c, s++))
2406 return -EFAULT;
2407 if (!isspace(c))
2408 break;
2409 left--;
2410 }
2411 }
2412 if (write && first)
2413 return -EINVAL;
2414 *lenp -= left;
2415 *ppos += *lenp;
2416 return 0;
2417#undef TMPBUFLEN
2418}
2419
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002420static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp,
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002421 void __user *buffer, size_t *lenp, loff_t *ppos,
2422 int (*conv)(int *negp, unsigned long *lvalp, int *valp,
2423 int write, void *data),
2424 void *data)
2425{
2426 return __do_proc_dointvec(table->data, table, write, filp,
2427 buffer, lenp, ppos, conv, data);
2428}
2429
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430/**
2431 * proc_dointvec - read a vector of integers
2432 * @table: the sysctl table
2433 * @write: %TRUE if this is a write to the sysctl file
2434 * @filp: the file structure
2435 * @buffer: the user buffer
2436 * @lenp: the size of the user buffer
2437 * @ppos: file position
2438 *
2439 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2440 * values from/to the user buffer, treated as an ASCII string.
2441 *
2442 * Returns 0 on success.
2443 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002444int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445 void __user *buffer, size_t *lenp, loff_t *ppos)
2446{
2447 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
2448 NULL,NULL);
2449}
2450
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002451/*
Andi Kleen25ddbb12008-10-15 22:01:41 -07002452 * Taint values can only be increased
2453 * This means we can safely use a temporary.
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002454 */
Andi Kleen25ddbb12008-10-15 22:01:41 -07002455static int proc_taint(struct ctl_table *table, int write, struct file *filp,
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002456 void __user *buffer, size_t *lenp, loff_t *ppos)
2457{
Andi Kleen25ddbb12008-10-15 22:01:41 -07002458 struct ctl_table t;
2459 unsigned long tmptaint = get_taint();
2460 int err;
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002461
Bastian Blank91fcd412007-04-23 14:41:14 -07002462 if (write && !capable(CAP_SYS_ADMIN))
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002463 return -EPERM;
2464
Andi Kleen25ddbb12008-10-15 22:01:41 -07002465 t = *table;
2466 t.data = &tmptaint;
2467 err = proc_doulongvec_minmax(&t, write, filp, buffer, lenp, ppos);
2468 if (err < 0)
2469 return err;
2470
2471 if (write) {
2472 /*
2473 * Poor man's atomic or. Not worth adding a primitive
2474 * to everyone's atomic.h for this
2475 */
2476 int i;
2477 for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
2478 if ((tmptaint >> i) & 1)
2479 add_taint(i);
2480 }
2481 }
2482
2483 return err;
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002484}
2485
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486struct do_proc_dointvec_minmax_conv_param {
2487 int *min;
2488 int *max;
2489};
2490
2491static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,
2492 int *valp,
2493 int write, void *data)
2494{
2495 struct do_proc_dointvec_minmax_conv_param *param = data;
2496 if (write) {
2497 int val = *negp ? -*lvalp : *lvalp;
2498 if ((param->min && *param->min > val) ||
2499 (param->max && *param->max < val))
2500 return -EINVAL;
2501 *valp = val;
2502 } else {
2503 int val = *valp;
2504 if (val < 0) {
2505 *negp = -1;
2506 *lvalp = (unsigned long)-val;
2507 } else {
2508 *negp = 0;
2509 *lvalp = (unsigned long)val;
2510 }
2511 }
2512 return 0;
2513}
2514
2515/**
2516 * proc_dointvec_minmax - read a vector of integers with min/max values
2517 * @table: the sysctl table
2518 * @write: %TRUE if this is a write to the sysctl file
2519 * @filp: the file structure
2520 * @buffer: the user buffer
2521 * @lenp: the size of the user buffer
2522 * @ppos: file position
2523 *
2524 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2525 * values from/to the user buffer, treated as an ASCII string.
2526 *
2527 * This routine will ensure the values are within the range specified by
2528 * table->extra1 (min) and table->extra2 (max).
2529 *
2530 * Returns 0 on success.
2531 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002532int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002533 void __user *buffer, size_t *lenp, loff_t *ppos)
2534{
2535 struct do_proc_dointvec_minmax_conv_param param = {
2536 .min = (int *) table->extra1,
2537 .max = (int *) table->extra2,
2538 };
2539 return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
2540 do_proc_dointvec_minmax_conv, &param);
2541}
2542
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002543static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 struct file *filp,
2545 void __user *buffer,
2546 size_t *lenp, loff_t *ppos,
2547 unsigned long convmul,
2548 unsigned long convdiv)
2549{
2550#define TMPBUFLEN 21
2551 unsigned long *i, *min, *max, val;
2552 int vleft, first=1, neg;
2553 size_t len, left;
2554 char buf[TMPBUFLEN], *p;
2555 char __user *s = buffer;
2556
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002557 if (!data || !table->maxlen || !*lenp ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558 (*ppos && !write)) {
2559 *lenp = 0;
2560 return 0;
2561 }
2562
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002563 i = (unsigned long *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 min = (unsigned long *) table->extra1;
2565 max = (unsigned long *) table->extra2;
2566 vleft = table->maxlen / sizeof(unsigned long);
2567 left = *lenp;
2568
2569 for (; left && vleft--; i++, min++, max++, first=0) {
2570 if (write) {
2571 while (left) {
2572 char c;
2573 if (get_user(c, s))
2574 return -EFAULT;
2575 if (!isspace(c))
2576 break;
2577 left--;
2578 s++;
2579 }
2580 if (!left)
2581 break;
2582 neg = 0;
2583 len = left;
2584 if (len > TMPBUFLEN-1)
2585 len = TMPBUFLEN-1;
2586 if (copy_from_user(buf, s, len))
2587 return -EFAULT;
2588 buf[len] = 0;
2589 p = buf;
2590 if (*p == '-' && left > 1) {
2591 neg = 1;
BP, Praveenbd9b0ba2006-12-06 20:39:09 -08002592 p++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593 }
2594 if (*p < '0' || *p > '9')
2595 break;
2596 val = simple_strtoul(p, &p, 0) * convmul / convdiv ;
2597 len = p-buf;
2598 if ((len < left) && *p && !isspace(*p))
2599 break;
2600 if (neg)
2601 val = -val;
2602 s += len;
2603 left -= len;
2604
2605 if(neg)
2606 continue;
2607 if ((min && val < *min) || (max && val > *max))
2608 continue;
2609 *i = val;
2610 } else {
2611 p = buf;
2612 if (!first)
2613 *p++ = '\t';
2614 sprintf(p, "%lu", convdiv * (*i) / convmul);
2615 len = strlen(buf);
2616 if (len > left)
2617 len = left;
2618 if(copy_to_user(s, buf, len))
2619 return -EFAULT;
2620 left -= len;
2621 s += len;
2622 }
2623 }
2624
2625 if (!write && !first && left) {
2626 if(put_user('\n', s))
2627 return -EFAULT;
2628 left--, s++;
2629 }
2630 if (write) {
2631 while (left) {
2632 char c;
2633 if (get_user(c, s++))
2634 return -EFAULT;
2635 if (!isspace(c))
2636 break;
2637 left--;
2638 }
2639 }
2640 if (write && first)
2641 return -EINVAL;
2642 *lenp -= left;
2643 *ppos += *lenp;
2644 return 0;
2645#undef TMPBUFLEN
2646}
2647
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002648static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002649 struct file *filp,
2650 void __user *buffer,
2651 size_t *lenp, loff_t *ppos,
2652 unsigned long convmul,
2653 unsigned long convdiv)
2654{
2655 return __do_proc_doulongvec_minmax(table->data, table, write,
2656 filp, buffer, lenp, ppos, convmul, convdiv);
2657}
2658
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659/**
2660 * proc_doulongvec_minmax - read a vector of long integers with min/max values
2661 * @table: the sysctl table
2662 * @write: %TRUE if this is a write to the sysctl file
2663 * @filp: the file structure
2664 * @buffer: the user buffer
2665 * @lenp: the size of the user buffer
2666 * @ppos: file position
2667 *
2668 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
2669 * values from/to the user buffer, treated as an ASCII string.
2670 *
2671 * This routine will ensure the values are within the range specified by
2672 * table->extra1 (min) and table->extra2 (max).
2673 *
2674 * Returns 0 on success.
2675 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002676int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002677 void __user *buffer, size_t *lenp, loff_t *ppos)
2678{
2679 return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l);
2680}
2681
2682/**
2683 * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
2684 * @table: the sysctl table
2685 * @write: %TRUE if this is a write to the sysctl file
2686 * @filp: the file structure
2687 * @buffer: the user buffer
2688 * @lenp: the size of the user buffer
2689 * @ppos: file position
2690 *
2691 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
2692 * values from/to the user buffer, treated as an ASCII string. The values
2693 * are treated as milliseconds, and converted to jiffies when they are stored.
2694 *
2695 * This routine will ensure the values are within the range specified by
2696 * table->extra1 (min) and table->extra2 (max).
2697 *
2698 * Returns 0 on success.
2699 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002700int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701 struct file *filp,
2702 void __user *buffer,
2703 size_t *lenp, loff_t *ppos)
2704{
2705 return do_proc_doulongvec_minmax(table, write, filp, buffer,
2706 lenp, ppos, HZ, 1000l);
2707}
2708
2709
2710static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp,
2711 int *valp,
2712 int write, void *data)
2713{
2714 if (write) {
Bart Samwelcba9f332006-03-24 03:15:50 -08002715 if (*lvalp > LONG_MAX / HZ)
2716 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717 *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ);
2718 } else {
2719 int val = *valp;
2720 unsigned long lval;
2721 if (val < 0) {
2722 *negp = -1;
2723 lval = (unsigned long)-val;
2724 } else {
2725 *negp = 0;
2726 lval = (unsigned long)val;
2727 }
2728 *lvalp = lval / HZ;
2729 }
2730 return 0;
2731}
2732
2733static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp,
2734 int *valp,
2735 int write, void *data)
2736{
2737 if (write) {
Bart Samwelcba9f332006-03-24 03:15:50 -08002738 if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ)
2739 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740 *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp);
2741 } else {
2742 int val = *valp;
2743 unsigned long lval;
2744 if (val < 0) {
2745 *negp = -1;
2746 lval = (unsigned long)-val;
2747 } else {
2748 *negp = 0;
2749 lval = (unsigned long)val;
2750 }
2751 *lvalp = jiffies_to_clock_t(lval);
2752 }
2753 return 0;
2754}
2755
2756static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,
2757 int *valp,
2758 int write, void *data)
2759{
2760 if (write) {
2761 *valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp);
2762 } else {
2763 int val = *valp;
2764 unsigned long lval;
2765 if (val < 0) {
2766 *negp = -1;
2767 lval = (unsigned long)-val;
2768 } else {
2769 *negp = 0;
2770 lval = (unsigned long)val;
2771 }
2772 *lvalp = jiffies_to_msecs(lval);
2773 }
2774 return 0;
2775}
2776
2777/**
2778 * proc_dointvec_jiffies - read a vector of integers as seconds
2779 * @table: the sysctl table
2780 * @write: %TRUE if this is a write to the sysctl file
2781 * @filp: the file structure
2782 * @buffer: the user buffer
2783 * @lenp: the size of the user buffer
2784 * @ppos: file position
2785 *
2786 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2787 * values from/to the user buffer, treated as an ASCII string.
2788 * The values read are assumed to be in seconds, and are converted into
2789 * jiffies.
2790 *
2791 * Returns 0 on success.
2792 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002793int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002794 void __user *buffer, size_t *lenp, loff_t *ppos)
2795{
2796 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
2797 do_proc_dointvec_jiffies_conv,NULL);
2798}
2799
2800/**
2801 * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
2802 * @table: the sysctl table
2803 * @write: %TRUE if this is a write to the sysctl file
2804 * @filp: the file structure
2805 * @buffer: the user buffer
2806 * @lenp: the size of the user buffer
Randy Dunlap1e5d5332005-11-07 01:01:06 -08002807 * @ppos: pointer to the file position
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808 *
2809 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2810 * values from/to the user buffer, treated as an ASCII string.
2811 * The values read are assumed to be in 1/USER_HZ seconds, and
2812 * are converted into jiffies.
2813 *
2814 * Returns 0 on success.
2815 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002816int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 void __user *buffer, size_t *lenp, loff_t *ppos)
2818{
2819 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
2820 do_proc_dointvec_userhz_jiffies_conv,NULL);
2821}
2822
2823/**
2824 * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds
2825 * @table: the sysctl table
2826 * @write: %TRUE if this is a write to the sysctl file
2827 * @filp: the file structure
2828 * @buffer: the user buffer
2829 * @lenp: the size of the user buffer
Martin Waitz67be2dd2005-05-01 08:59:26 -07002830 * @ppos: file position
2831 * @ppos: the current position in the file
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832 *
2833 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2834 * values from/to the user buffer, treated as an ASCII string.
2835 * The values read are assumed to be in 1/1000 seconds, and
2836 * are converted into jiffies.
2837 *
2838 * Returns 0 on success.
2839 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002840int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841 void __user *buffer, size_t *lenp, loff_t *ppos)
2842{
2843 return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
2844 do_proc_dointvec_ms_jiffies_conv, NULL);
2845}
2846
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002847static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
Cedric Le Goater9ec52092006-10-02 02:19:00 -07002848 void __user *buffer, size_t *lenp, loff_t *ppos)
2849{
2850 struct pid *new_pid;
2851 pid_t tmp;
2852 int r;
2853
Pavel Emelyanov6c5f3e72008-02-08 04:19:20 -08002854 tmp = pid_vnr(cad_pid);
Cedric Le Goater9ec52092006-10-02 02:19:00 -07002855
2856 r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
2857 lenp, ppos, NULL, NULL);
2858 if (r || !write)
2859 return r;
2860
2861 new_pid = find_get_pid(tmp);
2862 if (!new_pid)
2863 return -ESRCH;
2864
2865 put_pid(xchg(&cad_pid, new_pid));
2866 return 0;
2867}
2868
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869#else /* CONFIG_PROC_FS */
2870
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002871int proc_dostring(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872 void __user *buffer, size_t *lenp, loff_t *ppos)
2873{
2874 return -ENOSYS;
2875}
2876
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002877int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878 void __user *buffer, size_t *lenp, loff_t *ppos)
2879{
2880 return -ENOSYS;
2881}
2882
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002883int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884 void __user *buffer, size_t *lenp, loff_t *ppos)
2885{
2886 return -ENOSYS;
2887}
2888
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002889int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890 void __user *buffer, size_t *lenp, loff_t *ppos)
2891{
2892 return -ENOSYS;
2893}
2894
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002895int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896 void __user *buffer, size_t *lenp, loff_t *ppos)
2897{
2898 return -ENOSYS;
2899}
2900
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002901int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902 void __user *buffer, size_t *lenp, loff_t *ppos)
2903{
2904 return -ENOSYS;
2905}
2906
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002907int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908 void __user *buffer, size_t *lenp, loff_t *ppos)
2909{
2910 return -ENOSYS;
2911}
2912
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002913int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914 struct file *filp,
2915 void __user *buffer,
2916 size_t *lenp, loff_t *ppos)
2917{
2918 return -ENOSYS;
2919}
2920
2921
2922#endif /* CONFIG_PROC_FS */
2923
2924
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002925#ifdef CONFIG_SYSCTL_SYSCALL
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926/*
2927 * General sysctl support routines
2928 */
2929
Eric W. Biederman49a0c452007-10-18 03:05:23 -07002930/* The generic sysctl data routine (used if no strategy routine supplied) */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07002931int sysctl_data(struct ctl_table *table,
Eric W. Biederman49a0c452007-10-18 03:05:23 -07002932 void __user *oldval, size_t __user *oldlenp,
2933 void __user *newval, size_t newlen)
2934{
2935 size_t len;
2936
2937 /* Get out of I don't have a variable */
2938 if (!table->data || !table->maxlen)
2939 return -ENOTDIR;
2940
2941 if (oldval && oldlenp) {
2942 if (get_user(len, oldlenp))
2943 return -EFAULT;
2944 if (len) {
2945 if (len > table->maxlen)
2946 len = table->maxlen;
2947 if (copy_to_user(oldval, table->data, len))
2948 return -EFAULT;
2949 if (put_user(len, oldlenp))
2950 return -EFAULT;
2951 }
2952 }
2953
2954 if (newval && newlen) {
2955 if (newlen > table->maxlen)
2956 newlen = table->maxlen;
2957
2958 if (copy_from_user(table->data, newval, newlen))
2959 return -EFAULT;
2960 }
2961 return 1;
2962}
2963
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964/* The generic string strategy routine: */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07002965int sysctl_string(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08002967 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969 if (!table->data || !table->maxlen)
2970 return -ENOTDIR;
2971
2972 if (oldval && oldlenp) {
Linus Torvaldsde9e0072005-12-31 17:00:29 -08002973 size_t bufsize;
2974 if (get_user(bufsize, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975 return -EFAULT;
Linus Torvaldsde9e0072005-12-31 17:00:29 -08002976 if (bufsize) {
2977 size_t len = strlen(table->data), copied;
2978
2979 /* This shouldn't trigger for a well-formed sysctl */
2980 if (len > table->maxlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981 len = table->maxlen;
Linus Torvaldsde9e0072005-12-31 17:00:29 -08002982
2983 /* Copy up to a max of bufsize-1 bytes of the string */
2984 copied = (len >= bufsize) ? bufsize - 1 : len;
2985
2986 if (copy_to_user(oldval, table->data, copied) ||
2987 put_user(0, (char __user *)(oldval + copied)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988 return -EFAULT;
Linus Torvaldsde9e0072005-12-31 17:00:29 -08002989 if (put_user(len, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990 return -EFAULT;
2991 }
2992 }
2993 if (newval && newlen) {
Linus Torvaldsde9e0072005-12-31 17:00:29 -08002994 size_t len = newlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995 if (len > table->maxlen)
2996 len = table->maxlen;
2997 if(copy_from_user(table->data, newval, len))
2998 return -EFAULT;
2999 if (len == table->maxlen)
3000 len--;
3001 ((char *) table->data)[len] = 0;
3002 }
Yi Yang82c9df82005-12-30 16:37:10 +08003003 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004}
3005
3006/*
3007 * This function makes sure that all of the integers in the vector
3008 * are between the minimum and maximum values given in the arrays
3009 * table->extra1 and table->extra2, respectively.
3010 */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003011int sysctl_intvec(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003013 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003014{
3015
3016 if (newval && newlen) {
3017 int __user *vec = (int __user *) newval;
3018 int *min = (int *) table->extra1;
3019 int *max = (int *) table->extra2;
3020 size_t length;
3021 int i;
3022
3023 if (newlen % sizeof(int) != 0)
3024 return -EINVAL;
3025
3026 if (!table->extra1 && !table->extra2)
3027 return 0;
3028
3029 if (newlen > table->maxlen)
3030 newlen = table->maxlen;
3031 length = newlen / sizeof(int);
3032
3033 for (i = 0; i < length; i++) {
3034 int value;
3035 if (get_user(value, vec + i))
3036 return -EFAULT;
3037 if (min && value < min[i])
3038 return -EINVAL;
3039 if (max && value > max[i])
3040 return -EINVAL;
3041 }
3042 }
3043 return 0;
3044}
3045
3046/* Strategy function to convert jiffies to seconds */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003047int sysctl_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003048 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003049 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003050{
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003051 if (oldval && oldlenp) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003052 size_t olen;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003053
3054 if (get_user(olen, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055 return -EFAULT;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003056 if (olen) {
3057 int val;
3058
3059 if (olen < sizeof(int))
3060 return -EINVAL;
3061
3062 val = *(int *)(table->data) / HZ;
3063 if (put_user(val, (int __user *)oldval))
3064 return -EFAULT;
3065 if (put_user(sizeof(int), oldlenp))
3066 return -EFAULT;
3067 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068 }
3069 if (newval && newlen) {
3070 int new;
3071 if (newlen != sizeof(int))
3072 return -EINVAL;
3073 if (get_user(new, (int __user *)newval))
3074 return -EFAULT;
3075 *(int *)(table->data) = new*HZ;
3076 }
3077 return 1;
3078}
3079
3080/* Strategy function to convert jiffies to seconds */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003081int sysctl_ms_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003083 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003084{
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003085 if (oldval && oldlenp) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003086 size_t olen;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003087
3088 if (get_user(olen, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003089 return -EFAULT;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003090 if (olen) {
3091 int val;
3092
3093 if (olen < sizeof(int))
3094 return -EINVAL;
3095
3096 val = jiffies_to_msecs(*(int *)(table->data));
3097 if (put_user(val, (int __user *)oldval))
3098 return -EFAULT;
3099 if (put_user(sizeof(int), oldlenp))
3100 return -EFAULT;
3101 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003102 }
3103 if (newval && newlen) {
3104 int new;
3105 if (newlen != sizeof(int))
3106 return -EINVAL;
3107 if (get_user(new, (int __user *)newval))
3108 return -EFAULT;
3109 *(int *)(table->data) = msecs_to_jiffies(new);
3110 }
3111 return 1;
3112}
3113
Eric W. Biedermanc4b8b762006-12-08 02:39:55 -08003114
Eric W. Biedermanc4b8b762006-12-08 02:39:55 -08003115
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07003116#else /* CONFIG_SYSCTL_SYSCALL */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003117
3118
Heiko Carstens1e7bfb22009-01-14 14:14:29 +01003119SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120{
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003121 struct __sysctl_args tmp;
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003122 int error;
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003123
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003124 if (copy_from_user(&tmp, args, sizeof(tmp)))
3125 return -EFAULT;
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003126
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003127 error = deprecated_sysctl_warning(&tmp);
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07003128
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003129 /* If no error reading the parameters then just -ENOSYS ... */
3130 if (!error)
3131 error = -ENOSYS;
3132
3133 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134}
3135
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003136int sysctl_data(struct ctl_table *table,
Eric W. Biederman49a0c452007-10-18 03:05:23 -07003137 void __user *oldval, size_t __user *oldlenp,
3138 void __user *newval, size_t newlen)
3139{
3140 return -ENOSYS;
3141}
3142
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003143int sysctl_string(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003145 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146{
3147 return -ENOSYS;
3148}
3149
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003150int sysctl_intvec(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003152 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153{
3154 return -ENOSYS;
3155}
3156
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003157int sysctl_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003158 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003159 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160{
3161 return -ENOSYS;
3162}
3163
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003164int sysctl_ms_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003166 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167{
3168 return -ENOSYS;
3169}
3170
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07003171#endif /* CONFIG_SYSCTL_SYSCALL */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003173static int deprecated_sysctl_warning(struct __sysctl_args *args)
3174{
3175 static int msg_count;
3176 int name[CTL_MAXNAME];
3177 int i;
3178
Tetsuo Handa6fc48af2007-11-14 16:58:38 -08003179 /* Check args->nlen. */
3180 if (args->nlen < 0 || args->nlen > CTL_MAXNAME)
3181 return -ENOTDIR;
3182
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003183 /* Read in the sysctl name for better debug message logging */
3184 for (i = 0; i < args->nlen; i++)
3185 if (get_user(name[i], args->name + i))
3186 return -EFAULT;
3187
3188 /* Ignore accesses to kernel.version */
3189 if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
3190 return 0;
3191
3192 if (msg_count < 5) {
3193 msg_count++;
3194 printk(KERN_INFO
3195 "warning: process `%s' used the deprecated sysctl "
3196 "system call with ", current->comm);
3197 for (i = 0; i < args->nlen; i++)
3198 printk("%d.", name[i]);
3199 printk("\n");
3200 }
3201 return 0;
3202}
3203
Linus Torvalds1da177e2005-04-16 15:20:36 -07003204/*
3205 * No sense putting this after each symbol definition, twice,
3206 * exception granted :-)
3207 */
3208EXPORT_SYMBOL(proc_dointvec);
3209EXPORT_SYMBOL(proc_dointvec_jiffies);
3210EXPORT_SYMBOL(proc_dointvec_minmax);
3211EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
3212EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
3213EXPORT_SYMBOL(proc_dostring);
3214EXPORT_SYMBOL(proc_doulongvec_minmax);
3215EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
3216EXPORT_SYMBOL(register_sysctl_table);
Eric W. Biederman29e796f2007-11-30 23:50:18 +11003217EXPORT_SYMBOL(register_sysctl_paths);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003218EXPORT_SYMBOL(sysctl_intvec);
3219EXPORT_SYMBOL(sysctl_jiffies);
3220EXPORT_SYMBOL(sysctl_ms_jiffies);
3221EXPORT_SYMBOL(sysctl_string);
Eric W. Biederman49a0c452007-10-18 03:05:23 -07003222EXPORT_SYMBOL(sysctl_data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003223EXPORT_SYMBOL(unregister_sysctl_table);