blob: 771ac48f16523a2a27ce9ba1d0e7556cbe2317df [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>
Vegard Nossumdfec0722008-04-04 00:51:41 +020029#include <linux/kmemcheck.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030#include <linux/smp_lock.h>
Adrian Bunk62239ac2007-07-17 04:03:45 -070031#include <linux/fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/init.h>
33#include <linux/kernel.h>
Kay Sievers0296b222005-11-11 05:33:52 +010034#include <linux/kobject.h>
Arnaldo Carvalho de Melo20380732005-08-16 02:18:02 -030035#include <linux/net.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include <linux/sysrq.h>
37#include <linux/highuid.h>
38#include <linux/writeback.h>
39#include <linux/hugetlb.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#include <linux/initrd.h>
David Howells0b77f5b2008-04-29 01:01:32 -070041#include <linux/key.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042#include <linux/times.h>
43#include <linux/limits.h>
44#include <linux/dcache.h>
45#include <linux/syscalls.h>
Adrian Bunkc748e132008-07-23 21:27:03 -070046#include <linux/vmstat.h>
Pavel Machekc255d842006-02-20 18:27:58 -080047#include <linux/nfs_fs.h>
48#include <linux/acpi.h>
Jeremy Fitzhardinge10a0a8d2007-07-17 18:37:02 -070049#include <linux/reboot.h>
Steven Rostedtb0fc4942008-05-12 21:20:43 +020050#include <linux/ftrace.h>
David Howells12e22c52009-04-03 16:42:35 +010051#include <linux/slow-work.h>
Ingo Molnarcdd6c482009-09-21 12:02:48 +020052#include <linux/perf_event.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
54#include <asm/uaccess.h>
55#include <asm/processor.h>
56
Andi Kleen29cbc782006-09-30 01:47:55 +020057#ifdef CONFIG_X86
58#include <asm/nmi.h>
Chuck Ebbert0741f4d2006-12-07 02:14:11 +010059#include <asm/stacktrace.h>
Ingo Molnar6e7c4022008-01-30 13:30:05 +010060#include <asm/io.h>
Andi Kleen29cbc782006-09-30 01:47:55 +020061#endif
62
Eric W. Biederman7058cb02007-10-18 03:05:58 -070063static int deprecated_sysctl_warning(struct __sysctl_args *args);
64
Linus Torvalds1da177e2005-04-16 15:20:36 -070065#if defined(CONFIG_SYSCTL)
66
67/* External variables not in a header file. */
68extern int C_A_D;
Ingo Molnar45807a12007-07-15 23:40:10 -070069extern int print_fatal_signals;
Linus Torvalds1da177e2005-04-16 15:20:36 -070070extern int sysctl_overcommit_memory;
71extern int sysctl_overcommit_ratio;
KAMEZAWA Hiroyukifadd8fb2006-06-23 02:03:13 -070072extern int sysctl_panic_on_oom;
David Rientjesfe071d72007-10-16 23:25:56 -070073extern int sysctl_oom_kill_allocating_task;
David Rientjesfef1bdd2008-02-07 00:14:07 -080074extern int sysctl_oom_dump_tasks;
Linus Torvalds1da177e2005-04-16 15:20:36 -070075extern int max_threads;
Linus Torvalds1da177e2005-04-16 15:20:36 -070076extern int core_uses_pid;
Alan Coxd6e71142005-06-23 00:09:43 -070077extern int suid_dumpable;
Linus Torvalds1da177e2005-04-16 15:20:36 -070078extern char core_pattern[];
Neil Hormana2939802009-09-23 15:56:56 -070079extern unsigned int core_pipe_limit;
Linus Torvalds1da177e2005-04-16 15:20:36 -070080extern int pid_max;
81extern int min_free_kbytes;
Arve Hjønnevågc177d042009-02-17 14:51:02 -080082extern int min_free_order_shift;
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 Gondwana195cf452008-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;
Dave Youngaf913222009-09-22 16:43:33 -0700110#ifdef CONFIG_PRINTK
111static int ten_thousand = 10000;
112#endif
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700113
Andrea Righi9e4a5bd2009-04-30 15:08:57 -0700114/* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
115static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
116
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
118static int maxolduid = 65535;
119static int minolduid;
Rohit Seth8ad4b1f2006-01-08 01:00:40 -0800120static int min_percpu_pagelist_fract = 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
122static int ngroups_max = NGROUPS_MAX;
123
Johannes Berga1ef5ad2008-07-08 19:00:17 +0200124#ifdef CONFIG_MODULES
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125extern char modprobe_path[];
Kees Cook3d433212009-04-02 15:49:29 -0700126extern int modules_disabled;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128#ifdef CONFIG_CHR_DEV_SG
129extern int sg_big_buff;
130#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
David S. Miller72c57ed2008-09-11 23:29:54 -0700132#ifdef CONFIG_SPARC
David S. Miller17f04fb2008-09-11 23:33:53 -0700133#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134#endif
135
David S. Miller08714202008-11-16 23:49:24 -0800136#ifdef CONFIG_SPARC64
137extern int sysctl_tsb_ratio;
138#endif
139
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140#ifdef __hppa__
141extern int pwrsw_enabled;
142extern int unaligned_enabled;
143#endif
144
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800145#ifdef CONFIG_S390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146#ifdef CONFIG_MATHEMU
147extern int sysctl_ieee_emulation_warnings;
148#endif
149extern int sysctl_userprocess_debug;
Martin Schwidefsky951f22d2005-07-27 11:44:57 -0700150extern int spin_retry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151#endif
152
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153#ifdef CONFIG_BSD_PROCESS_ACCT
154extern int acct_parm[];
155#endif
156
Jes Sorensend2b176e2006-02-28 09:42:23 -0800157#ifdef CONFIG_IA64
158extern int no_unaligned_warning;
Doug Chapman88fc2412009-01-15 10:38:56 -0800159extern int unaligned_dump_stack;
Jes Sorensend2b176e2006-02-28 09:42:23 -0800160#endif
161
Ingo Molnar23f78d42006-06-27 02:54:53 -0700162#ifdef CONFIG_RT_MUTEXES
163extern int max_lock_depth;
164#endif
165
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700166#ifdef CONFIG_PROC_SYSCTL
Alexey Dobriyan8d65af72009-09-23 15:57:19 -0700167static int proc_do_cad_pid(struct ctl_table *table, int write,
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700168 void __user *buffer, size_t *lenp, loff_t *ppos);
Alexey Dobriyan8d65af72009-09-23 15:57:19 -0700169static int proc_taint(struct ctl_table *table, int write,
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800170 void __user *buffer, size_t *lenp, loff_t *ppos);
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700171#endif
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700172
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700173static struct ctl_table root_table[];
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100174static struct ctl_table_root sysctl_table_root;
175static struct ctl_table_header root_table_header = {
Al Virob380b0d2008-09-04 17:05:57 +0100176 .count = 1,
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100177 .ctl_table = root_table,
Al Viro73455092008-07-14 21:22:20 -0400178 .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100179 .root = &sysctl_table_root,
Al Viro73455092008-07-14 21:22:20 -0400180 .set = &sysctl_table_root.default_set,
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100181};
182static struct ctl_table_root sysctl_table_root = {
183 .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
Al Viro73455092008-07-14 21:22:20 -0400184 .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry),
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100185};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700187static struct ctl_table kern_table[];
188static struct ctl_table vm_table[];
189static struct ctl_table fs_table[];
190static struct ctl_table debug_table[];
191static struct ctl_table dev_table[];
192extern struct ctl_table random_table[];
Amy Griffis2d9048e2006-06-01 13:10:59 -0700193#ifdef CONFIG_INOTIFY_USER
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700194extern struct ctl_table inotify_table[];
Robert Love0399cb02005-07-13 12:38:18 -0400195#endif
Davide Libenzi7ef99642008-12-01 13:13:55 -0800196#ifdef CONFIG_EPOLL
197extern struct ctl_table epoll_table[];
198#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
200#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
201int sysctl_legacy_va_layout;
202#endif
203
Peter Zijlstraf20786f2007-07-19 01:48:56 -0700204extern int prove_locking;
205extern int lock_stat;
Eric W. Biederman9bc9a6b2006-12-08 02:39:56 -0800206
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207/* The default sysctl tables: */
208
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700209static struct ctl_table root_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 {
211 .ctl_name = CTL_KERN,
212 .procname = "kernel",
213 .mode = 0555,
214 .child = kern_table,
215 },
216 {
217 .ctl_name = CTL_VM,
218 .procname = "vm",
219 .mode = 0555,
220 .child = vm_table,
221 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 .ctl_name = CTL_FS,
224 .procname = "fs",
225 .mode = 0555,
226 .child = fs_table,
227 },
228 {
229 .ctl_name = CTL_DEBUG,
230 .procname = "debug",
231 .mode = 0555,
232 .child = debug_table,
233 },
234 {
235 .ctl_name = CTL_DEV,
236 .procname = "dev",
237 .mode = 0555,
238 .child = dev_table,
239 },
Andrew Morton2be7fe02007-07-15 23:41:21 -0700240/*
241 * NOTE: do not add new entries to this table unless you have read
242 * Documentation/sysctl/ctl_unnumbered.txt
243 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244 { .ctl_name = 0 }
245};
246
Ingo Molnar77e54a12007-07-09 18:52:00 +0200247#ifdef CONFIG_SCHED_DEBUG
Eric Dumazet73c4efd2007-12-18 15:21:13 +0100248static int min_sched_granularity_ns = 100000; /* 100 usecs */
249static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */
250static int min_wakeup_granularity_ns; /* 0 usecs */
251static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */
Ingo Molnar77e54a12007-07-09 18:52:00 +0200252#endif
253
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700254static struct ctl_table kern_table[] = {
Mike Galbraith2bba22c2009-09-09 15:41:37 +0200255 {
256 .ctl_name = CTL_UNNUMBERED,
257 .procname = "sched_child_runs_first",
258 .data = &sysctl_sched_child_runs_first,
259 .maxlen = sizeof(unsigned int),
260 .mode = 0644,
261 .proc_handler = &proc_dointvec,
262 },
Ingo Molnar77e54a12007-07-09 18:52:00 +0200263#ifdef CONFIG_SCHED_DEBUG
264 {
265 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstrab2be5e92007-11-09 22:39:37 +0100266 .procname = "sched_min_granularity_ns",
267 .data = &sysctl_sched_min_granularity,
Ingo Molnar77e54a12007-07-09 18:52:00 +0200268 .maxlen = sizeof(unsigned int),
269 .mode = 0644,
Peter Zijlstrab2be5e92007-11-09 22:39:37 +0100270 .proc_handler = &sched_nr_latency_handler,
271 .strategy = &sysctl_intvec,
272 .extra1 = &min_sched_granularity_ns,
273 .extra2 = &max_sched_granularity_ns,
Ingo Molnar77e54a12007-07-09 18:52:00 +0200274 },
275 {
276 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra21805082007-08-25 18:41:53 +0200277 .procname = "sched_latency_ns",
278 .data = &sysctl_sched_latency,
279 .maxlen = sizeof(unsigned int),
280 .mode = 0644,
Peter Zijlstrab2be5e92007-11-09 22:39:37 +0100281 .proc_handler = &sched_nr_latency_handler,
Peter Zijlstra21805082007-08-25 18:41:53 +0200282 .strategy = &sysctl_intvec,
283 .extra1 = &min_sched_granularity_ns,
284 .extra2 = &max_sched_granularity_ns,
285 },
286 {
287 .ctl_name = CTL_UNNUMBERED,
Ingo Molnar77e54a12007-07-09 18:52:00 +0200288 .procname = "sched_wakeup_granularity_ns",
289 .data = &sysctl_sched_wakeup_granularity,
290 .maxlen = sizeof(unsigned int),
291 .mode = 0644,
292 .proc_handler = &proc_dointvec_minmax,
293 .strategy = &sysctl_intvec,
294 .extra1 = &min_wakeup_granularity_ns,
295 .extra2 = &max_wakeup_granularity_ns,
296 },
297 {
298 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra2398f2c2008-06-27 13:41:35 +0200299 .procname = "sched_shares_ratelimit",
300 .data = &sysctl_sched_shares_ratelimit,
301 .maxlen = sizeof(unsigned int),
302 .mode = 0644,
303 .proc_handler = &proc_dointvec,
304 },
305 {
306 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstraffda12a2008-10-17 19:27:02 +0200307 .procname = "sched_shares_thresh",
308 .data = &sysctl_sched_shares_thresh,
309 .maxlen = sizeof(unsigned int),
310 .mode = 0644,
311 .proc_handler = &proc_dointvec_minmax,
312 .strategy = &sysctl_intvec,
313 .extra1 = &zero,
314 },
315 {
316 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra1fc84aa2007-08-25 18:41:52 +0200317 .procname = "sched_features",
318 .data = &sysctl_sched_features,
319 .maxlen = sizeof(unsigned int),
320 .mode = 0644,
321 .proc_handler = &proc_dointvec,
322 },
Ingo Molnarda84d962007-10-15 17:00:18 +0200323 {
324 .ctl_name = CTL_UNNUMBERED,
325 .procname = "sched_migration_cost",
326 .data = &sysctl_sched_migration_cost,
327 .maxlen = sizeof(unsigned int),
328 .mode = 0644,
329 .proc_handler = &proc_dointvec,
330 },
Peter Zijlstrab82d9fd2007-11-09 22:39:39 +0100331 {
332 .ctl_name = CTL_UNNUMBERED,
333 .procname = "sched_nr_migrate",
334 .data = &sysctl_sched_nr_migrate,
335 .maxlen = sizeof(unsigned int),
Peter Zijlstrafa85ae22008-01-25 21:08:29 +0100336 .mode = 0644,
337 .proc_handler = &proc_dointvec,
338 },
Arun R Bharadwajcd1bb942009-04-16 12:15:34 +0530339 {
340 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstrae9e92502009-09-01 10:34:37 +0200341 .procname = "sched_time_avg",
342 .data = &sysctl_sched_time_avg,
343 .maxlen = sizeof(unsigned int),
344 .mode = 0644,
345 .proc_handler = &proc_dointvec,
346 },
347 {
348 .ctl_name = CTL_UNNUMBERED,
Arun R Bharadwajcd1bb942009-04-16 12:15:34 +0530349 .procname = "timer_migration",
350 .data = &sysctl_timer_migration,
351 .maxlen = sizeof(unsigned int),
352 .mode = 0644,
Arun R Bharadwajbfdb4d92009-06-23 10:00:58 +0530353 .proc_handler = &proc_dointvec_minmax,
354 .strategy = &sysctl_intvec,
355 .extra1 = &zero,
356 .extra2 = &one,
Arun R Bharadwajcd1bb942009-04-16 12:15:34 +0530357 },
Peter Zijlstra1fc84aa2007-08-25 18:41:52 +0200358#endif
Ingo Molnar1799e352007-09-19 23:34:46 +0200359 {
360 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra9f0c1e52008-02-13 15:45:39 +0100361 .procname = "sched_rt_period_us",
362 .data = &sysctl_sched_rt_period,
363 .maxlen = sizeof(unsigned int),
364 .mode = 0644,
Peter Zijlstrad0b27fa72008-04-19 19:44:57 +0200365 .proc_handler = &sched_rt_handler,
Peter Zijlstra9f0c1e52008-02-13 15:45:39 +0100366 },
367 {
368 .ctl_name = CTL_UNNUMBERED,
369 .procname = "sched_rt_runtime_us",
370 .data = &sysctl_sched_rt_runtime,
371 .maxlen = sizeof(int),
372 .mode = 0644,
Peter Zijlstrad0b27fa72008-04-19 19:44:57 +0200373 .proc_handler = &sched_rt_handler,
Peter Zijlstra9f0c1e52008-02-13 15:45:39 +0100374 },
375 {
376 .ctl_name = CTL_UNNUMBERED,
Ingo Molnar1799e352007-09-19 23:34:46 +0200377 .procname = "sched_compat_yield",
378 .data = &sysctl_sched_compat_yield,
379 .maxlen = sizeof(unsigned int),
380 .mode = 0644,
381 .proc_handler = &proc_dointvec,
382 },
Peter Zijlstraf20786f2007-07-19 01:48:56 -0700383#ifdef CONFIG_PROVE_LOCKING
384 {
385 .ctl_name = CTL_UNNUMBERED,
386 .procname = "prove_locking",
387 .data = &prove_locking,
388 .maxlen = sizeof(int),
389 .mode = 0644,
390 .proc_handler = &proc_dointvec,
391 },
392#endif
393#ifdef CONFIG_LOCK_STAT
394 {
395 .ctl_name = CTL_UNNUMBERED,
396 .procname = "lock_stat",
397 .data = &lock_stat,
398 .maxlen = sizeof(int),
399 .mode = 0644,
400 .proc_handler = &proc_dointvec,
401 },
402#endif
Ingo Molnar77e54a12007-07-09 18:52:00 +0200403 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 .ctl_name = KERN_PANIC,
405 .procname = "panic",
406 .data = &panic_timeout,
407 .maxlen = sizeof(int),
408 .mode = 0644,
409 .proc_handler = &proc_dointvec,
410 },
411 {
412 .ctl_name = KERN_CORE_USES_PID,
413 .procname = "core_uses_pid",
414 .data = &core_uses_pid,
415 .maxlen = sizeof(int),
416 .mode = 0644,
417 .proc_handler = &proc_dointvec,
418 },
419 {
420 .ctl_name = KERN_CORE_PATTERN,
421 .procname = "core_pattern",
422 .data = core_pattern,
Dan Aloni71ce92f2007-05-16 22:11:16 -0700423 .maxlen = CORENAME_MAX_SIZE,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 .mode = 0644,
425 .proc_handler = &proc_dostring,
426 .strategy = &sysctl_string,
427 },
Neil Hormana2939802009-09-23 15:56:56 -0700428 {
429 .ctl_name = CTL_UNNUMBERED,
430 .procname = "core_pipe_limit",
431 .data = &core_pipe_limit,
432 .maxlen = sizeof(unsigned int),
433 .mode = 0644,
434 .proc_handler = &proc_dointvec,
435 },
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800436#ifdef CONFIG_PROC_SYSCTL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 .procname = "tainted",
Andi Kleen25ddbb12008-10-15 22:01:41 -0700439 .maxlen = sizeof(long),
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800440 .mode = 0644,
Andi Kleen25ddbb12008-10-15 22:01:41 -0700441 .proc_handler = &proc_taint,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 },
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800443#endif
Arjan van de Ven97455122008-01-25 21:08:34 +0100444#ifdef CONFIG_LATENCYTOP
445 {
446 .procname = "latencytop",
447 .data = &latencytop_enabled,
448 .maxlen = sizeof(int),
449 .mode = 0644,
450 .proc_handler = &proc_dointvec,
451 },
452#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453#ifdef CONFIG_BLK_DEV_INITRD
454 {
455 .ctl_name = KERN_REALROOTDEV,
456 .procname = "real-root-dev",
457 .data = &real_root_dev,
458 .maxlen = sizeof(int),
459 .mode = 0644,
460 .proc_handler = &proc_dointvec,
461 },
462#endif
Ingo Molnar45807a12007-07-15 23:40:10 -0700463 {
464 .ctl_name = CTL_UNNUMBERED,
465 .procname = "print-fatal-signals",
466 .data = &print_fatal_signals,
467 .maxlen = sizeof(int),
468 .mode = 0644,
469 .proc_handler = &proc_dointvec,
470 },
David S. Miller72c57ed2008-09-11 23:29:54 -0700471#ifdef CONFIG_SPARC
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 {
473 .ctl_name = KERN_SPARC_REBOOT,
474 .procname = "reboot-cmd",
475 .data = reboot_command,
476 .maxlen = 256,
477 .mode = 0644,
478 .proc_handler = &proc_dostring,
479 .strategy = &sysctl_string,
480 },
481 {
482 .ctl_name = KERN_SPARC_STOP_A,
483 .procname = "stop-a",
484 .data = &stop_a_enabled,
485 .maxlen = sizeof (int),
486 .mode = 0644,
487 .proc_handler = &proc_dointvec,
488 },
489 {
490 .ctl_name = KERN_SPARC_SCONS_PWROFF,
491 .procname = "scons-poweroff",
492 .data = &scons_pwroff,
493 .maxlen = sizeof (int),
494 .mode = 0644,
495 .proc_handler = &proc_dointvec,
496 },
497#endif
David S. Miller08714202008-11-16 23:49:24 -0800498#ifdef CONFIG_SPARC64
499 {
500 .ctl_name = CTL_UNNUMBERED,
501 .procname = "tsb-ratio",
502 .data = &sysctl_tsb_ratio,
503 .maxlen = sizeof (int),
504 .mode = 0644,
505 .proc_handler = &proc_dointvec,
506 },
507#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508#ifdef __hppa__
509 {
510 .ctl_name = KERN_HPPA_PWRSW,
511 .procname = "soft-power",
512 .data = &pwrsw_enabled,
513 .maxlen = sizeof (int),
514 .mode = 0644,
515 .proc_handler = &proc_dointvec,
516 },
517 {
518 .ctl_name = KERN_HPPA_UNALIGNED,
519 .procname = "unaligned-trap",
520 .data = &unaligned_enabled,
521 .maxlen = sizeof (int),
522 .mode = 0644,
523 .proc_handler = &proc_dointvec,
524 },
525#endif
526 {
527 .ctl_name = KERN_CTLALTDEL,
528 .procname = "ctrl-alt-del",
529 .data = &C_A_D,
530 .maxlen = sizeof(int),
531 .mode = 0644,
532 .proc_handler = &proc_dointvec,
533 },
Steven Rostedt606576c2008-10-06 19:06:12 -0400534#ifdef CONFIG_FUNCTION_TRACER
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200535 {
536 .ctl_name = CTL_UNNUMBERED,
537 .procname = "ftrace_enabled",
538 .data = &ftrace_enabled,
539 .maxlen = sizeof(int),
540 .mode = 0644,
541 .proc_handler = &ftrace_enable_sysctl,
542 },
543#endif
Steven Rostedtf38f1d22008-12-16 23:06:40 -0500544#ifdef CONFIG_STACK_TRACER
545 {
546 .ctl_name = CTL_UNNUMBERED,
547 .procname = "stack_tracer_enabled",
548 .data = &stack_tracer_enabled,
549 .maxlen = sizeof(int),
550 .mode = 0644,
551 .proc_handler = &stack_trace_sysctl,
552 },
553#endif
Steven Rostedt944ac422008-10-23 19:26:08 -0400554#ifdef CONFIG_TRACING
555 {
556 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra3299b4d2008-11-04 11:58:21 +0100557 .procname = "ftrace_dump_on_oops",
Steven Rostedt944ac422008-10-23 19:26:08 -0400558 .data = &ftrace_dump_on_oops,
559 .maxlen = sizeof(int),
560 .mode = 0644,
561 .proc_handler = &proc_dointvec,
562 },
563#endif
Johannes Berga1ef5ad2008-07-08 19:00:17 +0200564#ifdef CONFIG_MODULES
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565 {
566 .ctl_name = KERN_MODPROBE,
567 .procname = "modprobe",
568 .data = &modprobe_path,
569 .maxlen = KMOD_PATH_LEN,
570 .mode = 0644,
571 .proc_handler = &proc_dostring,
572 .strategy = &sysctl_string,
573 },
Kees Cook3d433212009-04-02 15:49:29 -0700574 {
575 .ctl_name = CTL_UNNUMBERED,
576 .procname = "modules_disabled",
577 .data = &modules_disabled,
578 .maxlen = sizeof(int),
579 .mode = 0644,
580 /* only handle a transition from default "0" to "1" */
581 .proc_handler = &proc_dointvec_minmax,
582 .extra1 = &one,
583 .extra2 = &one,
584 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585#endif
Andrew Morton57ae2502006-06-23 02:05:47 -0700586#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 {
588 .ctl_name = KERN_HOTPLUG,
589 .procname = "hotplug",
Kay Sievers312c0042005-11-16 09:00:00 +0100590 .data = &uevent_helper,
591 .maxlen = UEVENT_HELPER_PATH_LEN,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 .mode = 0644,
593 .proc_handler = &proc_dostring,
594 .strategy = &sysctl_string,
595 },
596#endif
597#ifdef CONFIG_CHR_DEV_SG
598 {
599 .ctl_name = KERN_SG_BIG_BUFF,
600 .procname = "sg-big-buff",
601 .data = &sg_big_buff,
602 .maxlen = sizeof (int),
603 .mode = 0444,
604 .proc_handler = &proc_dointvec,
605 },
606#endif
607#ifdef CONFIG_BSD_PROCESS_ACCT
608 {
609 .ctl_name = KERN_ACCT,
610 .procname = "acct",
611 .data = &acct_parm,
612 .maxlen = 3*sizeof(int),
613 .mode = 0644,
614 .proc_handler = &proc_dointvec,
615 },
616#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617#ifdef CONFIG_MAGIC_SYSRQ
618 {
619 .ctl_name = KERN_SYSRQ,
620 .procname = "sysrq",
Ingo Molnar5d6f6472006-12-13 00:34:36 -0800621 .data = &__sysrq_enabled,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 .maxlen = sizeof (int),
623 .mode = 0644,
624 .proc_handler = &proc_dointvec,
625 },
626#endif
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700627#ifdef CONFIG_PROC_SYSCTL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 .procname = "cad_pid",
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700630 .data = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 .maxlen = sizeof (int),
632 .mode = 0600,
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700633 .proc_handler = &proc_do_cad_pid,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 },
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700635#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 {
637 .ctl_name = KERN_MAX_THREADS,
638 .procname = "threads-max",
639 .data = &max_threads,
640 .maxlen = sizeof(int),
641 .mode = 0644,
642 .proc_handler = &proc_dointvec,
643 },
644 {
645 .ctl_name = KERN_RANDOM,
646 .procname = "random",
647 .mode = 0555,
648 .child = random_table,
649 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 {
651 .ctl_name = KERN_OVERFLOWUID,
652 .procname = "overflowuid",
653 .data = &overflowuid,
654 .maxlen = sizeof(int),
655 .mode = 0644,
656 .proc_handler = &proc_dointvec_minmax,
657 .strategy = &sysctl_intvec,
658 .extra1 = &minolduid,
659 .extra2 = &maxolduid,
660 },
661 {
662 .ctl_name = KERN_OVERFLOWGID,
663 .procname = "overflowgid",
664 .data = &overflowgid,
665 .maxlen = sizeof(int),
666 .mode = 0644,
667 .proc_handler = &proc_dointvec_minmax,
668 .strategy = &sysctl_intvec,
669 .extra1 = &minolduid,
670 .extra2 = &maxolduid,
671 },
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800672#ifdef CONFIG_S390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673#ifdef CONFIG_MATHEMU
674 {
675 .ctl_name = KERN_IEEE_EMULATION_WARNINGS,
676 .procname = "ieee_emulation_warnings",
677 .data = &sysctl_ieee_emulation_warnings,
678 .maxlen = sizeof(int),
679 .mode = 0644,
680 .proc_handler = &proc_dointvec,
681 },
682#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 {
684 .ctl_name = KERN_S390_USER_DEBUG_LOGGING,
685 .procname = "userprocess_debug",
686 .data = &sysctl_userprocess_debug,
687 .maxlen = sizeof(int),
688 .mode = 0644,
689 .proc_handler = &proc_dointvec,
690 },
691#endif
692 {
693 .ctl_name = KERN_PIDMAX,
694 .procname = "pid_max",
695 .data = &pid_max,
696 .maxlen = sizeof (int),
697 .mode = 0644,
698 .proc_handler = &proc_dointvec_minmax,
699 .strategy = sysctl_intvec,
700 .extra1 = &pid_max_min,
701 .extra2 = &pid_max_max,
702 },
703 {
704 .ctl_name = KERN_PANIC_ON_OOPS,
705 .procname = "panic_on_oops",
706 .data = &panic_on_oops,
707 .maxlen = sizeof(int),
708 .mode = 0644,
709 .proc_handler = &proc_dointvec,
710 },
Joe Perches7ef3d2f2008-02-08 04:21:25 -0800711#if defined CONFIG_PRINTK
712 {
713 .ctl_name = KERN_PRINTK,
714 .procname = "printk",
715 .data = &console_loglevel,
716 .maxlen = 4*sizeof(int),
717 .mode = 0644,
718 .proc_handler = &proc_dointvec,
719 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 {
721 .ctl_name = KERN_PRINTK_RATELIMIT,
722 .procname = "printk_ratelimit",
Dave Young717115e2008-07-25 01:45:58 -0700723 .data = &printk_ratelimit_state.interval,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 .maxlen = sizeof(int),
725 .mode = 0644,
726 .proc_handler = &proc_dointvec_jiffies,
727 .strategy = &sysctl_jiffies,
728 },
729 {
730 .ctl_name = KERN_PRINTK_RATELIMIT_BURST,
731 .procname = "printk_ratelimit_burst",
Dave Young717115e2008-07-25 01:45:58 -0700732 .data = &printk_ratelimit_state.burst,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 .maxlen = sizeof(int),
734 .mode = 0644,
735 .proc_handler = &proc_dointvec,
736 },
Dave Youngaf913222009-09-22 16:43:33 -0700737 {
738 .ctl_name = CTL_UNNUMBERED,
739 .procname = "printk_delay",
740 .data = &printk_delay_msec,
741 .maxlen = sizeof(int),
742 .mode = 0644,
743 .proc_handler = &proc_dointvec_minmax,
744 .strategy = &sysctl_intvec,
745 .extra1 = &zero,
746 .extra2 = &ten_thousand,
747 },
Joe Perches7ef3d2f2008-02-08 04:21:25 -0800748#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 {
750 .ctl_name = KERN_NGROUPS_MAX,
751 .procname = "ngroups_max",
752 .data = &ngroups_max,
753 .maxlen = sizeof (int),
754 .mode = 0444,
755 .proc_handler = &proc_dointvec,
756 },
757#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
758 {
759 .ctl_name = KERN_UNKNOWN_NMI_PANIC,
760 .procname = "unknown_nmi_panic",
761 .data = &unknown_nmi_panic,
762 .maxlen = sizeof (int),
763 .mode = 0644,
Don Zickus2fbe7b22006-09-26 10:52:27 +0200764 .proc_handler = &proc_dointvec,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 },
Don Zickus407984f2006-09-26 10:52:27 +0200766 {
Don Zickus407984f2006-09-26 10:52:27 +0200767 .procname = "nmi_watchdog",
768 .data = &nmi_watchdog_enabled,
769 .maxlen = sizeof (int),
770 .mode = 0644,
771 .proc_handler = &proc_nmi_enabled,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772 },
773#endif
774#if defined(CONFIG_X86)
775 {
Don Zickus8da5add2006-09-26 10:52:27 +0200776 .ctl_name = KERN_PANIC_ON_NMI,
777 .procname = "panic_on_unrecovered_nmi",
778 .data = &panic_on_unrecovered_nmi,
779 .maxlen = sizeof(int),
780 .mode = 0644,
781 .proc_handler = &proc_dointvec,
782 },
783 {
Kurt Garloff5211a242009-06-24 14:32:11 -0700784 .ctl_name = CTL_UNNUMBERED,
785 .procname = "panic_on_io_nmi",
786 .data = &panic_on_io_nmi,
787 .maxlen = sizeof(int),
788 .mode = 0644,
789 .proc_handler = &proc_dointvec,
790 },
791 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 .ctl_name = KERN_BOOTLOADER_TYPE,
793 .procname = "bootloader_type",
794 .data = &bootloader_type,
795 .maxlen = sizeof (int),
796 .mode = 0444,
797 .proc_handler = &proc_dointvec,
798 },
Chuck Ebbert0741f4d2006-12-07 02:14:11 +0100799 {
800 .ctl_name = CTL_UNNUMBERED,
H. Peter Anvin50312962009-05-07 16:54:11 -0700801 .procname = "bootloader_version",
802 .data = &bootloader_version,
803 .maxlen = sizeof (int),
804 .mode = 0444,
805 .proc_handler = &proc_dointvec,
806 },
807 {
808 .ctl_name = CTL_UNNUMBERED,
Chuck Ebbert0741f4d2006-12-07 02:14:11 +0100809 .procname = "kstack_depth_to_print",
810 .data = &kstack_depth_to_print,
811 .maxlen = sizeof(int),
812 .mode = 0644,
813 .proc_handler = &proc_dointvec,
814 },
Ingo Molnar6e7c4022008-01-30 13:30:05 +0100815 {
816 .ctl_name = CTL_UNNUMBERED,
817 .procname = "io_delay_type",
818 .data = &io_delay_type,
819 .maxlen = sizeof(int),
820 .mode = 0644,
821 .proc_handler = &proc_dointvec,
822 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823#endif
Luke Yang7a9166e2006-02-20 18:28:07 -0800824#if defined(CONFIG_MMU)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 {
826 .ctl_name = KERN_RANDOMIZE,
827 .procname = "randomize_va_space",
828 .data = &randomize_va_space,
829 .maxlen = sizeof(int),
830 .mode = 0644,
831 .proc_handler = &proc_dointvec,
832 },
Luke Yang7a9166e2006-02-20 18:28:07 -0800833#endif
Martin Schwidefsky0152fb32006-01-14 13:21:00 -0800834#if defined(CONFIG_S390) && defined(CONFIG_SMP)
Martin Schwidefsky951f22d2005-07-27 11:44:57 -0700835 {
836 .ctl_name = KERN_SPIN_RETRY,
837 .procname = "spin_retry",
838 .data = &spin_retry,
839 .maxlen = sizeof (int),
840 .mode = 0644,
841 .proc_handler = &proc_dointvec,
842 },
843#endif
Len Brown673d5b42007-07-28 03:33:16 -0400844#if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86)
Pavel Machekc255d842006-02-20 18:27:58 -0800845 {
Pavel Machekc255d842006-02-20 18:27:58 -0800846 .procname = "acpi_video_flags",
Pavel Machek77afcf72007-07-19 01:47:41 -0700847 .data = &acpi_realmode_flags,
Pavel Machekc255d842006-02-20 18:27:58 -0800848 .maxlen = sizeof (unsigned long),
849 .mode = 0644,
Stefan Seyfried7f99f062006-03-02 02:54:34 -0800850 .proc_handler = &proc_doulongvec_minmax,
Pavel Machekc255d842006-02-20 18:27:58 -0800851 },
852#endif
Jes Sorensend2b176e2006-02-28 09:42:23 -0800853#ifdef CONFIG_IA64
854 {
855 .ctl_name = KERN_IA64_UNALIGNED,
856 .procname = "ignore-unaligned-usertrap",
857 .data = &no_unaligned_warning,
858 .maxlen = sizeof (int),
859 .mode = 0644,
860 .proc_handler = &proc_dointvec,
861 },
Doug Chapman88fc2412009-01-15 10:38:56 -0800862 {
863 .ctl_name = CTL_UNNUMBERED,
864 .procname = "unaligned-dump-stack",
865 .data = &unaligned_dump_stack,
866 .maxlen = sizeof (int),
867 .mode = 0644,
868 .proc_handler = &proc_dointvec,
869 },
Jes Sorensend2b176e2006-02-28 09:42:23 -0800870#endif
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700871#ifdef CONFIG_DETECT_SOFTLOCKUP
872 {
873 .ctl_name = CTL_UNNUMBERED,
Ingo Molnar9c44bc02008-05-12 21:21:04 +0200874 .procname = "softlockup_panic",
875 .data = &softlockup_panic,
876 .maxlen = sizeof(int),
877 .mode = 0644,
Hiroshi Shimamoto4dca10a2008-07-07 18:37:04 -0700878 .proc_handler = &proc_dointvec_minmax,
Ingo Molnar9c44bc02008-05-12 21:21:04 +0200879 .strategy = &sysctl_intvec,
880 .extra1 = &zero,
881 .extra2 = &one,
882 },
883 {
884 .ctl_name = CTL_UNNUMBERED,
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700885 .procname = "softlockup_thresh",
886 .data = &softlockup_thresh,
Dimitri Sivanich9383d962008-05-12 21:21:14 +0200887 .maxlen = sizeof(int),
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700888 .mode = 0644,
Mandeep Singh Bainesbaf48f62009-01-12 21:15:17 -0800889 .proc_handler = &proc_dosoftlockup_thresh,
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700890 .strategy = &sysctl_intvec,
Dimitri Sivanich9383d962008-05-12 21:21:14 +0200891 .extra1 = &neg_one,
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700892 .extra2 = &sixty,
893 },
Mandeep Singh Bainese162b392009-01-15 11:08:40 -0800894#endif
895#ifdef CONFIG_DETECT_HUNG_TASK
896 {
897 .ctl_name = CTL_UNNUMBERED,
898 .procname = "hung_task_panic",
899 .data = &sysctl_hung_task_panic,
900 .maxlen = sizeof(int),
901 .mode = 0644,
902 .proc_handler = &proc_dointvec_minmax,
903 .strategy = &sysctl_intvec,
904 .extra1 = &zero,
905 .extra2 = &one,
906 },
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100907 {
908 .ctl_name = CTL_UNNUMBERED,
909 .procname = "hung_task_check_count",
910 .data = &sysctl_hung_task_check_count,
Ingo Molnar90739082008-01-25 21:08:34 +0100911 .maxlen = sizeof(unsigned long),
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100912 .mode = 0644,
Ingo Molnar90739082008-01-25 21:08:34 +0100913 .proc_handler = &proc_doulongvec_minmax,
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100914 .strategy = &sysctl_intvec,
915 },
916 {
917 .ctl_name = CTL_UNNUMBERED,
918 .procname = "hung_task_timeout_secs",
919 .data = &sysctl_hung_task_timeout_secs,
Ingo Molnar90739082008-01-25 21:08:34 +0100920 .maxlen = sizeof(unsigned long),
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100921 .mode = 0644,
Mandeep Singh Bainese162b392009-01-15 11:08:40 -0800922 .proc_handler = &proc_dohung_task_timeout_secs,
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100923 .strategy = &sysctl_intvec,
924 },
925 {
926 .ctl_name = CTL_UNNUMBERED,
927 .procname = "hung_task_warnings",
928 .data = &sysctl_hung_task_warnings,
Ingo Molnar90739082008-01-25 21:08:34 +0100929 .maxlen = sizeof(unsigned long),
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100930 .mode = 0644,
Ingo Molnar90739082008-01-25 21:08:34 +0100931 .proc_handler = &proc_doulongvec_minmax,
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100932 .strategy = &sysctl_intvec,
933 },
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700934#endif
Andi Kleenbebfa102006-06-26 13:56:52 +0200935#ifdef CONFIG_COMPAT
936 {
937 .ctl_name = KERN_COMPAT_LOG,
938 .procname = "compat-log",
939 .data = &compat_log,
940 .maxlen = sizeof (int),
941 .mode = 0644,
942 .proc_handler = &proc_dointvec,
943 },
944#endif
Ingo Molnar23f78d42006-06-27 02:54:53 -0700945#ifdef CONFIG_RT_MUTEXES
946 {
947 .ctl_name = KERN_MAX_LOCK_DEPTH,
948 .procname = "max_lock_depth",
949 .data = &max_lock_depth,
950 .maxlen = sizeof(int),
951 .mode = 0644,
952 .proc_handler = &proc_dointvec,
953 },
954#endif
Jeremy Fitzhardinge10a0a8d2007-07-17 18:37:02 -0700955 {
956 .ctl_name = CTL_UNNUMBERED,
957 .procname = "poweroff_cmd",
958 .data = &poweroff_cmd,
959 .maxlen = POWEROFF_CMD_PATH_LEN,
960 .mode = 0644,
961 .proc_handler = &proc_dostring,
962 .strategy = &sysctl_string,
963 },
David Howells0b77f5b2008-04-29 01:01:32 -0700964#ifdef CONFIG_KEYS
965 {
966 .ctl_name = CTL_UNNUMBERED,
967 .procname = "keys",
968 .mode = 0555,
969 .child = key_sysctls,
970 },
971#endif
Paul E. McKenney31a72bc2008-06-18 09:26:49 -0700972#ifdef CONFIG_RCU_TORTURE_TEST
973 {
974 .ctl_name = CTL_UNNUMBERED,
975 .procname = "rcutorture_runnable",
976 .data = &rcutorture_runnable,
977 .maxlen = sizeof(int),
978 .mode = 0644,
979 .proc_handler = &proc_dointvec,
980 },
981#endif
David Howells12e22c52009-04-03 16:42:35 +0100982#ifdef CONFIG_SLOW_WORK
983 {
984 .ctl_name = CTL_UNNUMBERED,
985 .procname = "slow-work",
986 .mode = 0555,
987 .child = slow_work_sysctls,
988 },
989#endif
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200990#ifdef CONFIG_PERF_EVENTS
Peter Zijlstra1ccd1542009-04-09 10:53:45 +0200991 {
992 .ctl_name = CTL_UNNUMBERED,
Ingo Molnarcdd6c482009-09-21 12:02:48 +0200993 .procname = "perf_event_paranoid",
994 .data = &sysctl_perf_event_paranoid,
995 .maxlen = sizeof(sysctl_perf_event_paranoid),
Peter Zijlstra1ccd1542009-04-09 10:53:45 +0200996 .mode = 0644,
997 .proc_handler = &proc_dointvec,
998 },
Peter Zijlstrac5078f72009-05-05 17:50:24 +0200999 {
1000 .ctl_name = CTL_UNNUMBERED,
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001001 .procname = "perf_event_mlock_kb",
1002 .data = &sysctl_perf_event_mlock,
1003 .maxlen = sizeof(sysctl_perf_event_mlock),
Peter Zijlstrac5078f72009-05-05 17:50:24 +02001004 .mode = 0644,
1005 .proc_handler = &proc_dointvec,
1006 },
Peter Zijlstraa78ac322009-05-25 17:39:05 +02001007 {
1008 .ctl_name = CTL_UNNUMBERED,
Ingo Molnarcdd6c482009-09-21 12:02:48 +02001009 .procname = "perf_event_max_sample_rate",
1010 .data = &sysctl_perf_event_sample_rate,
1011 .maxlen = sizeof(sysctl_perf_event_sample_rate),
Peter Zijlstraa78ac322009-05-25 17:39:05 +02001012 .mode = 0644,
1013 .proc_handler = &proc_dointvec,
1014 },
Peter Zijlstra1ccd1542009-04-09 10:53:45 +02001015#endif
Vegard Nossumdfec0722008-04-04 00:51:41 +02001016#ifdef CONFIG_KMEMCHECK
1017 {
1018 .ctl_name = CTL_UNNUMBERED,
1019 .procname = "kmemcheck",
1020 .data = &kmemcheck_enabled,
1021 .maxlen = sizeof(int),
1022 .mode = 0644,
1023 .proc_handler = &proc_dointvec,
1024 },
1025#endif
Jens Axboecb684b52009-09-15 21:53:11 +02001026#ifdef CONFIG_BLOCK
Jens Axboe5e605b62009-08-05 09:07:21 +02001027 {
1028 .ctl_name = CTL_UNNUMBERED,
1029 .procname = "blk_iopoll",
1030 .data = &blk_iopoll_enabled,
1031 .maxlen = sizeof(int),
1032 .mode = 0644,
1033 .proc_handler = &proc_dointvec,
1034 },
Jens Axboecb684b52009-09-15 21:53:11 +02001035#endif
Andrew Mortoned2c12f2007-07-19 01:50:35 -07001036/*
1037 * NOTE: do not add new entries to this table unless you have read
1038 * Documentation/sysctl/ctl_unnumbered.txt
1039 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040 { .ctl_name = 0 }
1041};
1042
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001043static struct ctl_table vm_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 {
1045 .ctl_name = VM_OVERCOMMIT_MEMORY,
1046 .procname = "overcommit_memory",
1047 .data = &sysctl_overcommit_memory,
1048 .maxlen = sizeof(sysctl_overcommit_memory),
1049 .mode = 0644,
1050 .proc_handler = &proc_dointvec,
1051 },
1052 {
KAMEZAWA Hiroyukifadd8fb2006-06-23 02:03:13 -07001053 .ctl_name = VM_PANIC_ON_OOM,
1054 .procname = "panic_on_oom",
1055 .data = &sysctl_panic_on_oom,
1056 .maxlen = sizeof(sysctl_panic_on_oom),
1057 .mode = 0644,
1058 .proc_handler = &proc_dointvec,
1059 },
1060 {
David Rientjesfe071d72007-10-16 23:25:56 -07001061 .ctl_name = CTL_UNNUMBERED,
1062 .procname = "oom_kill_allocating_task",
1063 .data = &sysctl_oom_kill_allocating_task,
1064 .maxlen = sizeof(sysctl_oom_kill_allocating_task),
1065 .mode = 0644,
1066 .proc_handler = &proc_dointvec,
1067 },
1068 {
David Rientjesfef1bdd2008-02-07 00:14:07 -08001069 .ctl_name = CTL_UNNUMBERED,
1070 .procname = "oom_dump_tasks",
1071 .data = &sysctl_oom_dump_tasks,
1072 .maxlen = sizeof(sysctl_oom_dump_tasks),
1073 .mode = 0644,
1074 .proc_handler = &proc_dointvec,
1075 },
1076 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 .ctl_name = VM_OVERCOMMIT_RATIO,
1078 .procname = "overcommit_ratio",
1079 .data = &sysctl_overcommit_ratio,
1080 .maxlen = sizeof(sysctl_overcommit_ratio),
1081 .mode = 0644,
1082 .proc_handler = &proc_dointvec,
1083 },
1084 {
1085 .ctl_name = VM_PAGE_CLUSTER,
1086 .procname = "page-cluster",
1087 .data = &page_cluster,
1088 .maxlen = sizeof(int),
1089 .mode = 0644,
1090 .proc_handler = &proc_dointvec,
1091 },
1092 {
1093 .ctl_name = VM_DIRTY_BACKGROUND,
1094 .procname = "dirty_background_ratio",
1095 .data = &dirty_background_ratio,
1096 .maxlen = sizeof(dirty_background_ratio),
1097 .mode = 0644,
David Rientjes2da02992009-01-06 14:39:31 -08001098 .proc_handler = &dirty_background_ratio_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 .strategy = &sysctl_intvec,
1100 .extra1 = &zero,
1101 .extra2 = &one_hundred,
1102 },
1103 {
David Rientjes2da02992009-01-06 14:39:31 -08001104 .ctl_name = CTL_UNNUMBERED,
1105 .procname = "dirty_background_bytes",
1106 .data = &dirty_background_bytes,
1107 .maxlen = sizeof(dirty_background_bytes),
1108 .mode = 0644,
1109 .proc_handler = &dirty_background_bytes_handler,
1110 .strategy = &sysctl_intvec,
Sven Wegenerfc3501d2009-02-11 13:04:23 -08001111 .extra1 = &one_ul,
David Rientjes2da02992009-01-06 14:39:31 -08001112 },
1113 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 .ctl_name = VM_DIRTY_RATIO,
1115 .procname = "dirty_ratio",
1116 .data = &vm_dirty_ratio,
1117 .maxlen = sizeof(vm_dirty_ratio),
1118 .mode = 0644,
Peter Zijlstra04fbfdc2007-10-16 23:25:50 -07001119 .proc_handler = &dirty_ratio_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 .strategy = &sysctl_intvec,
1121 .extra1 = &zero,
1122 .extra2 = &one_hundred,
1123 },
1124 {
David Rientjes2da02992009-01-06 14:39:31 -08001125 .ctl_name = CTL_UNNUMBERED,
1126 .procname = "dirty_bytes",
1127 .data = &vm_dirty_bytes,
1128 .maxlen = sizeof(vm_dirty_bytes),
1129 .mode = 0644,
1130 .proc_handler = &dirty_bytes_handler,
1131 .strategy = &sysctl_intvec,
Andrea Righi9e4a5bd2009-04-30 15:08:57 -07001132 .extra1 = &dirty_bytes_min,
David Rientjes2da02992009-01-06 14:39:31 -08001133 },
1134 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 .procname = "dirty_writeback_centisecs",
Bart Samwelf6ef9432006-03-24 03:15:48 -08001136 .data = &dirty_writeback_interval,
1137 .maxlen = sizeof(dirty_writeback_interval),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 .mode = 0644,
1139 .proc_handler = &dirty_writeback_centisecs_handler,
1140 },
1141 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142 .procname = "dirty_expire_centisecs",
Bart Samwelf6ef9432006-03-24 03:15:48 -08001143 .data = &dirty_expire_interval,
1144 .maxlen = sizeof(dirty_expire_interval),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 .mode = 0644,
Alexey Dobriyan704503d2009-03-31 15:23:18 -07001146 .proc_handler = &proc_dointvec,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 },
1148 {
1149 .ctl_name = VM_NR_PDFLUSH_THREADS,
1150 .procname = "nr_pdflush_threads",
1151 .data = &nr_pdflush_threads,
1152 .maxlen = sizeof nr_pdflush_threads,
1153 .mode = 0444 /* read-only*/,
1154 .proc_handler = &proc_dointvec,
1155 },
1156 {
1157 .ctl_name = VM_SWAPPINESS,
1158 .procname = "swappiness",
1159 .data = &vm_swappiness,
1160 .maxlen = sizeof(vm_swappiness),
1161 .mode = 0644,
1162 .proc_handler = &proc_dointvec_minmax,
1163 .strategy = &sysctl_intvec,
1164 .extra1 = &zero,
1165 .extra2 = &one_hundred,
1166 },
1167#ifdef CONFIG_HUGETLB_PAGE
1168 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169 .procname = "nr_hugepages",
Andi Kleene5ff2152008-07-23 21:27:42 -07001170 .data = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 .maxlen = sizeof(unsigned long),
1172 .mode = 0644,
1173 .proc_handler = &hugetlb_sysctl_handler,
1174 .extra1 = (void *)&hugetlb_zero,
1175 .extra2 = (void *)&hugetlb_infinity,
1176 },
1177 {
1178 .ctl_name = VM_HUGETLB_GROUP,
1179 .procname = "hugetlb_shm_group",
1180 .data = &sysctl_hugetlb_shm_group,
1181 .maxlen = sizeof(gid_t),
1182 .mode = 0644,
1183 .proc_handler = &proc_dointvec,
1184 },
Mel Gorman396faf02007-07-17 04:03:13 -07001185 {
1186 .ctl_name = CTL_UNNUMBERED,
1187 .procname = "hugepages_treat_as_movable",
1188 .data = &hugepages_treat_as_movable,
1189 .maxlen = sizeof(int),
1190 .mode = 0644,
1191 .proc_handler = &hugetlb_treat_movable_handler,
1192 },
Adam Litke54f9f802007-10-16 01:26:20 -07001193 {
1194 .ctl_name = CTL_UNNUMBERED,
Nishanth Aravamudand1c3fb12007-12-17 16:20:12 -08001195 .procname = "nr_overcommit_hugepages",
Andi Kleene5ff2152008-07-23 21:27:42 -07001196 .data = NULL,
1197 .maxlen = sizeof(unsigned long),
Nishanth Aravamudand1c3fb12007-12-17 16:20:12 -08001198 .mode = 0644,
Nishanth Aravamudana3d0c6a2008-02-08 04:18:18 -08001199 .proc_handler = &hugetlb_overcommit_handler,
Andi Kleene5ff2152008-07-23 21:27:42 -07001200 .extra1 = (void *)&hugetlb_zero,
1201 .extra2 = (void *)&hugetlb_infinity,
Nishanth Aravamudand1c3fb12007-12-17 16:20:12 -08001202 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203#endif
1204 {
1205 .ctl_name = VM_LOWMEM_RESERVE_RATIO,
1206 .procname = "lowmem_reserve_ratio",
1207 .data = &sysctl_lowmem_reserve_ratio,
1208 .maxlen = sizeof(sysctl_lowmem_reserve_ratio),
1209 .mode = 0644,
1210 .proc_handler = &lowmem_reserve_ratio_sysctl_handler,
1211 .strategy = &sysctl_intvec,
1212 },
1213 {
Andrew Morton9d0243b2006-01-08 01:00:39 -08001214 .ctl_name = VM_DROP_PAGECACHE,
1215 .procname = "drop_caches",
1216 .data = &sysctl_drop_caches,
1217 .maxlen = sizeof(int),
1218 .mode = 0644,
1219 .proc_handler = drop_caches_sysctl_handler,
1220 .strategy = &sysctl_intvec,
1221 },
1222 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 .ctl_name = VM_MIN_FREE_KBYTES,
1224 .procname = "min_free_kbytes",
1225 .data = &min_free_kbytes,
1226 .maxlen = sizeof(min_free_kbytes),
1227 .mode = 0644,
1228 .proc_handler = &min_free_kbytes_sysctl_handler,
1229 .strategy = &sysctl_intvec,
1230 .extra1 = &zero,
1231 },
Rohit Seth8ad4b1f2006-01-08 01:00:40 -08001232 {
Arve Hjønnevågc177d042009-02-17 14:51:02 -08001233 .ctl_name = CTL_UNNUMBERED,
1234 .procname = "min_free_order_shift",
1235 .data = &min_free_order_shift,
1236 .maxlen = sizeof(min_free_order_shift),
1237 .mode = 0644,
1238 .proc_handler = &proc_dointvec
1239 },
1240 {
Rohit Seth8ad4b1f2006-01-08 01:00:40 -08001241 .ctl_name = VM_PERCPU_PAGELIST_FRACTION,
1242 .procname = "percpu_pagelist_fraction",
1243 .data = &percpu_pagelist_fraction,
1244 .maxlen = sizeof(percpu_pagelist_fraction),
1245 .mode = 0644,
1246 .proc_handler = &percpu_pagelist_fraction_sysctl_handler,
1247 .strategy = &sysctl_intvec,
1248 .extra1 = &min_percpu_pagelist_fract,
1249 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250#ifdef CONFIG_MMU
1251 {
1252 .ctl_name = VM_MAX_MAP_COUNT,
1253 .procname = "max_map_count",
1254 .data = &sysctl_max_map_count,
1255 .maxlen = sizeof(sysctl_max_map_count),
1256 .mode = 0644,
1257 .proc_handler = &proc_dointvec
1258 },
Paul Mundtdd8632a2009-01-08 12:04:47 +00001259#else
1260 {
1261 .ctl_name = CTL_UNNUMBERED,
1262 .procname = "nr_trim_pages",
1263 .data = &sysctl_nr_trim_pages,
1264 .maxlen = sizeof(sysctl_nr_trim_pages),
1265 .mode = 0644,
1266 .proc_handler = &proc_dointvec_minmax,
1267 .strategy = &sysctl_intvec,
1268 .extra1 = &zero,
1269 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270#endif
1271 {
1272 .ctl_name = VM_LAPTOP_MODE,
1273 .procname = "laptop_mode",
1274 .data = &laptop_mode,
1275 .maxlen = sizeof(laptop_mode),
1276 .mode = 0644,
Bart Samweled5b43f2006-03-24 03:15:49 -08001277 .proc_handler = &proc_dointvec_jiffies,
1278 .strategy = &sysctl_jiffies,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 },
1280 {
1281 .ctl_name = VM_BLOCK_DUMP,
1282 .procname = "block_dump",
1283 .data = &block_dump,
1284 .maxlen = sizeof(block_dump),
1285 .mode = 0644,
1286 .proc_handler = &proc_dointvec,
1287 .strategy = &sysctl_intvec,
1288 .extra1 = &zero,
1289 },
1290 {
1291 .ctl_name = VM_VFS_CACHE_PRESSURE,
1292 .procname = "vfs_cache_pressure",
1293 .data = &sysctl_vfs_cache_pressure,
1294 .maxlen = sizeof(sysctl_vfs_cache_pressure),
1295 .mode = 0644,
1296 .proc_handler = &proc_dointvec,
1297 .strategy = &sysctl_intvec,
1298 .extra1 = &zero,
1299 },
1300#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
1301 {
1302 .ctl_name = VM_LEGACY_VA_LAYOUT,
1303 .procname = "legacy_va_layout",
1304 .data = &sysctl_legacy_va_layout,
1305 .maxlen = sizeof(sysctl_legacy_va_layout),
1306 .mode = 0644,
1307 .proc_handler = &proc_dointvec,
1308 .strategy = &sysctl_intvec,
1309 .extra1 = &zero,
1310 },
1311#endif
Christoph Lameter17436602006-01-18 17:42:32 -08001312#ifdef CONFIG_NUMA
1313 {
1314 .ctl_name = VM_ZONE_RECLAIM_MODE,
1315 .procname = "zone_reclaim_mode",
1316 .data = &zone_reclaim_mode,
1317 .maxlen = sizeof(zone_reclaim_mode),
1318 .mode = 0644,
1319 .proc_handler = &proc_dointvec,
Christoph Lameterc84db232006-02-01 03:05:29 -08001320 .strategy = &sysctl_intvec,
1321 .extra1 = &zero,
Christoph Lameter17436602006-01-18 17:42:32 -08001322 },
Christoph Lameter96146342006-07-03 00:24:13 -07001323 {
1324 .ctl_name = VM_MIN_UNMAPPED,
1325 .procname = "min_unmapped_ratio",
1326 .data = &sysctl_min_unmapped_ratio,
1327 .maxlen = sizeof(sysctl_min_unmapped_ratio),
1328 .mode = 0644,
1329 .proc_handler = &sysctl_min_unmapped_ratio_sysctl_handler,
1330 .strategy = &sysctl_intvec,
1331 .extra1 = &zero,
1332 .extra2 = &one_hundred,
1333 },
Christoph Lameter0ff38492006-09-25 23:31:52 -07001334 {
1335 .ctl_name = VM_MIN_SLAB,
1336 .procname = "min_slab_ratio",
1337 .data = &sysctl_min_slab_ratio,
1338 .maxlen = sizeof(sysctl_min_slab_ratio),
1339 .mode = 0644,
1340 .proc_handler = &sysctl_min_slab_ratio_sysctl_handler,
1341 .strategy = &sysctl_intvec,
1342 .extra1 = &zero,
1343 .extra2 = &one_hundred,
1344 },
Christoph Lameter17436602006-01-18 17:42:32 -08001345#endif
Christoph Lameter77461ab2007-05-09 02:35:13 -07001346#ifdef CONFIG_SMP
1347 {
1348 .ctl_name = CTL_UNNUMBERED,
1349 .procname = "stat_interval",
1350 .data = &sysctl_stat_interval,
1351 .maxlen = sizeof(sysctl_stat_interval),
1352 .mode = 0644,
1353 .proc_handler = &proc_dointvec_jiffies,
1354 .strategy = &sysctl_jiffies,
1355 },
1356#endif
Mike Frysinger71c77072010-01-08 00:40:42 -05001357#ifdef CONFIG_MMU
Eric Parised032182007-06-28 15:55:21 -04001358 {
1359 .ctl_name = CTL_UNNUMBERED,
1360 .procname = "mmap_min_addr",
Eric Paris788084a2009-07-31 12:54:11 -04001361 .data = &dac_mmap_min_addr,
1362 .maxlen = sizeof(unsigned long),
Eric Parised032182007-06-28 15:55:21 -04001363 .mode = 0644,
Eric Paris788084a2009-07-31 12:54:11 -04001364 .proc_handler = &mmap_min_addr_handler,
Eric Parised032182007-06-28 15:55:21 -04001365 },
David Howells03991232009-12-15 19:27:45 +00001366#endif
KAMEZAWA Hiroyukif0c0b2b2007-07-15 23:38:01 -07001367#ifdef CONFIG_NUMA
1368 {
1369 .ctl_name = CTL_UNNUMBERED,
1370 .procname = "numa_zonelist_order",
1371 .data = &numa_zonelist_order,
1372 .maxlen = NUMA_ZONELIST_ORDER_LEN,
1373 .mode = 0644,
1374 .proc_handler = &numa_zonelist_order_handler,
1375 .strategy = &sysctl_string,
1376 },
1377#endif
Al Viro2b8232c2007-10-13 08:16:04 +01001378#if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \
Paul Mundt5c36e652007-03-01 10:07:42 +09001379 (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
Ingo Molnare6e54942006-06-27 02:53:50 -07001380 {
1381 .ctl_name = VM_VDSO_ENABLED,
1382 .procname = "vdso_enabled",
1383 .data = &vdso_enabled,
1384 .maxlen = sizeof(vdso_enabled),
1385 .mode = 0644,
1386 .proc_handler = &proc_dointvec,
1387 .strategy = &sysctl_intvec,
1388 .extra1 = &zero,
1389 },
1390#endif
Bron Gondwana195cf452008-02-04 22:29:20 -08001391#ifdef CONFIG_HIGHMEM
1392 {
1393 .ctl_name = CTL_UNNUMBERED,
1394 .procname = "highmem_is_dirtyable",
1395 .data = &vm_highmem_is_dirtyable,
1396 .maxlen = sizeof(vm_highmem_is_dirtyable),
1397 .mode = 0644,
1398 .proc_handler = &proc_dointvec_minmax,
1399 .strategy = &sysctl_intvec,
1400 .extra1 = &zero,
1401 .extra2 = &one,
1402 },
1403#endif
Peter Zijlstra4be6f6b2009-04-13 14:39:33 -07001404 {
1405 .ctl_name = CTL_UNNUMBERED,
1406 .procname = "scan_unevictable_pages",
1407 .data = &scan_unevictable_pages,
1408 .maxlen = sizeof(scan_unevictable_pages),
1409 .mode = 0644,
1410 .proc_handler = &scan_unevictable_handler,
1411 },
Andi Kleen6a460792009-09-16 11:50:15 +02001412#ifdef CONFIG_MEMORY_FAILURE
1413 {
1414 .ctl_name = CTL_UNNUMBERED,
1415 .procname = "memory_failure_early_kill",
1416 .data = &sysctl_memory_failure_early_kill,
1417 .maxlen = sizeof(sysctl_memory_failure_early_kill),
1418 .mode = 0644,
1419 .proc_handler = &proc_dointvec_minmax,
1420 .strategy = &sysctl_intvec,
1421 .extra1 = &zero,
1422 .extra2 = &one,
1423 },
1424 {
1425 .ctl_name = CTL_UNNUMBERED,
1426 .procname = "memory_failure_recovery",
1427 .data = &sysctl_memory_failure_recovery,
1428 .maxlen = sizeof(sysctl_memory_failure_recovery),
1429 .mode = 0644,
1430 .proc_handler = &proc_dointvec_minmax,
1431 .strategy = &sysctl_intvec,
1432 .extra1 = &zero,
1433 .extra2 = &one,
1434 },
1435#endif
1436
Andrew Morton2be7fe02007-07-15 23:41:21 -07001437/*
1438 * NOTE: do not add new entries to this table unless you have read
1439 * Documentation/sysctl/ctl_unnumbered.txt
1440 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441 { .ctl_name = 0 }
1442};
1443
Eric W. Biederman2abc26f2007-02-14 00:34:07 -08001444#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001445static struct ctl_table binfmt_misc_table[] = {
Eric W. Biederman2abc26f2007-02-14 00:34:07 -08001446 { .ctl_name = 0 }
1447};
1448#endif
1449
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001450static struct ctl_table fs_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 {
1452 .ctl_name = FS_NRINODE,
1453 .procname = "inode-nr",
1454 .data = &inodes_stat,
1455 .maxlen = 2*sizeof(int),
1456 .mode = 0444,
1457 .proc_handler = &proc_dointvec,
1458 },
1459 {
1460 .ctl_name = FS_STATINODE,
1461 .procname = "inode-state",
1462 .data = &inodes_stat,
1463 .maxlen = 7*sizeof(int),
1464 .mode = 0444,
1465 .proc_handler = &proc_dointvec,
1466 },
1467 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 .procname = "file-nr",
1469 .data = &files_stat,
1470 .maxlen = 3*sizeof(int),
1471 .mode = 0444,
Dipankar Sarma529bf6b2006-03-07 21:55:35 -08001472 .proc_handler = &proc_nr_files,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 },
1474 {
1475 .ctl_name = FS_MAXFILE,
1476 .procname = "file-max",
1477 .data = &files_stat.max_files,
1478 .maxlen = sizeof(int),
1479 .mode = 0644,
1480 .proc_handler = &proc_dointvec,
1481 },
1482 {
Eric Dumazet9cfe0152008-02-06 01:37:16 -08001483 .ctl_name = CTL_UNNUMBERED,
1484 .procname = "nr_open",
1485 .data = &sysctl_nr_open,
1486 .maxlen = sizeof(int),
1487 .mode = 0644,
Al Viroeceea0b2008-05-10 10:08:32 -04001488 .proc_handler = &proc_dointvec_minmax,
1489 .extra1 = &sysctl_nr_open_min,
1490 .extra2 = &sysctl_nr_open_max,
Eric Dumazet9cfe0152008-02-06 01:37:16 -08001491 },
1492 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 .ctl_name = FS_DENTRY,
1494 .procname = "dentry-state",
1495 .data = &dentry_stat,
1496 .maxlen = 6*sizeof(int),
1497 .mode = 0444,
1498 .proc_handler = &proc_dointvec,
1499 },
1500 {
1501 .ctl_name = FS_OVERFLOWUID,
1502 .procname = "overflowuid",
1503 .data = &fs_overflowuid,
1504 .maxlen = sizeof(int),
1505 .mode = 0644,
1506 .proc_handler = &proc_dointvec_minmax,
1507 .strategy = &sysctl_intvec,
1508 .extra1 = &minolduid,
1509 .extra2 = &maxolduid,
1510 },
1511 {
1512 .ctl_name = FS_OVERFLOWGID,
1513 .procname = "overflowgid",
1514 .data = &fs_overflowgid,
1515 .maxlen = sizeof(int),
1516 .mode = 0644,
1517 .proc_handler = &proc_dointvec_minmax,
1518 .strategy = &sysctl_intvec,
1519 .extra1 = &minolduid,
1520 .extra2 = &maxolduid,
1521 },
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001522#ifdef CONFIG_FILE_LOCKING
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 {
1524 .ctl_name = FS_LEASES,
1525 .procname = "leases-enable",
1526 .data = &leases_enable,
1527 .maxlen = sizeof(int),
1528 .mode = 0644,
1529 .proc_handler = &proc_dointvec,
1530 },
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001531#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532#ifdef CONFIG_DNOTIFY
1533 {
1534 .ctl_name = FS_DIR_NOTIFY,
1535 .procname = "dir-notify-enable",
1536 .data = &dir_notify_enable,
1537 .maxlen = sizeof(int),
1538 .mode = 0644,
1539 .proc_handler = &proc_dointvec,
1540 },
1541#endif
1542#ifdef CONFIG_MMU
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001543#ifdef CONFIG_FILE_LOCKING
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 {
1545 .ctl_name = FS_LEASE_TIME,
1546 .procname = "lease-break-time",
1547 .data = &lease_break_time,
1548 .maxlen = sizeof(int),
1549 .mode = 0644,
Matthew Wilcox8e654fb2009-04-02 16:58:33 -07001550 .proc_handler = &proc_dointvec,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 },
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001552#endif
Thomas Petazzoniebf3f092008-10-15 22:05:12 -07001553#ifdef CONFIG_AIO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555 .procname = "aio-nr",
1556 .data = &aio_nr,
1557 .maxlen = sizeof(aio_nr),
1558 .mode = 0444,
Zach Brownd55b5fd2005-11-07 00:59:31 -08001559 .proc_handler = &proc_doulongvec_minmax,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 },
1561 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 .procname = "aio-max-nr",
1563 .data = &aio_max_nr,
1564 .maxlen = sizeof(aio_max_nr),
1565 .mode = 0644,
Zach Brownd55b5fd2005-11-07 00:59:31 -08001566 .proc_handler = &proc_doulongvec_minmax,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 },
Thomas Petazzoniebf3f092008-10-15 22:05:12 -07001568#endif /* CONFIG_AIO */
Amy Griffis2d9048e2006-06-01 13:10:59 -07001569#ifdef CONFIG_INOTIFY_USER
Robert Love0399cb02005-07-13 12:38:18 -04001570 {
1571 .ctl_name = FS_INOTIFY,
1572 .procname = "inotify",
1573 .mode = 0555,
1574 .child = inotify_table,
1575 },
1576#endif
Davide Libenzi7ef99642008-12-01 13:13:55 -08001577#ifdef CONFIG_EPOLL
1578 {
1579 .procname = "epoll",
1580 .mode = 0555,
1581 .child = epoll_table,
1582 },
1583#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584#endif
Alan Coxd6e71142005-06-23 00:09:43 -07001585 {
1586 .ctl_name = KERN_SETUID_DUMPABLE,
1587 .procname = "suid_dumpable",
1588 .data = &suid_dumpable,
1589 .maxlen = sizeof(int),
1590 .mode = 0644,
Matthew Wilcox8e654fb2009-04-02 16:58:33 -07001591 .proc_handler = &proc_dointvec_minmax,
1592 .strategy = &sysctl_intvec,
1593 .extra1 = &zero,
1594 .extra2 = &two,
Alan Coxd6e71142005-06-23 00:09:43 -07001595 },
Eric W. Biederman2abc26f2007-02-14 00:34:07 -08001596#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
1597 {
1598 .ctl_name = CTL_UNNUMBERED,
1599 .procname = "binfmt_misc",
1600 .mode = 0555,
1601 .child = binfmt_misc_table,
1602 },
1603#endif
Andrew Morton2be7fe02007-07-15 23:41:21 -07001604/*
1605 * NOTE: do not add new entries to this table unless you have read
1606 * Documentation/sysctl/ctl_unnumbered.txt
1607 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 { .ctl_name = 0 }
1609};
1610
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001611static struct ctl_table debug_table[] = {
Olof Johanssond0c3d532007-10-12 10:20:07 +10001612#if defined(CONFIG_X86) || defined(CONFIG_PPC)
Masoud Asgharifard Sharbianiabd4f752007-07-22 11:12:28 +02001613 {
1614 .ctl_name = CTL_UNNUMBERED,
1615 .procname = "exception-trace",
1616 .data = &show_unhandled_signals,
1617 .maxlen = sizeof(int),
1618 .mode = 0644,
WANG Cong4b6d2632009-12-17 15:27:05 -08001619 .proc_handler = proc_dointvec_minmax,
Amerigo Wang3ec268a2009-12-14 17:59:52 -08001620 .extra1 = &zero,
Masoud Asgharifard Sharbianiabd4f752007-07-22 11:12:28 +02001621 },
1622#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 { .ctl_name = 0 }
1624};
1625
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001626static struct ctl_table dev_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 { .ctl_name = 0 }
Robert Love0eeca282005-07-12 17:06:03 -04001628};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629
Al Viro330d57f2005-11-04 10:18:40 +00001630static DEFINE_SPINLOCK(sysctl_lock);
1631
1632/* called under sysctl_lock */
1633static int use_table(struct ctl_table_header *p)
1634{
1635 if (unlikely(p->unregistering))
1636 return 0;
1637 p->used++;
1638 return 1;
1639}
1640
1641/* called under sysctl_lock */
1642static void unuse_table(struct ctl_table_header *p)
1643{
1644 if (!--p->used)
1645 if (unlikely(p->unregistering))
1646 complete(p->unregistering);
1647}
1648
1649/* called under sysctl_lock, will reacquire if has to wait */
1650static void start_unregistering(struct ctl_table_header *p)
1651{
1652 /*
1653 * if p->used is 0, nobody will ever touch that entry again;
1654 * we'll eliminate all paths to it before dropping sysctl_lock
1655 */
1656 if (unlikely(p->used)) {
1657 struct completion wait;
1658 init_completion(&wait);
1659 p->unregistering = &wait;
1660 spin_unlock(&sysctl_lock);
1661 wait_for_completion(&wait);
1662 spin_lock(&sysctl_lock);
Al Virof7e6ced2008-07-15 01:44:23 -04001663 } else {
1664 /* anything non-NULL; we'll never dereference it */
1665 p->unregistering = ERR_PTR(-EINVAL);
Al Viro330d57f2005-11-04 10:18:40 +00001666 }
1667 /*
1668 * do not remove from the list until nobody holds it; walking the
1669 * list in do_sysctl() relies on that.
1670 */
1671 list_del_init(&p->ctl_entry);
1672}
1673
Al Virof7e6ced2008-07-15 01:44:23 -04001674void sysctl_head_get(struct ctl_table_header *head)
1675{
1676 spin_lock(&sysctl_lock);
1677 head->count++;
1678 spin_unlock(&sysctl_lock);
1679}
1680
1681void sysctl_head_put(struct ctl_table_header *head)
1682{
1683 spin_lock(&sysctl_lock);
1684 if (!--head->count)
1685 kfree(head);
1686 spin_unlock(&sysctl_lock);
1687}
1688
1689struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
1690{
1691 if (!head)
1692 BUG();
1693 spin_lock(&sysctl_lock);
1694 if (!use_table(head))
1695 head = ERR_PTR(-ENOENT);
1696 spin_unlock(&sysctl_lock);
1697 return head;
1698}
1699
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001700void sysctl_head_finish(struct ctl_table_header *head)
1701{
1702 if (!head)
1703 return;
1704 spin_lock(&sysctl_lock);
1705 unuse_table(head);
1706 spin_unlock(&sysctl_lock);
1707}
1708
Al Viro73455092008-07-14 21:22:20 -04001709static struct ctl_table_set *
1710lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces)
1711{
1712 struct ctl_table_set *set = &root->default_set;
1713 if (root->lookup)
1714 set = root->lookup(root, namespaces);
1715 return set;
1716}
1717
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001718static struct list_head *
1719lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001720{
Al Viro73455092008-07-14 21:22:20 -04001721 struct ctl_table_set *set = lookup_header_set(root, namespaces);
1722 return &set->list;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001723}
1724
1725struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
1726 struct ctl_table_header *prev)
1727{
1728 struct ctl_table_root *root;
1729 struct list_head *header_list;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001730 struct ctl_table_header *head;
1731 struct list_head *tmp;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001732
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001733 spin_lock(&sysctl_lock);
1734 if (prev) {
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001735 head = prev;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001736 tmp = &prev->ctl_entry;
1737 unuse_table(prev);
1738 goto next;
1739 }
1740 tmp = &root_table_header.ctl_entry;
1741 for (;;) {
1742 head = list_entry(tmp, struct ctl_table_header, ctl_entry);
1743
1744 if (!use_table(head))
1745 goto next;
1746 spin_unlock(&sysctl_lock);
1747 return head;
1748 next:
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001749 root = head->root;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001750 tmp = tmp->next;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001751 header_list = lookup_header_list(root, namespaces);
1752 if (tmp != header_list)
1753 continue;
1754
1755 do {
1756 root = list_entry(root->root_list.next,
1757 struct ctl_table_root, root_list);
1758 if (root == &sysctl_table_root)
1759 goto out;
1760 header_list = lookup_header_list(root, namespaces);
1761 } while (list_empty(header_list));
1762 tmp = header_list->next;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001763 }
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001764out:
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001765 spin_unlock(&sysctl_lock);
1766 return NULL;
1767}
1768
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001769struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
1770{
1771 return __sysctl_head_next(current->nsproxy, prev);
1772}
1773
1774void register_sysctl_root(struct ctl_table_root *root)
1775{
1776 spin_lock(&sysctl_lock);
1777 list_add_tail(&root->root_list, &sysctl_table_root.root_list);
1778 spin_unlock(&sysctl_lock);
1779}
1780
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07001781#ifdef CONFIG_SYSCTL_SYSCALL
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001782/* Perform the actual read/write of a sysctl table entry. */
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001783static int do_sysctl_strategy(struct ctl_table_root *root,
1784 struct ctl_table *table,
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001785 void __user *oldval, size_t __user *oldlenp,
1786 void __user *newval, size_t newlen)
1787{
1788 int op = 0, rc;
1789
1790 if (oldval)
Al Viroe6305c42008-07-15 21:03:57 -04001791 op |= MAY_READ;
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001792 if (newval)
Al Viroe6305c42008-07-15 21:03:57 -04001793 op |= MAY_WRITE;
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001794 if (sysctl_perm(root, table, op))
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001795 return -EPERM;
1796
1797 if (table->strategy) {
Alexey Dobriyanf221e722008-10-15 22:04:23 -07001798 rc = table->strategy(table, oldval, oldlenp, newval, newlen);
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001799 if (rc < 0)
1800 return rc;
1801 if (rc > 0)
1802 return 0;
1803 }
1804
1805 /* If there is no strategy routine, or if the strategy returns
1806 * zero, proceed with automatic r/w */
1807 if (table->data && table->maxlen) {
Alexey Dobriyanf221e722008-10-15 22:04:23 -07001808 rc = sysctl_data(table, oldval, oldlenp, newval, newlen);
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001809 if (rc < 0)
1810 return rc;
1811 }
1812 return 0;
1813}
1814
1815static int parse_table(int __user *name, int nlen,
1816 void __user *oldval, size_t __user *oldlenp,
1817 void __user *newval, size_t newlen,
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001818 struct ctl_table_root *root,
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001819 struct ctl_table *table)
1820{
1821 int n;
1822repeat:
1823 if (!nlen)
1824 return -ENOTDIR;
1825 if (get_user(n, name))
1826 return -EFAULT;
1827 for ( ; table->ctl_name || table->procname; table++) {
1828 if (!table->ctl_name)
1829 continue;
1830 if (n == table->ctl_name) {
1831 int error;
1832 if (table->child) {
Al Viroe6305c42008-07-15 21:03:57 -04001833 if (sysctl_perm(root, table, MAY_EXEC))
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001834 return -EPERM;
1835 name++;
1836 nlen--;
1837 table = table->child;
1838 goto repeat;
1839 }
Alexey Dobriyanf221e722008-10-15 22:04:23 -07001840 error = do_sysctl_strategy(root, table,
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001841 oldval, oldlenp,
1842 newval, newlen);
1843 return error;
1844 }
1845 }
1846 return -ENOTDIR;
1847}
1848
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp,
1850 void __user *newval, size_t newlen)
1851{
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001852 struct ctl_table_header *head;
Al Viro330d57f2005-11-04 10:18:40 +00001853 int error = -ENOTDIR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854
1855 if (nlen <= 0 || nlen >= CTL_MAXNAME)
1856 return -ENOTDIR;
1857 if (oldval) {
1858 int old_len;
1859 if (!oldlenp || get_user(old_len, oldlenp))
1860 return -EFAULT;
1861 }
Al Viro330d57f2005-11-04 10:18:40 +00001862
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001863 for (head = sysctl_head_next(NULL); head;
1864 head = sysctl_head_next(head)) {
Al Viro330d57f2005-11-04 10:18:40 +00001865 error = parse_table(name, nlen, oldval, oldlenp,
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001866 newval, newlen,
1867 head->root, head->ctl_table);
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001868 if (error != -ENOTDIR) {
1869 sysctl_head_finish(head);
Al Viro330d57f2005-11-04 10:18:40 +00001870 break;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001871 }
1872 }
Al Viro330d57f2005-11-04 10:18:40 +00001873 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874}
1875
Heiko Carstens1e7bfb22009-01-14 14:14:29 +01001876SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877{
1878 struct __sysctl_args tmp;
1879 int error;
1880
1881 if (copy_from_user(&tmp, args, sizeof(tmp)))
1882 return -EFAULT;
1883
Eric W. Biederman7058cb02007-10-18 03:05:58 -07001884 error = deprecated_sysctl_warning(&tmp);
1885 if (error)
1886 goto out;
1887
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 lock_kernel();
1889 error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
1890 tmp.newval, tmp.newlen);
1891 unlock_kernel();
Eric W. Biederman7058cb02007-10-18 03:05:58 -07001892out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 return error;
1894}
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07001895#endif /* CONFIG_SYSCTL_SYSCALL */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896
1897/*
Eric W. Biederman1ff007e2007-02-14 00:34:11 -08001898 * sysctl_perm does NOT grant the superuser all rights automatically, because
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 * some sysctl variables are readonly even to root.
1900 */
1901
1902static int test_perm(int mode, int op)
1903{
David Howells76aac0e2008-11-14 10:39:12 +11001904 if (!current_euid())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 mode >>= 6;
1906 else if (in_egroup_p(0))
1907 mode >>= 3;
Al Viroe6305c42008-07-15 21:03:57 -04001908 if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 return 0;
1910 return -EACCES;
1911}
1912
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001913int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914{
1915 int error;
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001916 int mode;
1917
Al Viroe6305c42008-07-15 21:03:57 -04001918 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 if (error)
1920 return error;
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001921
1922 if (root->permissions)
1923 mode = root->permissions(root, current->nsproxy, table);
1924 else
1925 mode = table->mode;
1926
1927 return test_perm(mode, op);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928}
1929
Eric W. Biedermand912b0c2007-02-14 00:34:13 -08001930static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
1931{
1932 for (; table->ctl_name || table->procname; table++) {
1933 table->parent = parent;
1934 if (table->child)
1935 sysctl_set_parent(table, table->child);
1936 }
1937}
1938
1939static __init int sysctl_init(void)
1940{
1941 sysctl_set_parent(NULL, root_table);
Holger Schurig88f458e2008-04-29 01:02:36 -07001942#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
1943 {
1944 int err;
1945 err = sysctl_check_table(current->nsproxy, root_table);
1946 }
1947#endif
Eric W. Biedermand912b0c2007-02-14 00:34:13 -08001948 return 0;
1949}
1950
1951core_initcall(sysctl_init);
1952
Al Virobfbcf032008-07-27 06:31:22 +01001953static struct ctl_table *is_branch_in(struct ctl_table *branch,
1954 struct ctl_table *table)
Al Viroae7edec2008-07-15 06:33:31 -04001955{
1956 struct ctl_table *p;
1957 const char *s = branch->procname;
1958
1959 /* branch should have named subdirectory as its first element */
1960 if (!s || !branch->child)
Al Virobfbcf032008-07-27 06:31:22 +01001961 return NULL;
Al Viroae7edec2008-07-15 06:33:31 -04001962
1963 /* ... and nothing else */
1964 if (branch[1].procname || branch[1].ctl_name)
Al Virobfbcf032008-07-27 06:31:22 +01001965 return NULL;
Al Viroae7edec2008-07-15 06:33:31 -04001966
1967 /* table should contain subdirectory with the same name */
1968 for (p = table; p->procname || p->ctl_name; p++) {
1969 if (!p->child)
1970 continue;
1971 if (p->procname && strcmp(p->procname, s) == 0)
Al Virobfbcf032008-07-27 06:31:22 +01001972 return p;
Al Viroae7edec2008-07-15 06:33:31 -04001973 }
Al Virobfbcf032008-07-27 06:31:22 +01001974 return NULL;
Al Viroae7edec2008-07-15 06:33:31 -04001975}
1976
1977/* see if attaching q to p would be an improvement */
1978static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)
1979{
1980 struct ctl_table *to = p->ctl_table, *by = q->ctl_table;
Al Virobfbcf032008-07-27 06:31:22 +01001981 struct ctl_table *next;
Al Viroae7edec2008-07-15 06:33:31 -04001982 int is_better = 0;
1983 int not_in_parent = !p->attached_by;
1984
Al Virobfbcf032008-07-27 06:31:22 +01001985 while ((next = is_branch_in(by, to)) != NULL) {
Al Viroae7edec2008-07-15 06:33:31 -04001986 if (by == q->attached_by)
1987 is_better = 1;
1988 if (to == p->attached_by)
1989 not_in_parent = 1;
1990 by = by->child;
Al Virobfbcf032008-07-27 06:31:22 +01001991 to = next->child;
Al Viroae7edec2008-07-15 06:33:31 -04001992 }
1993
1994 if (is_better && not_in_parent) {
1995 q->attached_by = by;
1996 q->attached_to = to;
1997 q->parent = p;
1998 }
1999}
2000
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001/**
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002002 * __register_sysctl_paths - register a sysctl hierarchy
2003 * @root: List of sysctl headers to register on
2004 * @namespaces: Data to compute which lists of sysctl entries are visible
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002005 * @path: The path to the directory the sysctl table is in.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006 * @table: the top-level table structure
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007 *
2008 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002009 * array. A completely 0 filled entry terminates the table.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010 *
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002011 * The members of the &struct ctl_table structure are used as follows:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012 *
2013 * ctl_name - This is the numeric sysctl value used by sysctl(2). The number
2014 * must be unique within that level of sysctl
2015 *
2016 * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
2017 * enter a sysctl file
2018 *
2019 * data - a pointer to data for use by proc_handler
2020 *
2021 * maxlen - the maximum size in bytes of the data
2022 *
2023 * mode - the file permissions for the /proc/sys file, and for sysctl(2)
2024 *
2025 * child - a pointer to the child sysctl table if this entry is a directory, or
2026 * %NULL.
2027 *
2028 * proc_handler - the text handler routine (described below)
2029 *
2030 * strategy - the strategy routine (described below)
2031 *
2032 * de - for internal use by the sysctl routines
2033 *
2034 * extra1, extra2 - extra pointers usable by the proc handler routines
2035 *
2036 * Leaf nodes in the sysctl tree will be represented by a single file
2037 * under /proc; non-leaf nodes will be represented by directories.
2038 *
2039 * sysctl(2) can automatically manage read and write requests through
2040 * the sysctl table. The data and maxlen fields of the ctl_table
2041 * struct enable minimal validation of the values being written to be
2042 * performed, and the mode field allows minimal authentication.
2043 *
2044 * More sophisticated management can be enabled by the provision of a
2045 * strategy routine with the table entry. This will be called before
2046 * any automatic read or write of the data is performed.
2047 *
2048 * The strategy routine may return
2049 *
2050 * < 0 - Error occurred (error is passed to user process)
2051 *
2052 * 0 - OK - proceed with automatic read or write.
2053 *
2054 * > 0 - OK - read or write has been done by the strategy routine, so
2055 * return immediately.
2056 *
2057 * There must be a proc_handler routine for any terminal nodes
2058 * mirrored under /proc/sys (non-terminals are handled by a built-in
2059 * directory handler). Several default handlers are available to
2060 * cover common cases -
2061 *
2062 * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
2063 * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(),
2064 * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax()
2065 *
2066 * It is the handler's job to read the input buffer from user memory
2067 * and process it. The handler should return 0 on success.
2068 *
2069 * This routine returns %NULL on a failure to register, and a pointer
2070 * to the table header on success.
2071 */
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002072struct ctl_table_header *__register_sysctl_paths(
2073 struct ctl_table_root *root,
2074 struct nsproxy *namespaces,
2075 const struct ctl_path *path, struct ctl_table *table)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076{
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002077 struct ctl_table_header *header;
2078 struct ctl_table *new, **prevp;
2079 unsigned int n, npath;
Al Viroae7edec2008-07-15 06:33:31 -04002080 struct ctl_table_set *set;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002081
2082 /* Count the path components */
2083 for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath)
2084 ;
2085
2086 /*
2087 * For each path component, allocate a 2-element ctl_table array.
2088 * The first array element will be filled with the sysctl entry
2089 * for this, the second will be the sentinel (ctl_name == 0).
2090 *
2091 * We allocate everything in one go so that we don't have to
2092 * worry about freeing additional memory in unregister_sysctl_table.
2093 */
2094 header = kzalloc(sizeof(struct ctl_table_header) +
2095 (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
2096 if (!header)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097 return NULL;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002098
2099 new = (struct ctl_table *) (header + 1);
2100
2101 /* Now connect the dots */
2102 prevp = &header->ctl_table;
2103 for (n = 0; n < npath; ++n, ++path) {
2104 /* Copy the procname */
2105 new->procname = path->procname;
2106 new->ctl_name = path->ctl_name;
2107 new->mode = 0555;
2108
2109 *prevp = new;
2110 prevp = &new->child;
2111
2112 new += 2;
2113 }
2114 *prevp = table;
Eric W. Biederman23eb06d2007-11-30 23:52:10 +11002115 header->ctl_table_arg = table;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002116
2117 INIT_LIST_HEAD(&header->ctl_entry);
2118 header->used = 0;
2119 header->unregistering = NULL;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002120 header->root = root;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002121 sysctl_set_parent(NULL, header->ctl_table);
Al Virof7e6ced2008-07-15 01:44:23 -04002122 header->count = 1;
Holger Schurig88f458e2008-04-29 01:02:36 -07002123#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002124 if (sysctl_check_table(namespaces, header->ctl_table)) {
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002125 kfree(header);
Eric W. Biedermanfc6cd252007-10-18 03:05:54 -07002126 return NULL;
2127 }
Holger Schurig88f458e2008-04-29 01:02:36 -07002128#endif
Al Viro330d57f2005-11-04 10:18:40 +00002129 spin_lock(&sysctl_lock);
Al Viro73455092008-07-14 21:22:20 -04002130 header->set = lookup_header_set(root, namespaces);
Al Viroae7edec2008-07-15 06:33:31 -04002131 header->attached_by = header->ctl_table;
2132 header->attached_to = root_table;
2133 header->parent = &root_table_header;
2134 for (set = header->set; set; set = set->parent) {
2135 struct ctl_table_header *p;
2136 list_for_each_entry(p, &set->list, ctl_entry) {
2137 if (p->unregistering)
2138 continue;
2139 try_attach(p, header);
2140 }
2141 }
2142 header->parent->count++;
Al Viro73455092008-07-14 21:22:20 -04002143 list_add_tail(&header->ctl_entry, &header->set->list);
Al Viro330d57f2005-11-04 10:18:40 +00002144 spin_unlock(&sysctl_lock);
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002145
2146 return header;
2147}
2148
2149/**
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002150 * register_sysctl_table_path - register a sysctl table hierarchy
2151 * @path: The path to the directory the sysctl table is in.
2152 * @table: the top-level table structure
2153 *
2154 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
2155 * array. A completely 0 filled entry terminates the table.
2156 *
2157 * See __register_sysctl_paths for more details.
2158 */
2159struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
2160 struct ctl_table *table)
2161{
2162 return __register_sysctl_paths(&sysctl_table_root, current->nsproxy,
2163 path, table);
2164}
2165
2166/**
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002167 * register_sysctl_table - register a sysctl table hierarchy
2168 * @table: the top-level table structure
2169 *
2170 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
2171 * array. A completely 0 filled entry terminates the table.
2172 *
2173 * See register_sysctl_paths for more details.
2174 */
2175struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
2176{
2177 static const struct ctl_path null_path[] = { {} };
2178
2179 return register_sysctl_paths(null_path, table);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180}
2181
2182/**
2183 * unregister_sysctl_table - unregister a sysctl table hierarchy
2184 * @header: the header returned from register_sysctl_table
2185 *
2186 * Unregisters the sysctl table and all children. proc entries may not
2187 * actually be removed until they are no longer used by anyone.
2188 */
2189void unregister_sysctl_table(struct ctl_table_header * header)
2190{
Al Viro330d57f2005-11-04 10:18:40 +00002191 might_sleep();
Pavel Emelyanovf1dad162007-12-04 23:45:24 -08002192
2193 if (header == NULL)
2194 return;
2195
Al Viro330d57f2005-11-04 10:18:40 +00002196 spin_lock(&sysctl_lock);
2197 start_unregistering(header);
Al Viroae7edec2008-07-15 06:33:31 -04002198 if (!--header->parent->count) {
2199 WARN_ON(1);
2200 kfree(header->parent);
2201 }
Al Virof7e6ced2008-07-15 01:44:23 -04002202 if (!--header->count)
2203 kfree(header);
Al Viro330d57f2005-11-04 10:18:40 +00002204 spin_unlock(&sysctl_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205}
2206
Al Viro90434762008-07-15 08:54:06 -04002207int sysctl_is_seen(struct ctl_table_header *p)
2208{
2209 struct ctl_table_set *set = p->set;
2210 int res;
2211 spin_lock(&sysctl_lock);
2212 if (p->unregistering)
2213 res = 0;
2214 else if (!set->is_seen)
2215 res = 1;
2216 else
2217 res = set->is_seen(set);
2218 spin_unlock(&sysctl_lock);
2219 return res;
2220}
2221
Al Viro73455092008-07-14 21:22:20 -04002222void setup_sysctl_set(struct ctl_table_set *p,
2223 struct ctl_table_set *parent,
2224 int (*is_seen)(struct ctl_table_set *))
2225{
2226 INIT_LIST_HEAD(&p->list);
2227 p->parent = parent ? parent : &sysctl_table_root.default_set;
2228 p->is_seen = is_seen;
2229}
2230
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002231#else /* !CONFIG_SYSCTL */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002232struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002233{
2234 return NULL;
2235}
2236
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002237struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
2238 struct ctl_table *table)
2239{
2240 return NULL;
2241}
2242
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002243void unregister_sysctl_table(struct ctl_table_header * table)
2244{
2245}
2246
Al Viro73455092008-07-14 21:22:20 -04002247void setup_sysctl_set(struct ctl_table_set *p,
2248 struct ctl_table_set *parent,
2249 int (*is_seen)(struct ctl_table_set *))
2250{
2251}
2252
Al Virof7e6ced2008-07-15 01:44:23 -04002253void sysctl_head_put(struct ctl_table_header *head)
2254{
2255}
2256
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002257#endif /* CONFIG_SYSCTL */
2258
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259/*
2260 * /proc/sys support
2261 */
2262
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002263#ifdef CONFIG_PROC_SYSCTL
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264
Adrian Bunkb1ba4dd2006-10-02 02:18:05 -07002265static int _proc_do_string(void* data, int maxlen, int write,
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002266 void __user *buffer,
Adrian Bunkb1ba4dd2006-10-02 02:18:05 -07002267 size_t *lenp, loff_t *ppos)
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002268{
2269 size_t len;
2270 char __user *p;
2271 char c;
Oleg Nesterov8d060872007-02-10 01:46:38 -08002272
2273 if (!data || !maxlen || !*lenp) {
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002274 *lenp = 0;
2275 return 0;
2276 }
Oleg Nesterov8d060872007-02-10 01:46:38 -08002277
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002278 if (write) {
2279 len = 0;
2280 p = buffer;
2281 while (len < *lenp) {
2282 if (get_user(c, p++))
2283 return -EFAULT;
2284 if (c == 0 || c == '\n')
2285 break;
2286 len++;
2287 }
2288 if (len >= maxlen)
2289 len = maxlen-1;
2290 if(copy_from_user(data, buffer, len))
2291 return -EFAULT;
2292 ((char *) data)[len] = 0;
2293 *ppos += *lenp;
2294 } else {
2295 len = strlen(data);
2296 if (len > maxlen)
2297 len = maxlen;
Oleg Nesterov8d060872007-02-10 01:46:38 -08002298
2299 if (*ppos > len) {
2300 *lenp = 0;
2301 return 0;
2302 }
2303
2304 data += *ppos;
2305 len -= *ppos;
2306
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002307 if (len > *lenp)
2308 len = *lenp;
2309 if (len)
2310 if(copy_to_user(buffer, data, len))
2311 return -EFAULT;
2312 if (len < *lenp) {
2313 if(put_user('\n', ((char __user *) buffer) + len))
2314 return -EFAULT;
2315 len++;
2316 }
2317 *lenp = len;
2318 *ppos += len;
2319 }
2320 return 0;
2321}
2322
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323/**
2324 * proc_dostring - read a string sysctl
2325 * @table: the sysctl table
2326 * @write: %TRUE if this is a write to the sysctl file
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327 * @buffer: the user buffer
2328 * @lenp: the size of the user buffer
2329 * @ppos: file position
2330 *
2331 * Reads/writes a string from/to the user buffer. If the kernel
2332 * buffer provided is not large enough to hold the string, the
2333 * string is truncated. The copied string is %NULL-terminated.
2334 * If the string is being read by the user process, it is copied
2335 * and a newline '\n' is added. It is truncated if the buffer is
2336 * not large enough.
2337 *
2338 * Returns 0 on success.
2339 */
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002340int proc_dostring(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341 void __user *buffer, size_t *lenp, loff_t *ppos)
2342{
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002343 return _proc_do_string(table->data, table->maxlen, write,
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002344 buffer, lenp, ppos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002345}
2346
Linus Torvalds1da177e2005-04-16 15:20:36 -07002347
2348static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
2349 int *valp,
2350 int write, void *data)
2351{
2352 if (write) {
2353 *valp = *negp ? -*lvalp : *lvalp;
2354 } else {
2355 int val = *valp;
2356 if (val < 0) {
2357 *negp = -1;
2358 *lvalp = (unsigned long)-val;
2359 } else {
2360 *negp = 0;
2361 *lvalp = (unsigned long)val;
2362 }
2363 }
2364 return 0;
2365}
2366
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002367static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002368 int write, void __user *buffer,
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002369 size_t *lenp, loff_t *ppos,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370 int (*conv)(int *negp, unsigned long *lvalp, int *valp,
2371 int write, void *data),
2372 void *data)
2373{
2374#define TMPBUFLEN 21
Sukanto Ghosh7338f292009-06-17 16:27:50 -07002375 int *i, vleft, first = 1, neg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376 unsigned long lval;
2377 size_t left, len;
2378
2379 char buf[TMPBUFLEN], *p;
2380 char __user *s = buffer;
2381
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002382 if (!tbl_data || !table->maxlen || !*lenp ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383 (*ppos && !write)) {
2384 *lenp = 0;
2385 return 0;
2386 }
2387
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002388 i = (int *) tbl_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389 vleft = table->maxlen / sizeof(*i);
2390 left = *lenp;
2391
2392 if (!conv)
2393 conv = do_proc_dointvec_conv;
2394
2395 for (; left && vleft--; i++, first=0) {
2396 if (write) {
2397 while (left) {
2398 char c;
2399 if (get_user(c, s))
2400 return -EFAULT;
2401 if (!isspace(c))
2402 break;
2403 left--;
2404 s++;
2405 }
2406 if (!left)
2407 break;
2408 neg = 0;
2409 len = left;
2410 if (len > sizeof(buf) - 1)
2411 len = sizeof(buf) - 1;
2412 if (copy_from_user(buf, s, len))
2413 return -EFAULT;
2414 buf[len] = 0;
2415 p = buf;
2416 if (*p == '-' && left > 1) {
2417 neg = 1;
BP, Praveenbd9b0ba2006-12-06 20:39:09 -08002418 p++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419 }
2420 if (*p < '0' || *p > '9')
2421 break;
2422
2423 lval = simple_strtoul(p, &p, 0);
2424
2425 len = p-buf;
2426 if ((len < left) && *p && !isspace(*p))
2427 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002428 s += len;
2429 left -= len;
2430
2431 if (conv(&neg, &lval, i, 1, data))
2432 break;
2433 } else {
2434 p = buf;
2435 if (!first)
2436 *p++ = '\t';
2437
2438 if (conv(&neg, &lval, i, 0, data))
2439 break;
2440
2441 sprintf(p, "%s%lu", neg ? "-" : "", lval);
2442 len = strlen(buf);
2443 if (len > left)
2444 len = left;
2445 if(copy_to_user(s, buf, len))
2446 return -EFAULT;
2447 left -= len;
2448 s += len;
2449 }
2450 }
2451
2452 if (!write && !first && left) {
2453 if(put_user('\n', s))
2454 return -EFAULT;
2455 left--, s++;
2456 }
2457 if (write) {
2458 while (left) {
2459 char c;
2460 if (get_user(c, s++))
2461 return -EFAULT;
2462 if (!isspace(c))
2463 break;
2464 left--;
2465 }
2466 }
2467 if (write && first)
2468 return -EINVAL;
2469 *lenp -= left;
2470 *ppos += *lenp;
2471 return 0;
2472#undef TMPBUFLEN
2473}
2474
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002475static int do_proc_dointvec(struct ctl_table *table, int write,
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002476 void __user *buffer, size_t *lenp, loff_t *ppos,
2477 int (*conv)(int *negp, unsigned long *lvalp, int *valp,
2478 int write, void *data),
2479 void *data)
2480{
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002481 return __do_proc_dointvec(table->data, table, write,
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002482 buffer, lenp, ppos, conv, data);
2483}
2484
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485/**
2486 * proc_dointvec - read a vector of integers
2487 * @table: the sysctl table
2488 * @write: %TRUE if this is a write to the sysctl file
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489 * @buffer: the user buffer
2490 * @lenp: the size of the user buffer
2491 * @ppos: file position
2492 *
2493 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2494 * values from/to the user buffer, treated as an ASCII string.
2495 *
2496 * Returns 0 on success.
2497 */
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002498int proc_dointvec(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 void __user *buffer, size_t *lenp, loff_t *ppos)
2500{
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002501 return do_proc_dointvec(table,write,buffer,lenp,ppos,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502 NULL,NULL);
2503}
2504
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002505/*
Andi Kleen25ddbb12008-10-15 22:01:41 -07002506 * Taint values can only be increased
2507 * This means we can safely use a temporary.
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002508 */
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002509static int proc_taint(struct ctl_table *table, int write,
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002510 void __user *buffer, size_t *lenp, loff_t *ppos)
2511{
Andi Kleen25ddbb12008-10-15 22:01:41 -07002512 struct ctl_table t;
2513 unsigned long tmptaint = get_taint();
2514 int err;
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002515
Bastian Blank91fcd412007-04-23 14:41:14 -07002516 if (write && !capable(CAP_SYS_ADMIN))
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002517 return -EPERM;
2518
Andi Kleen25ddbb12008-10-15 22:01:41 -07002519 t = *table;
2520 t.data = &tmptaint;
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002521 err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos);
Andi Kleen25ddbb12008-10-15 22:01:41 -07002522 if (err < 0)
2523 return err;
2524
2525 if (write) {
2526 /*
2527 * Poor man's atomic or. Not worth adding a primitive
2528 * to everyone's atomic.h for this
2529 */
2530 int i;
2531 for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
2532 if ((tmptaint >> i) & 1)
2533 add_taint(i);
2534 }
2535 }
2536
2537 return err;
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002538}
2539
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540struct do_proc_dointvec_minmax_conv_param {
2541 int *min;
2542 int *max;
2543};
2544
2545static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,
2546 int *valp,
2547 int write, void *data)
2548{
2549 struct do_proc_dointvec_minmax_conv_param *param = data;
2550 if (write) {
2551 int val = *negp ? -*lvalp : *lvalp;
2552 if ((param->min && *param->min > val) ||
2553 (param->max && *param->max < val))
2554 return -EINVAL;
2555 *valp = val;
2556 } else {
2557 int val = *valp;
2558 if (val < 0) {
2559 *negp = -1;
2560 *lvalp = (unsigned long)-val;
2561 } else {
2562 *negp = 0;
2563 *lvalp = (unsigned long)val;
2564 }
2565 }
2566 return 0;
2567}
2568
2569/**
2570 * proc_dointvec_minmax - read a vector of integers with min/max values
2571 * @table: the sysctl table
2572 * @write: %TRUE if this is a write to the sysctl file
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573 * @buffer: the user buffer
2574 * @lenp: the size of the user buffer
2575 * @ppos: file position
2576 *
2577 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2578 * values from/to the user buffer, treated as an ASCII string.
2579 *
2580 * This routine will ensure the values are within the range specified by
2581 * table->extra1 (min) and table->extra2 (max).
2582 *
2583 * Returns 0 on success.
2584 */
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002585int proc_dointvec_minmax(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002586 void __user *buffer, size_t *lenp, loff_t *ppos)
2587{
2588 struct do_proc_dointvec_minmax_conv_param param = {
2589 .min = (int *) table->extra1,
2590 .max = (int *) table->extra2,
2591 };
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002592 return do_proc_dointvec(table, write, buffer, lenp, ppos,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593 do_proc_dointvec_minmax_conv, &param);
2594}
2595
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002596static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597 void __user *buffer,
2598 size_t *lenp, loff_t *ppos,
2599 unsigned long convmul,
2600 unsigned long convdiv)
2601{
2602#define TMPBUFLEN 21
2603 unsigned long *i, *min, *max, val;
2604 int vleft, first=1, neg;
2605 size_t len, left;
2606 char buf[TMPBUFLEN], *p;
2607 char __user *s = buffer;
2608
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002609 if (!data || !table->maxlen || !*lenp ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002610 (*ppos && !write)) {
2611 *lenp = 0;
2612 return 0;
2613 }
2614
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002615 i = (unsigned long *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002616 min = (unsigned long *) table->extra1;
2617 max = (unsigned long *) table->extra2;
2618 vleft = table->maxlen / sizeof(unsigned long);
2619 left = *lenp;
2620
2621 for (; left && vleft--; i++, min++, max++, first=0) {
2622 if (write) {
2623 while (left) {
2624 char c;
2625 if (get_user(c, s))
2626 return -EFAULT;
2627 if (!isspace(c))
2628 break;
2629 left--;
2630 s++;
2631 }
2632 if (!left)
2633 break;
2634 neg = 0;
2635 len = left;
2636 if (len > TMPBUFLEN-1)
2637 len = TMPBUFLEN-1;
2638 if (copy_from_user(buf, s, len))
2639 return -EFAULT;
2640 buf[len] = 0;
2641 p = buf;
2642 if (*p == '-' && left > 1) {
2643 neg = 1;
BP, Praveenbd9b0ba2006-12-06 20:39:09 -08002644 p++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645 }
2646 if (*p < '0' || *p > '9')
2647 break;
2648 val = simple_strtoul(p, &p, 0) * convmul / convdiv ;
2649 len = p-buf;
2650 if ((len < left) && *p && !isspace(*p))
2651 break;
2652 if (neg)
2653 val = -val;
2654 s += len;
2655 left -= len;
2656
2657 if(neg)
2658 continue;
2659 if ((min && val < *min) || (max && val > *max))
2660 continue;
2661 *i = val;
2662 } else {
2663 p = buf;
2664 if (!first)
2665 *p++ = '\t';
2666 sprintf(p, "%lu", convdiv * (*i) / convmul);
2667 len = strlen(buf);
2668 if (len > left)
2669 len = left;
2670 if(copy_to_user(s, buf, len))
2671 return -EFAULT;
2672 left -= len;
2673 s += len;
2674 }
2675 }
2676
2677 if (!write && !first && left) {
2678 if(put_user('\n', s))
2679 return -EFAULT;
2680 left--, s++;
2681 }
2682 if (write) {
2683 while (left) {
2684 char c;
2685 if (get_user(c, s++))
2686 return -EFAULT;
2687 if (!isspace(c))
2688 break;
2689 left--;
2690 }
2691 }
2692 if (write && first)
2693 return -EINVAL;
2694 *lenp -= left;
2695 *ppos += *lenp;
2696 return 0;
2697#undef TMPBUFLEN
2698}
2699
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002700static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002701 void __user *buffer,
2702 size_t *lenp, loff_t *ppos,
2703 unsigned long convmul,
2704 unsigned long convdiv)
2705{
2706 return __do_proc_doulongvec_minmax(table->data, table, write,
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002707 buffer, lenp, ppos, convmul, convdiv);
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002708}
2709
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710/**
2711 * proc_doulongvec_minmax - read a vector of long integers with min/max values
2712 * @table: the sysctl table
2713 * @write: %TRUE if this is a write to the sysctl file
Linus Torvalds1da177e2005-04-16 15:20:36 -07002714 * @buffer: the user buffer
2715 * @lenp: the size of the user buffer
2716 * @ppos: file position
2717 *
2718 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
2719 * values from/to the user buffer, treated as an ASCII string.
2720 *
2721 * This routine will ensure the values are within the range specified by
2722 * table->extra1 (min) and table->extra2 (max).
2723 *
2724 * Returns 0 on success.
2725 */
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002726int proc_doulongvec_minmax(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727 void __user *buffer, size_t *lenp, loff_t *ppos)
2728{
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002729 return do_proc_doulongvec_minmax(table, write, buffer, lenp, ppos, 1l, 1l);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730}
2731
2732/**
2733 * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
2734 * @table: the sysctl table
2735 * @write: %TRUE if this is a write to the sysctl file
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736 * @buffer: the user buffer
2737 * @lenp: the size of the user buffer
2738 * @ppos: file position
2739 *
2740 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
2741 * values from/to the user buffer, treated as an ASCII string. The values
2742 * are treated as milliseconds, and converted to jiffies when they are stored.
2743 *
2744 * This routine will ensure the values are within the range specified by
2745 * table->extra1 (min) and table->extra2 (max).
2746 *
2747 * Returns 0 on success.
2748 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002749int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750 void __user *buffer,
2751 size_t *lenp, loff_t *ppos)
2752{
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002753 return do_proc_doulongvec_minmax(table, write, buffer,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754 lenp, ppos, HZ, 1000l);
2755}
2756
2757
2758static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp,
2759 int *valp,
2760 int write, void *data)
2761{
2762 if (write) {
Bart Samwelcba9f332006-03-24 03:15:50 -08002763 if (*lvalp > LONG_MAX / HZ)
2764 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765 *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ);
2766 } else {
2767 int val = *valp;
2768 unsigned long lval;
2769 if (val < 0) {
2770 *negp = -1;
2771 lval = (unsigned long)-val;
2772 } else {
2773 *negp = 0;
2774 lval = (unsigned long)val;
2775 }
2776 *lvalp = lval / HZ;
2777 }
2778 return 0;
2779}
2780
2781static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp,
2782 int *valp,
2783 int write, void *data)
2784{
2785 if (write) {
Bart Samwelcba9f332006-03-24 03:15:50 -08002786 if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ)
2787 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002788 *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp);
2789 } else {
2790 int val = *valp;
2791 unsigned long lval;
2792 if (val < 0) {
2793 *negp = -1;
2794 lval = (unsigned long)-val;
2795 } else {
2796 *negp = 0;
2797 lval = (unsigned long)val;
2798 }
2799 *lvalp = jiffies_to_clock_t(lval);
2800 }
2801 return 0;
2802}
2803
2804static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,
2805 int *valp,
2806 int write, void *data)
2807{
2808 if (write) {
2809 *valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp);
2810 } else {
2811 int val = *valp;
2812 unsigned long lval;
2813 if (val < 0) {
2814 *negp = -1;
2815 lval = (unsigned long)-val;
2816 } else {
2817 *negp = 0;
2818 lval = (unsigned long)val;
2819 }
2820 *lvalp = jiffies_to_msecs(lval);
2821 }
2822 return 0;
2823}
2824
2825/**
2826 * proc_dointvec_jiffies - read a vector of integers as seconds
2827 * @table: the sysctl table
2828 * @write: %TRUE if this is a write to the sysctl file
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 * @buffer: the user buffer
2830 * @lenp: the size of the user buffer
2831 * @ppos: file position
2832 *
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 seconds, and are converted into
2836 * jiffies.
2837 *
2838 * Returns 0 on success.
2839 */
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002840int proc_dointvec_jiffies(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841 void __user *buffer, size_t *lenp, loff_t *ppos)
2842{
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002843 return do_proc_dointvec(table,write,buffer,lenp,ppos,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002844 do_proc_dointvec_jiffies_conv,NULL);
2845}
2846
2847/**
2848 * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
2849 * @table: the sysctl table
2850 * @write: %TRUE if this is a write to the sysctl file
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851 * @buffer: the user buffer
2852 * @lenp: the size of the user buffer
Randy Dunlap1e5d5332005-11-07 01:01:06 -08002853 * @ppos: pointer to the file position
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854 *
2855 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2856 * values from/to the user buffer, treated as an ASCII string.
2857 * The values read are assumed to be in 1/USER_HZ seconds, and
2858 * are converted into jiffies.
2859 *
2860 * Returns 0 on success.
2861 */
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002862int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863 void __user *buffer, size_t *lenp, loff_t *ppos)
2864{
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002865 return do_proc_dointvec(table,write,buffer,lenp,ppos,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 do_proc_dointvec_userhz_jiffies_conv,NULL);
2867}
2868
2869/**
2870 * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds
2871 * @table: the sysctl table
2872 * @write: %TRUE if this is a write to the sysctl file
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873 * @buffer: the user buffer
2874 * @lenp: the size of the user buffer
Martin Waitz67be2dd2005-05-01 08:59:26 -07002875 * @ppos: file position
2876 * @ppos: the current position in the file
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877 *
2878 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2879 * values from/to the user buffer, treated as an ASCII string.
2880 * The values read are assumed to be in 1/1000 seconds, and
2881 * are converted into jiffies.
2882 *
2883 * Returns 0 on success.
2884 */
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002885int proc_dointvec_ms_jiffies(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002886 void __user *buffer, size_t *lenp, loff_t *ppos)
2887{
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002888 return do_proc_dointvec(table, write, buffer, lenp, ppos,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889 do_proc_dointvec_ms_jiffies_conv, NULL);
2890}
2891
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002892static int proc_do_cad_pid(struct ctl_table *table, int write,
Cedric Le Goater9ec52092006-10-02 02:19:00 -07002893 void __user *buffer, size_t *lenp, loff_t *ppos)
2894{
2895 struct pid *new_pid;
2896 pid_t tmp;
2897 int r;
2898
Pavel Emelyanov6c5f3e72008-02-08 04:19:20 -08002899 tmp = pid_vnr(cad_pid);
Cedric Le Goater9ec52092006-10-02 02:19:00 -07002900
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002901 r = __do_proc_dointvec(&tmp, table, write, buffer,
Cedric Le Goater9ec52092006-10-02 02:19:00 -07002902 lenp, ppos, NULL, NULL);
2903 if (r || !write)
2904 return r;
2905
2906 new_pid = find_get_pid(tmp);
2907 if (!new_pid)
2908 return -ESRCH;
2909
2910 put_pid(xchg(&cad_pid, new_pid));
2911 return 0;
2912}
2913
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914#else /* CONFIG_PROC_FS */
2915
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002916int proc_dostring(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917 void __user *buffer, size_t *lenp, loff_t *ppos)
2918{
2919 return -ENOSYS;
2920}
2921
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002922int proc_dointvec(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923 void __user *buffer, size_t *lenp, loff_t *ppos)
2924{
2925 return -ENOSYS;
2926}
2927
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002928int proc_dointvec_minmax(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 void __user *buffer, size_t *lenp, loff_t *ppos)
2930{
2931 return -ENOSYS;
2932}
2933
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002934int proc_dointvec_jiffies(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 void __user *buffer, size_t *lenp, loff_t *ppos)
2936{
2937 return -ENOSYS;
2938}
2939
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002940int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941 void __user *buffer, size_t *lenp, loff_t *ppos)
2942{
2943 return -ENOSYS;
2944}
2945
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002946int proc_dointvec_ms_jiffies(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002947 void __user *buffer, size_t *lenp, loff_t *ppos)
2948{
2949 return -ENOSYS;
2950}
2951
Alexey Dobriyan8d65af72009-09-23 15:57:19 -07002952int proc_doulongvec_minmax(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 void __user *buffer, size_t *lenp, loff_t *ppos)
2954{
2955 return -ENOSYS;
2956}
2957
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002958int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959 void __user *buffer,
2960 size_t *lenp, loff_t *ppos)
2961{
2962 return -ENOSYS;
2963}
2964
2965
2966#endif /* CONFIG_PROC_FS */
2967
2968
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002969#ifdef CONFIG_SYSCTL_SYSCALL
Linus Torvalds1da177e2005-04-16 15:20:36 -07002970/*
2971 * General sysctl support routines
2972 */
2973
Eric W. Biederman49a0c452007-10-18 03:05:23 -07002974/* The generic sysctl data routine (used if no strategy routine supplied) */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07002975int sysctl_data(struct ctl_table *table,
Eric W. Biederman49a0c452007-10-18 03:05:23 -07002976 void __user *oldval, size_t __user *oldlenp,
2977 void __user *newval, size_t newlen)
2978{
2979 size_t len;
2980
2981 /* Get out of I don't have a variable */
2982 if (!table->data || !table->maxlen)
2983 return -ENOTDIR;
2984
2985 if (oldval && oldlenp) {
2986 if (get_user(len, oldlenp))
2987 return -EFAULT;
2988 if (len) {
2989 if (len > table->maxlen)
2990 len = table->maxlen;
2991 if (copy_to_user(oldval, table->data, len))
2992 return -EFAULT;
2993 if (put_user(len, oldlenp))
2994 return -EFAULT;
2995 }
2996 }
2997
2998 if (newval && newlen) {
2999 if (newlen > table->maxlen)
3000 newlen = table->maxlen;
3001
3002 if (copy_from_user(table->data, newval, newlen))
3003 return -EFAULT;
3004 }
3005 return 1;
3006}
3007
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008/* The generic string strategy routine: */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003009int sysctl_string(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003011 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013 if (!table->data || !table->maxlen)
3014 return -ENOTDIR;
3015
3016 if (oldval && oldlenp) {
Linus Torvaldsde9e0072005-12-31 17:00:29 -08003017 size_t bufsize;
3018 if (get_user(bufsize, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003019 return -EFAULT;
Linus Torvaldsde9e0072005-12-31 17:00:29 -08003020 if (bufsize) {
3021 size_t len = strlen(table->data), copied;
3022
3023 /* This shouldn't trigger for a well-formed sysctl */
3024 if (len > table->maxlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003025 len = table->maxlen;
Linus Torvaldsde9e0072005-12-31 17:00:29 -08003026
3027 /* Copy up to a max of bufsize-1 bytes of the string */
3028 copied = (len >= bufsize) ? bufsize - 1 : len;
3029
3030 if (copy_to_user(oldval, table->data, copied) ||
3031 put_user(0, (char __user *)(oldval + copied)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003032 return -EFAULT;
Linus Torvaldsde9e0072005-12-31 17:00:29 -08003033 if (put_user(len, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003034 return -EFAULT;
3035 }
3036 }
3037 if (newval && newlen) {
Linus Torvaldsde9e0072005-12-31 17:00:29 -08003038 size_t len = newlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003039 if (len > table->maxlen)
3040 len = table->maxlen;
3041 if(copy_from_user(table->data, newval, len))
3042 return -EFAULT;
3043 if (len == table->maxlen)
3044 len--;
3045 ((char *) table->data)[len] = 0;
3046 }
Yi Yang82c9df82005-12-30 16:37:10 +08003047 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003048}
3049
3050/*
3051 * This function makes sure that all of the integers in the vector
3052 * are between the minimum and maximum values given in the arrays
3053 * table->extra1 and table->extra2, respectively.
3054 */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003055int sysctl_intvec(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003056 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003057 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003058{
3059
3060 if (newval && newlen) {
3061 int __user *vec = (int __user *) newval;
3062 int *min = (int *) table->extra1;
3063 int *max = (int *) table->extra2;
3064 size_t length;
3065 int i;
3066
3067 if (newlen % sizeof(int) != 0)
3068 return -EINVAL;
3069
3070 if (!table->extra1 && !table->extra2)
3071 return 0;
3072
3073 if (newlen > table->maxlen)
3074 newlen = table->maxlen;
3075 length = newlen / sizeof(int);
3076
3077 for (i = 0; i < length; i++) {
3078 int value;
3079 if (get_user(value, vec + i))
3080 return -EFAULT;
3081 if (min && value < min[i])
3082 return -EINVAL;
3083 if (max && value > max[i])
3084 return -EINVAL;
3085 }
3086 }
3087 return 0;
3088}
3089
3090/* Strategy function to convert jiffies to seconds */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003091int sysctl_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003092 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003093 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003094{
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003095 if (oldval && oldlenp) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096 size_t olen;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003097
3098 if (get_user(olen, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003099 return -EFAULT;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003100 if (olen) {
3101 int val;
3102
3103 if (olen < sizeof(int))
3104 return -EINVAL;
3105
3106 val = *(int *)(table->data) / HZ;
3107 if (put_user(val, (int __user *)oldval))
3108 return -EFAULT;
3109 if (put_user(sizeof(int), oldlenp))
3110 return -EFAULT;
3111 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003112 }
3113 if (newval && newlen) {
3114 int new;
3115 if (newlen != sizeof(int))
3116 return -EINVAL;
3117 if (get_user(new, (int __user *)newval))
3118 return -EFAULT;
3119 *(int *)(table->data) = new*HZ;
3120 }
3121 return 1;
3122}
3123
3124/* Strategy function to convert jiffies to seconds */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003125int sysctl_ms_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003126 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003127 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003128{
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003129 if (oldval && oldlenp) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130 size_t olen;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003131
3132 if (get_user(olen, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003133 return -EFAULT;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003134 if (olen) {
3135 int val;
3136
3137 if (olen < sizeof(int))
3138 return -EINVAL;
3139
3140 val = jiffies_to_msecs(*(int *)(table->data));
3141 if (put_user(val, (int __user *)oldval))
3142 return -EFAULT;
3143 if (put_user(sizeof(int), oldlenp))
3144 return -EFAULT;
3145 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146 }
3147 if (newval && newlen) {
3148 int new;
3149 if (newlen != sizeof(int))
3150 return -EINVAL;
3151 if (get_user(new, (int __user *)newval))
3152 return -EFAULT;
3153 *(int *)(table->data) = msecs_to_jiffies(new);
3154 }
3155 return 1;
3156}
3157
Eric W. Biedermanc4b8b762006-12-08 02:39:55 -08003158
Eric W. Biedermanc4b8b762006-12-08 02:39:55 -08003159
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07003160#else /* CONFIG_SYSCTL_SYSCALL */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161
3162
Heiko Carstens1e7bfb22009-01-14 14:14:29 +01003163SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003164{
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003165 struct __sysctl_args tmp;
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003166 int error;
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003167
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003168 if (copy_from_user(&tmp, args, sizeof(tmp)))
3169 return -EFAULT;
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003170
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003171 error = deprecated_sysctl_warning(&tmp);
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07003172
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003173 /* If no error reading the parameters then just -ENOSYS ... */
3174 if (!error)
3175 error = -ENOSYS;
3176
3177 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178}
3179
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003180int sysctl_data(struct ctl_table *table,
Eric W. Biederman49a0c452007-10-18 03:05:23 -07003181 void __user *oldval, size_t __user *oldlenp,
3182 void __user *newval, size_t newlen)
3183{
3184 return -ENOSYS;
3185}
3186
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003187int sysctl_string(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003189 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190{
3191 return -ENOSYS;
3192}
3193
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003194int sysctl_intvec(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003196 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003197{
3198 return -ENOSYS;
3199}
3200
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003201int sysctl_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003202 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003203 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003204{
3205 return -ENOSYS;
3206}
3207
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003208int sysctl_ms_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003209 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003210 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003211{
3212 return -ENOSYS;
3213}
3214
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07003215#endif /* CONFIG_SYSCTL_SYSCALL */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003216
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003217static int deprecated_sysctl_warning(struct __sysctl_args *args)
3218{
3219 static int msg_count;
3220 int name[CTL_MAXNAME];
3221 int i;
3222
Tetsuo Handa6fc48af2007-11-14 16:58:38 -08003223 /* Check args->nlen. */
3224 if (args->nlen < 0 || args->nlen > CTL_MAXNAME)
3225 return -ENOTDIR;
3226
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003227 /* Read in the sysctl name for better debug message logging */
3228 for (i = 0; i < args->nlen; i++)
3229 if (get_user(name[i], args->name + i))
3230 return -EFAULT;
3231
3232 /* Ignore accesses to kernel.version */
3233 if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
3234 return 0;
3235
3236 if (msg_count < 5) {
3237 msg_count++;
3238 printk(KERN_INFO
3239 "warning: process `%s' used the deprecated sysctl "
3240 "system call with ", current->comm);
3241 for (i = 0; i < args->nlen; i++)
3242 printk("%d.", name[i]);
3243 printk("\n");
3244 }
3245 return 0;
3246}
3247
Linus Torvalds1da177e2005-04-16 15:20:36 -07003248/*
3249 * No sense putting this after each symbol definition, twice,
3250 * exception granted :-)
3251 */
3252EXPORT_SYMBOL(proc_dointvec);
3253EXPORT_SYMBOL(proc_dointvec_jiffies);
3254EXPORT_SYMBOL(proc_dointvec_minmax);
3255EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
3256EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
3257EXPORT_SYMBOL(proc_dostring);
3258EXPORT_SYMBOL(proc_doulongvec_minmax);
3259EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
3260EXPORT_SYMBOL(register_sysctl_table);
Eric W. Biederman29e796f2007-11-30 23:50:18 +11003261EXPORT_SYMBOL(register_sysctl_paths);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003262EXPORT_SYMBOL(sysctl_intvec);
3263EXPORT_SYMBOL(sysctl_jiffies);
3264EXPORT_SYMBOL(sysctl_ms_jiffies);
3265EXPORT_SYMBOL(sysctl_string);
Eric W. Biederman49a0c452007-10-18 03:05:23 -07003266EXPORT_SYMBOL(sysctl_data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003267EXPORT_SYMBOL(unregister_sysctl_table);