blob: 3125cff1c570d8f0797b79ddce8c0b94f6f8df70 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * sysctl.c: General linux system control interface
3 *
4 * Begun 24 March 1995, Stephen Tweedie
5 * Added /proc support, Dec 1995
6 * Added bdflush entry and intvec min/max checking, 2/23/96, Tom Dyas.
7 * Added hooks for /proc/sys/net (minor, minor patch), 96/4/1, Mike Shaver.
8 * Added kernel/java-{interpreter,appletviewer}, 96/5/10, Mike Shaver.
9 * Dynamic registration fixes, Stephen Tweedie.
10 * Added kswapd-interval, ctrl-alt-del, printk stuff, 1/8/97, Chris Horn.
11 * Made sysctl support optional via CONFIG_SYSCTL, 1/10/97, Chris
12 * Horn.
13 * Added proc_doulongvec_ms_jiffies_minmax, 09/08/99, Carlos H. Bauer.
14 * Added proc_doulongvec_minmax, 09/08/99, Carlos H. Bauer.
15 * Changed linked lists to use list.h instead of lists.h, 02/24/00, Bill
16 * Wendling.
17 * The list_for_each() macro wasn't appropriate for the sysctl loop.
18 * Removed it and replaced it with older style, 03/23/00, Bill Wendling
19 */
20
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <linux/module.h>
22#include <linux/mm.h>
23#include <linux/swap.h>
24#include <linux/slab.h>
25#include <linux/sysctl.h>
26#include <linux/proc_fs.h>
Andrew Morgan72c2d582007-10-18 03:05:59 -070027#include <linux/security.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/ctype.h>
29#include <linux/utsname.h>
Vegard Nossumdfec0722008-04-04 00:51:41 +020030#include <linux/kmemcheck.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/smp_lock.h>
Adrian Bunk62239ac2007-07-17 04:03:45 -070032#include <linux/fs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/init.h>
34#include <linux/kernel.h>
Kay Sievers0296b222005-11-11 05:33:52 +010035#include <linux/kobject.h>
Arnaldo Carvalho de Melo20380732005-08-16 02:18:02 -030036#include <linux/net.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <linux/sysrq.h>
38#include <linux/highuid.h>
39#include <linux/writeback.h>
40#include <linux/hugetlb.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/initrd.h>
David Howells0b77f5b2008-04-29 01:01:32 -070042#include <linux/key.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <linux/times.h>
44#include <linux/limits.h>
45#include <linux/dcache.h>
46#include <linux/syscalls.h>
Adrian Bunkc748e132008-07-23 21:27:03 -070047#include <linux/vmstat.h>
Pavel Machekc255d842006-02-20 18:27:58 -080048#include <linux/nfs_fs.h>
49#include <linux/acpi.h>
Jeremy Fitzhardinge10a0a8d2007-07-17 18:37:02 -070050#include <linux/reboot.h>
Steven Rostedtb0fc4942008-05-12 21:20:43 +020051#include <linux/ftrace.h>
David Howells12e22c52009-04-03 16:42:35 +010052#include <linux/slow-work.h>
Peter Zijlstra1ccd1542009-04-09 10:53:45 +020053#include <linux/perf_counter.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55#include <asm/uaccess.h>
56#include <asm/processor.h>
57
Andi Kleen29cbc782006-09-30 01:47:55 +020058#ifdef CONFIG_X86
59#include <asm/nmi.h>
Chuck Ebbert0741f4d2006-12-07 02:14:11 +010060#include <asm/stacktrace.h>
Ingo Molnar6e7c4022008-01-30 13:30:05 +010061#include <asm/io.h>
Andi Kleen29cbc782006-09-30 01:47:55 +020062#endif
63
Eric W. Biederman7058cb02007-10-18 03:05:58 -070064static int deprecated_sysctl_warning(struct __sysctl_args *args);
65
Linus Torvalds1da177e2005-04-16 15:20:36 -070066#if defined(CONFIG_SYSCTL)
67
68/* External variables not in a header file. */
69extern int C_A_D;
Ingo Molnar45807a12007-07-15 23:40:10 -070070extern int print_fatal_signals;
Linus Torvalds1da177e2005-04-16 15:20:36 -070071extern int sysctl_overcommit_memory;
72extern int sysctl_overcommit_ratio;
KAMEZAWA Hiroyukifadd8fb2006-06-23 02:03:13 -070073extern int sysctl_panic_on_oom;
David Rientjesfe071d72007-10-16 23:25:56 -070074extern int sysctl_oom_kill_allocating_task;
David Rientjesfef1bdd2008-02-07 00:14:07 -080075extern int sysctl_oom_dump_tasks;
Linus Torvalds1da177e2005-04-16 15:20:36 -070076extern int max_threads;
Linus Torvalds1da177e2005-04-16 15:20:36 -070077extern int core_uses_pid;
Alan Coxd6e71142005-06-23 00:09:43 -070078extern int suid_dumpable;
Linus Torvalds1da177e2005-04-16 15:20:36 -070079extern char core_pattern[];
Linus Torvalds1da177e2005-04-16 15:20:36 -070080extern int pid_max;
81extern int min_free_kbytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082extern int pid_max_min, pid_max_max;
Andrew Morton9d0243b2006-01-08 01:00:39 -080083extern int sysctl_drop_caches;
Rohit Seth8ad4b1f2006-01-08 01:00:40 -080084extern int percpu_pagelist_fraction;
Andi Kleenbebfa102006-06-26 13:56:52 +020085extern int compat_log;
Arjan van de Ven97455122008-01-25 21:08:34 +010086extern int latencytop_enabled;
Al Viroeceea0b2008-05-10 10:08:32 -040087extern int sysctl_nr_open_min, sysctl_nr_open_max;
Paul Mundtdd8632a2009-01-08 12:04:47 +000088#ifndef CONFIG_MMU
89extern int sysctl_nr_trim_pages;
90#endif
Paul E. McKenney31a72bc2008-06-18 09:26:49 -070091#ifdef CONFIG_RCU_TORTURE_TEST
92extern int rcutorture_runnable;
93#endif /* #ifdef CONFIG_RCU_TORTURE_TEST */
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -070095/* Constants used for minimum and maximum */
Bron Gondwana195cf452008-02-04 22:29:20 -080096#ifdef CONFIG_DETECT_SOFTLOCKUP
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -070097static int sixty = 60;
Dimitri Sivanich9383d962008-05-12 21:21:14 +020098static int neg_one = -1;
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -070099#endif
100
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700101static int zero;
Linus Torvaldscd5f9a42009-04-06 13:38:46 -0700102static int __maybe_unused one = 1;
103static int __maybe_unused two = 2;
Sven Wegenerfc3501d2009-02-11 13:04:23 -0800104static unsigned long one_ul = 1;
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700105static int one_hundred = 100;
106
Andrea Righi9e4a5bd2009-04-30 15:08:57 -0700107/* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
108static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
109
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
111static int maxolduid = 65535;
112static int minolduid;
Rohit Seth8ad4b1f2006-01-08 01:00:40 -0800113static int min_percpu_pagelist_fract = 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
115static int ngroups_max = NGROUPS_MAX;
116
Johannes Berga1ef5ad2008-07-08 19:00:17 +0200117#ifdef CONFIG_MODULES
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118extern char modprobe_path[];
Kees Cook3d433212009-04-02 15:49:29 -0700119extern int modules_disabled;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121#ifdef CONFIG_CHR_DEV_SG
122extern int sg_big_buff;
123#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
David S. Miller72c57ed2008-09-11 23:29:54 -0700125#ifdef CONFIG_SPARC
David S. Miller17f04fb2008-09-11 23:33:53 -0700126#include <asm/system.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127#endif
128
David S. Miller08714202008-11-16 23:49:24 -0800129#ifdef CONFIG_SPARC64
130extern int sysctl_tsb_ratio;
131#endif
132
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133#ifdef __hppa__
134extern int pwrsw_enabled;
135extern int unaligned_enabled;
136#endif
137
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800138#ifdef CONFIG_S390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139#ifdef CONFIG_MATHEMU
140extern int sysctl_ieee_emulation_warnings;
141#endif
142extern int sysctl_userprocess_debug;
Martin Schwidefsky951f22d2005-07-27 11:44:57 -0700143extern int spin_retry;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144#endif
145
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146#ifdef CONFIG_BSD_PROCESS_ACCT
147extern int acct_parm[];
148#endif
149
Jes Sorensend2b176e2006-02-28 09:42:23 -0800150#ifdef CONFIG_IA64
151extern int no_unaligned_warning;
Doug Chapman88fc2412009-01-15 10:38:56 -0800152extern int unaligned_dump_stack;
Jes Sorensend2b176e2006-02-28 09:42:23 -0800153#endif
154
Ingo Molnar23f78d4a2006-06-27 02:54:53 -0700155#ifdef CONFIG_RT_MUTEXES
156extern int max_lock_depth;
157#endif
158
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700159#ifdef CONFIG_PROC_SYSCTL
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700160static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700161 void __user *buffer, size_t *lenp, loff_t *ppos);
Andi Kleen25ddbb12008-10-15 22:01:41 -0700162static int proc_taint(struct ctl_table *table, int write, struct file *filp,
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800163 void __user *buffer, size_t *lenp, loff_t *ppos);
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700164#endif
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700165
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700166static struct ctl_table root_table[];
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100167static struct ctl_table_root sysctl_table_root;
168static struct ctl_table_header root_table_header = {
Al Virob380b0d2008-09-04 17:05:57 +0100169 .count = 1,
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100170 .ctl_table = root_table,
Al Viro73455092008-07-14 21:22:20 -0400171 .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100172 .root = &sysctl_table_root,
Al Viro73455092008-07-14 21:22:20 -0400173 .set = &sysctl_table_root.default_set,
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100174};
175static struct ctl_table_root sysctl_table_root = {
176 .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
Al Viro73455092008-07-14 21:22:20 -0400177 .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry),
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +1100178};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700180static struct ctl_table kern_table[];
181static struct ctl_table vm_table[];
182static struct ctl_table fs_table[];
183static struct ctl_table debug_table[];
184static struct ctl_table dev_table[];
185extern struct ctl_table random_table[];
Amy Griffis2d9048e2006-06-01 13:10:59 -0700186#ifdef CONFIG_INOTIFY_USER
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700187extern struct ctl_table inotify_table[];
Robert Love0399cb02005-07-13 12:38:18 -0400188#endif
Davide Libenzi7ef99642008-12-01 13:13:55 -0800189#ifdef CONFIG_EPOLL
190extern struct ctl_table epoll_table[];
191#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192
193#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
194int sysctl_legacy_va_layout;
195#endif
196
Peter Zijlstraf20786f2007-07-19 01:48:56 -0700197extern int prove_locking;
198extern int lock_stat;
Eric W. Biederman9bc9a6b2006-12-08 02:39:56 -0800199
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200/* The default sysctl tables: */
201
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700202static struct ctl_table root_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 {
204 .ctl_name = CTL_KERN,
205 .procname = "kernel",
206 .mode = 0555,
207 .child = kern_table,
208 },
209 {
210 .ctl_name = CTL_VM,
211 .procname = "vm",
212 .mode = 0555,
213 .child = vm_table,
214 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 .ctl_name = CTL_FS,
217 .procname = "fs",
218 .mode = 0555,
219 .child = fs_table,
220 },
221 {
222 .ctl_name = CTL_DEBUG,
223 .procname = "debug",
224 .mode = 0555,
225 .child = debug_table,
226 },
227 {
228 .ctl_name = CTL_DEV,
229 .procname = "dev",
230 .mode = 0555,
231 .child = dev_table,
232 },
Andrew Morton2be7fe02007-07-15 23:41:21 -0700233/*
234 * NOTE: do not add new entries to this table unless you have read
235 * Documentation/sysctl/ctl_unnumbered.txt
236 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 { .ctl_name = 0 }
238};
239
Ingo Molnar77e54a12007-07-09 18:52:00 +0200240#ifdef CONFIG_SCHED_DEBUG
Eric Dumazet73c4efd2007-12-18 15:21:13 +0100241static int min_sched_granularity_ns = 100000; /* 100 usecs */
242static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */
243static int min_wakeup_granularity_ns; /* 0 usecs */
244static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */
Ingo Molnar77e54a12007-07-09 18:52:00 +0200245#endif
246
Eric W. Biedermand8217f02007-10-18 03:05:22 -0700247static struct ctl_table kern_table[] = {
Mike Galbraith2bba22c2009-09-09 15:41:37 +0200248 {
249 .ctl_name = CTL_UNNUMBERED,
250 .procname = "sched_child_runs_first",
251 .data = &sysctl_sched_child_runs_first,
252 .maxlen = sizeof(unsigned int),
253 .mode = 0644,
254 .proc_handler = &proc_dointvec,
255 },
Ingo Molnar77e54a12007-07-09 18:52:00 +0200256#ifdef CONFIG_SCHED_DEBUG
257 {
258 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstrab2be5e92007-11-09 22:39:37 +0100259 .procname = "sched_min_granularity_ns",
260 .data = &sysctl_sched_min_granularity,
Ingo Molnar77e54a12007-07-09 18:52:00 +0200261 .maxlen = sizeof(unsigned int),
262 .mode = 0644,
Peter Zijlstrab2be5e92007-11-09 22:39:37 +0100263 .proc_handler = &sched_nr_latency_handler,
264 .strategy = &sysctl_intvec,
265 .extra1 = &min_sched_granularity_ns,
266 .extra2 = &max_sched_granularity_ns,
Ingo Molnar77e54a12007-07-09 18:52:00 +0200267 },
268 {
269 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra21805082007-08-25 18:41:53 +0200270 .procname = "sched_latency_ns",
271 .data = &sysctl_sched_latency,
272 .maxlen = sizeof(unsigned int),
273 .mode = 0644,
Peter Zijlstrab2be5e92007-11-09 22:39:37 +0100274 .proc_handler = &sched_nr_latency_handler,
Peter Zijlstra21805082007-08-25 18:41:53 +0200275 .strategy = &sysctl_intvec,
276 .extra1 = &min_sched_granularity_ns,
277 .extra2 = &max_sched_granularity_ns,
278 },
279 {
280 .ctl_name = CTL_UNNUMBERED,
Ingo Molnar77e54a12007-07-09 18:52:00 +0200281 .procname = "sched_wakeup_granularity_ns",
282 .data = &sysctl_sched_wakeup_granularity,
283 .maxlen = sizeof(unsigned int),
284 .mode = 0644,
285 .proc_handler = &proc_dointvec_minmax,
286 .strategy = &sysctl_intvec,
287 .extra1 = &min_wakeup_granularity_ns,
288 .extra2 = &max_wakeup_granularity_ns,
289 },
290 {
291 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra2398f2c2008-06-27 13:41:35 +0200292 .procname = "sched_shares_ratelimit",
293 .data = &sysctl_sched_shares_ratelimit,
294 .maxlen = sizeof(unsigned int),
295 .mode = 0644,
296 .proc_handler = &proc_dointvec,
297 },
298 {
299 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstraffda12a2008-10-17 19:27:02 +0200300 .procname = "sched_shares_thresh",
301 .data = &sysctl_sched_shares_thresh,
302 .maxlen = sizeof(unsigned int),
303 .mode = 0644,
304 .proc_handler = &proc_dointvec_minmax,
305 .strategy = &sysctl_intvec,
306 .extra1 = &zero,
307 },
308 {
309 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra1fc84aa2007-08-25 18:41:52 +0200310 .procname = "sched_features",
311 .data = &sysctl_sched_features,
312 .maxlen = sizeof(unsigned int),
313 .mode = 0644,
314 .proc_handler = &proc_dointvec,
315 },
Ingo Molnarda84d962007-10-15 17:00:18 +0200316 {
317 .ctl_name = CTL_UNNUMBERED,
318 .procname = "sched_migration_cost",
319 .data = &sysctl_sched_migration_cost,
320 .maxlen = sizeof(unsigned int),
321 .mode = 0644,
322 .proc_handler = &proc_dointvec,
323 },
Peter Zijlstrab82d9fd2007-11-09 22:39:39 +0100324 {
325 .ctl_name = CTL_UNNUMBERED,
326 .procname = "sched_nr_migrate",
327 .data = &sysctl_sched_nr_migrate,
328 .maxlen = sizeof(unsigned int),
Peter Zijlstrafa85ae22008-01-25 21:08:29 +0100329 .mode = 0644,
330 .proc_handler = &proc_dointvec,
331 },
Arun R Bharadwajcd1bb942009-04-16 12:15:34 +0530332 {
333 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstrae9e92502009-09-01 10:34:37 +0200334 .procname = "sched_time_avg",
335 .data = &sysctl_sched_time_avg,
336 .maxlen = sizeof(unsigned int),
337 .mode = 0644,
338 .proc_handler = &proc_dointvec,
339 },
340 {
341 .ctl_name = CTL_UNNUMBERED,
Arun R Bharadwajcd1bb942009-04-16 12:15:34 +0530342 .procname = "timer_migration",
343 .data = &sysctl_timer_migration,
344 .maxlen = sizeof(unsigned int),
345 .mode = 0644,
Arun R Bharadwajbfdb4d92009-06-23 10:00:58 +0530346 .proc_handler = &proc_dointvec_minmax,
347 .strategy = &sysctl_intvec,
348 .extra1 = &zero,
349 .extra2 = &one,
Arun R Bharadwajcd1bb942009-04-16 12:15:34 +0530350 },
Peter Zijlstra1fc84aa2007-08-25 18:41:52 +0200351#endif
Ingo Molnar1799e352007-09-19 23:34:46 +0200352 {
353 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra9f0c1e52008-02-13 15:45:39 +0100354 .procname = "sched_rt_period_us",
355 .data = &sysctl_sched_rt_period,
356 .maxlen = sizeof(unsigned int),
357 .mode = 0644,
Peter Zijlstrad0b27fa2008-04-19 19:44:57 +0200358 .proc_handler = &sched_rt_handler,
Peter Zijlstra9f0c1e52008-02-13 15:45:39 +0100359 },
360 {
361 .ctl_name = CTL_UNNUMBERED,
362 .procname = "sched_rt_runtime_us",
363 .data = &sysctl_sched_rt_runtime,
364 .maxlen = sizeof(int),
365 .mode = 0644,
Peter Zijlstrad0b27fa2008-04-19 19:44:57 +0200366 .proc_handler = &sched_rt_handler,
Peter Zijlstra9f0c1e52008-02-13 15:45:39 +0100367 },
368 {
369 .ctl_name = CTL_UNNUMBERED,
Ingo Molnar1799e352007-09-19 23:34:46 +0200370 .procname = "sched_compat_yield",
371 .data = &sysctl_sched_compat_yield,
372 .maxlen = sizeof(unsigned int),
373 .mode = 0644,
374 .proc_handler = &proc_dointvec,
375 },
Peter Zijlstraf20786f2007-07-19 01:48:56 -0700376#ifdef CONFIG_PROVE_LOCKING
377 {
378 .ctl_name = CTL_UNNUMBERED,
379 .procname = "prove_locking",
380 .data = &prove_locking,
381 .maxlen = sizeof(int),
382 .mode = 0644,
383 .proc_handler = &proc_dointvec,
384 },
385#endif
386#ifdef CONFIG_LOCK_STAT
387 {
388 .ctl_name = CTL_UNNUMBERED,
389 .procname = "lock_stat",
390 .data = &lock_stat,
391 .maxlen = sizeof(int),
392 .mode = 0644,
393 .proc_handler = &proc_dointvec,
394 },
395#endif
Ingo Molnar77e54a12007-07-09 18:52:00 +0200396 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 .ctl_name = KERN_PANIC,
398 .procname = "panic",
399 .data = &panic_timeout,
400 .maxlen = sizeof(int),
401 .mode = 0644,
402 .proc_handler = &proc_dointvec,
403 },
404 {
405 .ctl_name = KERN_CORE_USES_PID,
406 .procname = "core_uses_pid",
407 .data = &core_uses_pid,
408 .maxlen = sizeof(int),
409 .mode = 0644,
410 .proc_handler = &proc_dointvec,
411 },
412 {
413 .ctl_name = KERN_CORE_PATTERN,
414 .procname = "core_pattern",
415 .data = core_pattern,
Dan Aloni71ce92f2007-05-16 22:11:16 -0700416 .maxlen = CORENAME_MAX_SIZE,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 .mode = 0644,
418 .proc_handler = &proc_dostring,
419 .strategy = &sysctl_string,
420 },
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800421#ifdef CONFIG_PROC_SYSCTL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 .procname = "tainted",
Andi Kleen25ddbb12008-10-15 22:01:41 -0700424 .maxlen = sizeof(long),
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800425 .mode = 0644,
Andi Kleen25ddbb12008-10-15 22:01:41 -0700426 .proc_handler = &proc_taint,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 },
Theodore Ts'o34f5a392007-02-10 01:45:24 -0800428#endif
Arjan van de Ven97455122008-01-25 21:08:34 +0100429#ifdef CONFIG_LATENCYTOP
430 {
431 .procname = "latencytop",
432 .data = &latencytop_enabled,
433 .maxlen = sizeof(int),
434 .mode = 0644,
435 .proc_handler = &proc_dointvec,
436 },
437#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438#ifdef CONFIG_BLK_DEV_INITRD
439 {
440 .ctl_name = KERN_REALROOTDEV,
441 .procname = "real-root-dev",
442 .data = &real_root_dev,
443 .maxlen = sizeof(int),
444 .mode = 0644,
445 .proc_handler = &proc_dointvec,
446 },
447#endif
Ingo Molnar45807a12007-07-15 23:40:10 -0700448 {
449 .ctl_name = CTL_UNNUMBERED,
450 .procname = "print-fatal-signals",
451 .data = &print_fatal_signals,
452 .maxlen = sizeof(int),
453 .mode = 0644,
454 .proc_handler = &proc_dointvec,
455 },
David S. Miller72c57ed2008-09-11 23:29:54 -0700456#ifdef CONFIG_SPARC
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457 {
458 .ctl_name = KERN_SPARC_REBOOT,
459 .procname = "reboot-cmd",
460 .data = reboot_command,
461 .maxlen = 256,
462 .mode = 0644,
463 .proc_handler = &proc_dostring,
464 .strategy = &sysctl_string,
465 },
466 {
467 .ctl_name = KERN_SPARC_STOP_A,
468 .procname = "stop-a",
469 .data = &stop_a_enabled,
470 .maxlen = sizeof (int),
471 .mode = 0644,
472 .proc_handler = &proc_dointvec,
473 },
474 {
475 .ctl_name = KERN_SPARC_SCONS_PWROFF,
476 .procname = "scons-poweroff",
477 .data = &scons_pwroff,
478 .maxlen = sizeof (int),
479 .mode = 0644,
480 .proc_handler = &proc_dointvec,
481 },
482#endif
David S. Miller08714202008-11-16 23:49:24 -0800483#ifdef CONFIG_SPARC64
484 {
485 .ctl_name = CTL_UNNUMBERED,
486 .procname = "tsb-ratio",
487 .data = &sysctl_tsb_ratio,
488 .maxlen = sizeof (int),
489 .mode = 0644,
490 .proc_handler = &proc_dointvec,
491 },
492#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493#ifdef __hppa__
494 {
495 .ctl_name = KERN_HPPA_PWRSW,
496 .procname = "soft-power",
497 .data = &pwrsw_enabled,
498 .maxlen = sizeof (int),
499 .mode = 0644,
500 .proc_handler = &proc_dointvec,
501 },
502 {
503 .ctl_name = KERN_HPPA_UNALIGNED,
504 .procname = "unaligned-trap",
505 .data = &unaligned_enabled,
506 .maxlen = sizeof (int),
507 .mode = 0644,
508 .proc_handler = &proc_dointvec,
509 },
510#endif
511 {
512 .ctl_name = KERN_CTLALTDEL,
513 .procname = "ctrl-alt-del",
514 .data = &C_A_D,
515 .maxlen = sizeof(int),
516 .mode = 0644,
517 .proc_handler = &proc_dointvec,
518 },
Steven Rostedt606576c2008-10-06 19:06:12 -0400519#ifdef CONFIG_FUNCTION_TRACER
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200520 {
521 .ctl_name = CTL_UNNUMBERED,
522 .procname = "ftrace_enabled",
523 .data = &ftrace_enabled,
524 .maxlen = sizeof(int),
525 .mode = 0644,
526 .proc_handler = &ftrace_enable_sysctl,
527 },
528#endif
Steven Rostedtf38f1d22008-12-16 23:06:40 -0500529#ifdef CONFIG_STACK_TRACER
530 {
531 .ctl_name = CTL_UNNUMBERED,
532 .procname = "stack_tracer_enabled",
533 .data = &stack_tracer_enabled,
534 .maxlen = sizeof(int),
535 .mode = 0644,
536 .proc_handler = &stack_trace_sysctl,
537 },
538#endif
Steven Rostedt944ac422008-10-23 19:26:08 -0400539#ifdef CONFIG_TRACING
540 {
541 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra3299b4d2008-11-04 11:58:21 +0100542 .procname = "ftrace_dump_on_oops",
Steven Rostedt944ac422008-10-23 19:26:08 -0400543 .data = &ftrace_dump_on_oops,
544 .maxlen = sizeof(int),
545 .mode = 0644,
546 .proc_handler = &proc_dointvec,
547 },
548#endif
Johannes Berga1ef5ad2008-07-08 19:00:17 +0200549#ifdef CONFIG_MODULES
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 {
551 .ctl_name = KERN_MODPROBE,
552 .procname = "modprobe",
553 .data = &modprobe_path,
554 .maxlen = KMOD_PATH_LEN,
555 .mode = 0644,
556 .proc_handler = &proc_dostring,
557 .strategy = &sysctl_string,
558 },
Kees Cook3d433212009-04-02 15:49:29 -0700559 {
560 .ctl_name = CTL_UNNUMBERED,
561 .procname = "modules_disabled",
562 .data = &modules_disabled,
563 .maxlen = sizeof(int),
564 .mode = 0644,
565 /* only handle a transition from default "0" to "1" */
566 .proc_handler = &proc_dointvec_minmax,
567 .extra1 = &one,
568 .extra2 = &one,
569 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570#endif
Andrew Morton57ae2502006-06-23 02:05:47 -0700571#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 {
573 .ctl_name = KERN_HOTPLUG,
574 .procname = "hotplug",
Kay Sievers312c0042005-11-16 09:00:00 +0100575 .data = &uevent_helper,
576 .maxlen = UEVENT_HELPER_PATH_LEN,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 .mode = 0644,
578 .proc_handler = &proc_dostring,
579 .strategy = &sysctl_string,
580 },
581#endif
582#ifdef CONFIG_CHR_DEV_SG
583 {
584 .ctl_name = KERN_SG_BIG_BUFF,
585 .procname = "sg-big-buff",
586 .data = &sg_big_buff,
587 .maxlen = sizeof (int),
588 .mode = 0444,
589 .proc_handler = &proc_dointvec,
590 },
591#endif
592#ifdef CONFIG_BSD_PROCESS_ACCT
593 {
594 .ctl_name = KERN_ACCT,
595 .procname = "acct",
596 .data = &acct_parm,
597 .maxlen = 3*sizeof(int),
598 .mode = 0644,
599 .proc_handler = &proc_dointvec,
600 },
601#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602#ifdef CONFIG_MAGIC_SYSRQ
603 {
604 .ctl_name = KERN_SYSRQ,
605 .procname = "sysrq",
Ingo Molnar5d6f6472006-12-13 00:34:36 -0800606 .data = &__sysrq_enabled,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 .maxlen = sizeof (int),
608 .mode = 0644,
609 .proc_handler = &proc_dointvec,
610 },
611#endif
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700612#ifdef CONFIG_PROC_SYSCTL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 .procname = "cad_pid",
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700615 .data = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 .maxlen = sizeof (int),
617 .mode = 0600,
Cedric Le Goater9ec52092006-10-02 02:19:00 -0700618 .proc_handler = &proc_do_cad_pid,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 },
Randy Dunlapd6f8ff72006-10-19 23:28:34 -0700620#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 {
622 .ctl_name = KERN_MAX_THREADS,
623 .procname = "threads-max",
624 .data = &max_threads,
625 .maxlen = sizeof(int),
626 .mode = 0644,
627 .proc_handler = &proc_dointvec,
628 },
629 {
630 .ctl_name = KERN_RANDOM,
631 .procname = "random",
632 .mode = 0555,
633 .child = random_table,
634 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 {
636 .ctl_name = KERN_OVERFLOWUID,
637 .procname = "overflowuid",
638 .data = &overflowuid,
639 .maxlen = sizeof(int),
640 .mode = 0644,
641 .proc_handler = &proc_dointvec_minmax,
642 .strategy = &sysctl_intvec,
643 .extra1 = &minolduid,
644 .extra2 = &maxolduid,
645 },
646 {
647 .ctl_name = KERN_OVERFLOWGID,
648 .procname = "overflowgid",
649 .data = &overflowgid,
650 .maxlen = sizeof(int),
651 .mode = 0644,
652 .proc_handler = &proc_dointvec_minmax,
653 .strategy = &sysctl_intvec,
654 .extra1 = &minolduid,
655 .extra2 = &maxolduid,
656 },
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -0800657#ifdef CONFIG_S390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658#ifdef CONFIG_MATHEMU
659 {
660 .ctl_name = KERN_IEEE_EMULATION_WARNINGS,
661 .procname = "ieee_emulation_warnings",
662 .data = &sysctl_ieee_emulation_warnings,
663 .maxlen = sizeof(int),
664 .mode = 0644,
665 .proc_handler = &proc_dointvec,
666 },
667#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 {
669 .ctl_name = KERN_S390_USER_DEBUG_LOGGING,
670 .procname = "userprocess_debug",
671 .data = &sysctl_userprocess_debug,
672 .maxlen = sizeof(int),
673 .mode = 0644,
674 .proc_handler = &proc_dointvec,
675 },
676#endif
677 {
678 .ctl_name = KERN_PIDMAX,
679 .procname = "pid_max",
680 .data = &pid_max,
681 .maxlen = sizeof (int),
682 .mode = 0644,
683 .proc_handler = &proc_dointvec_minmax,
684 .strategy = sysctl_intvec,
685 .extra1 = &pid_max_min,
686 .extra2 = &pid_max_max,
687 },
688 {
689 .ctl_name = KERN_PANIC_ON_OOPS,
690 .procname = "panic_on_oops",
691 .data = &panic_on_oops,
692 .maxlen = sizeof(int),
693 .mode = 0644,
694 .proc_handler = &proc_dointvec,
695 },
Joe Perches7ef3d2f2008-02-08 04:21:25 -0800696#if defined CONFIG_PRINTK
697 {
698 .ctl_name = KERN_PRINTK,
699 .procname = "printk",
700 .data = &console_loglevel,
701 .maxlen = 4*sizeof(int),
702 .mode = 0644,
703 .proc_handler = &proc_dointvec,
704 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 {
706 .ctl_name = KERN_PRINTK_RATELIMIT,
707 .procname = "printk_ratelimit",
Dave Young717115e2008-07-25 01:45:58 -0700708 .data = &printk_ratelimit_state.interval,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 .maxlen = sizeof(int),
710 .mode = 0644,
711 .proc_handler = &proc_dointvec_jiffies,
712 .strategy = &sysctl_jiffies,
713 },
714 {
715 .ctl_name = KERN_PRINTK_RATELIMIT_BURST,
716 .procname = "printk_ratelimit_burst",
Dave Young717115e2008-07-25 01:45:58 -0700717 .data = &printk_ratelimit_state.burst,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 .maxlen = sizeof(int),
719 .mode = 0644,
720 .proc_handler = &proc_dointvec,
721 },
Joe Perches7ef3d2f2008-02-08 04:21:25 -0800722#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 {
724 .ctl_name = KERN_NGROUPS_MAX,
725 .procname = "ngroups_max",
726 .data = &ngroups_max,
727 .maxlen = sizeof (int),
728 .mode = 0444,
729 .proc_handler = &proc_dointvec,
730 },
731#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
732 {
733 .ctl_name = KERN_UNKNOWN_NMI_PANIC,
734 .procname = "unknown_nmi_panic",
735 .data = &unknown_nmi_panic,
736 .maxlen = sizeof (int),
737 .mode = 0644,
Don Zickus2fbe7b22006-09-26 10:52:27 +0200738 .proc_handler = &proc_dointvec,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 },
Don Zickus407984f2006-09-26 10:52:27 +0200740 {
Don Zickus407984f2006-09-26 10:52:27 +0200741 .procname = "nmi_watchdog",
742 .data = &nmi_watchdog_enabled,
743 .maxlen = sizeof (int),
744 .mode = 0644,
745 .proc_handler = &proc_nmi_enabled,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 },
747#endif
748#if defined(CONFIG_X86)
749 {
Don Zickus8da5add2006-09-26 10:52:27 +0200750 .ctl_name = KERN_PANIC_ON_NMI,
751 .procname = "panic_on_unrecovered_nmi",
752 .data = &panic_on_unrecovered_nmi,
753 .maxlen = sizeof(int),
754 .mode = 0644,
755 .proc_handler = &proc_dointvec,
756 },
757 {
Kurt Garloff5211a242009-06-24 14:32:11 -0700758 .ctl_name = CTL_UNNUMBERED,
759 .procname = "panic_on_io_nmi",
760 .data = &panic_on_io_nmi,
761 .maxlen = sizeof(int),
762 .mode = 0644,
763 .proc_handler = &proc_dointvec,
764 },
765 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 .ctl_name = KERN_BOOTLOADER_TYPE,
767 .procname = "bootloader_type",
768 .data = &bootloader_type,
769 .maxlen = sizeof (int),
770 .mode = 0444,
771 .proc_handler = &proc_dointvec,
772 },
Chuck Ebbert0741f4d2006-12-07 02:14:11 +0100773 {
774 .ctl_name = CTL_UNNUMBERED,
H. Peter Anvin50312962009-05-07 16:54:11 -0700775 .procname = "bootloader_version",
776 .data = &bootloader_version,
777 .maxlen = sizeof (int),
778 .mode = 0444,
779 .proc_handler = &proc_dointvec,
780 },
781 {
782 .ctl_name = CTL_UNNUMBERED,
Chuck Ebbert0741f4d2006-12-07 02:14:11 +0100783 .procname = "kstack_depth_to_print",
784 .data = &kstack_depth_to_print,
785 .maxlen = sizeof(int),
786 .mode = 0644,
787 .proc_handler = &proc_dointvec,
788 },
Ingo Molnar6e7c4022008-01-30 13:30:05 +0100789 {
790 .ctl_name = CTL_UNNUMBERED,
791 .procname = "io_delay_type",
792 .data = &io_delay_type,
793 .maxlen = sizeof(int),
794 .mode = 0644,
795 .proc_handler = &proc_dointvec,
796 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797#endif
Luke Yang7a9166e2006-02-20 18:28:07 -0800798#if defined(CONFIG_MMU)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 {
800 .ctl_name = KERN_RANDOMIZE,
801 .procname = "randomize_va_space",
802 .data = &randomize_va_space,
803 .maxlen = sizeof(int),
804 .mode = 0644,
805 .proc_handler = &proc_dointvec,
806 },
Luke Yang7a9166e2006-02-20 18:28:07 -0800807#endif
Martin Schwidefsky0152fb32006-01-14 13:21:00 -0800808#if defined(CONFIG_S390) && defined(CONFIG_SMP)
Martin Schwidefsky951f22d2005-07-27 11:44:57 -0700809 {
810 .ctl_name = KERN_SPIN_RETRY,
811 .procname = "spin_retry",
812 .data = &spin_retry,
813 .maxlen = sizeof (int),
814 .mode = 0644,
815 .proc_handler = &proc_dointvec,
816 },
817#endif
Len Brown673d5b42007-07-28 03:33:16 -0400818#if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86)
Pavel Machekc255d842006-02-20 18:27:58 -0800819 {
Pavel Machekc255d842006-02-20 18:27:58 -0800820 .procname = "acpi_video_flags",
Pavel Machek77afcf72007-07-19 01:47:41 -0700821 .data = &acpi_realmode_flags,
Pavel Machekc255d842006-02-20 18:27:58 -0800822 .maxlen = sizeof (unsigned long),
823 .mode = 0644,
Stefan Seyfried7f99f062006-03-02 02:54:34 -0800824 .proc_handler = &proc_doulongvec_minmax,
Pavel Machekc255d842006-02-20 18:27:58 -0800825 },
826#endif
Jes Sorensend2b176e2006-02-28 09:42:23 -0800827#ifdef CONFIG_IA64
828 {
829 .ctl_name = KERN_IA64_UNALIGNED,
830 .procname = "ignore-unaligned-usertrap",
831 .data = &no_unaligned_warning,
832 .maxlen = sizeof (int),
833 .mode = 0644,
834 .proc_handler = &proc_dointvec,
835 },
Doug Chapman88fc2412009-01-15 10:38:56 -0800836 {
837 .ctl_name = CTL_UNNUMBERED,
838 .procname = "unaligned-dump-stack",
839 .data = &unaligned_dump_stack,
840 .maxlen = sizeof (int),
841 .mode = 0644,
842 .proc_handler = &proc_dointvec,
843 },
Jes Sorensend2b176e2006-02-28 09:42:23 -0800844#endif
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700845#ifdef CONFIG_DETECT_SOFTLOCKUP
846 {
847 .ctl_name = CTL_UNNUMBERED,
Ingo Molnar9c44bc02008-05-12 21:21:04 +0200848 .procname = "softlockup_panic",
849 .data = &softlockup_panic,
850 .maxlen = sizeof(int),
851 .mode = 0644,
Hiroshi Shimamoto4dca10a2008-07-07 18:37:04 -0700852 .proc_handler = &proc_dointvec_minmax,
Ingo Molnar9c44bc02008-05-12 21:21:04 +0200853 .strategy = &sysctl_intvec,
854 .extra1 = &zero,
855 .extra2 = &one,
856 },
857 {
858 .ctl_name = CTL_UNNUMBERED,
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700859 .procname = "softlockup_thresh",
860 .data = &softlockup_thresh,
Dimitri Sivanich9383d962008-05-12 21:21:14 +0200861 .maxlen = sizeof(int),
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700862 .mode = 0644,
Mandeep Singh Bainesbaf48f62009-01-12 21:15:17 -0800863 .proc_handler = &proc_dosoftlockup_thresh,
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700864 .strategy = &sysctl_intvec,
Dimitri Sivanich9383d962008-05-12 21:21:14 +0200865 .extra1 = &neg_one,
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700866 .extra2 = &sixty,
867 },
Mandeep Singh Bainese162b392009-01-15 11:08:40 -0800868#endif
869#ifdef CONFIG_DETECT_HUNG_TASK
870 {
871 .ctl_name = CTL_UNNUMBERED,
872 .procname = "hung_task_panic",
873 .data = &sysctl_hung_task_panic,
874 .maxlen = sizeof(int),
875 .mode = 0644,
876 .proc_handler = &proc_dointvec_minmax,
877 .strategy = &sysctl_intvec,
878 .extra1 = &zero,
879 .extra2 = &one,
880 },
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100881 {
882 .ctl_name = CTL_UNNUMBERED,
883 .procname = "hung_task_check_count",
884 .data = &sysctl_hung_task_check_count,
Ingo Molnar90739082008-01-25 21:08:34 +0100885 .maxlen = sizeof(unsigned long),
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100886 .mode = 0644,
Ingo Molnar90739082008-01-25 21:08:34 +0100887 .proc_handler = &proc_doulongvec_minmax,
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100888 .strategy = &sysctl_intvec,
889 },
890 {
891 .ctl_name = CTL_UNNUMBERED,
892 .procname = "hung_task_timeout_secs",
893 .data = &sysctl_hung_task_timeout_secs,
Ingo Molnar90739082008-01-25 21:08:34 +0100894 .maxlen = sizeof(unsigned long),
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100895 .mode = 0644,
Mandeep Singh Bainese162b392009-01-15 11:08:40 -0800896 .proc_handler = &proc_dohung_task_timeout_secs,
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100897 .strategy = &sysctl_intvec,
898 },
899 {
900 .ctl_name = CTL_UNNUMBERED,
901 .procname = "hung_task_warnings",
902 .data = &sysctl_hung_task_warnings,
Ingo Molnar90739082008-01-25 21:08:34 +0100903 .maxlen = sizeof(unsigned long),
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100904 .mode = 0644,
Ingo Molnar90739082008-01-25 21:08:34 +0100905 .proc_handler = &proc_doulongvec_minmax,
Ingo Molnar82a1fcb2008-01-25 21:08:02 +0100906 .strategy = &sysctl_intvec,
907 },
Ravikiran G Thirumalaic4f3b632007-10-16 23:26:09 -0700908#endif
Andi Kleenbebfa102006-06-26 13:56:52 +0200909#ifdef CONFIG_COMPAT
910 {
911 .ctl_name = KERN_COMPAT_LOG,
912 .procname = "compat-log",
913 .data = &compat_log,
914 .maxlen = sizeof (int),
915 .mode = 0644,
916 .proc_handler = &proc_dointvec,
917 },
918#endif
Ingo Molnar23f78d4a2006-06-27 02:54:53 -0700919#ifdef CONFIG_RT_MUTEXES
920 {
921 .ctl_name = KERN_MAX_LOCK_DEPTH,
922 .procname = "max_lock_depth",
923 .data = &max_lock_depth,
924 .maxlen = sizeof(int),
925 .mode = 0644,
926 .proc_handler = &proc_dointvec,
927 },
928#endif
Jeremy Fitzhardinge10a0a8d2007-07-17 18:37:02 -0700929 {
930 .ctl_name = CTL_UNNUMBERED,
931 .procname = "poweroff_cmd",
932 .data = &poweroff_cmd,
933 .maxlen = POWEROFF_CMD_PATH_LEN,
934 .mode = 0644,
935 .proc_handler = &proc_dostring,
936 .strategy = &sysctl_string,
937 },
David Howells0b77f5b2008-04-29 01:01:32 -0700938#ifdef CONFIG_KEYS
939 {
940 .ctl_name = CTL_UNNUMBERED,
941 .procname = "keys",
942 .mode = 0555,
943 .child = key_sysctls,
944 },
945#endif
Paul E. McKenney31a72bc2008-06-18 09:26:49 -0700946#ifdef CONFIG_RCU_TORTURE_TEST
947 {
948 .ctl_name = CTL_UNNUMBERED,
949 .procname = "rcutorture_runnable",
950 .data = &rcutorture_runnable,
951 .maxlen = sizeof(int),
952 .mode = 0644,
953 .proc_handler = &proc_dointvec,
954 },
955#endif
David Howells12e22c52009-04-03 16:42:35 +0100956#ifdef CONFIG_SLOW_WORK
957 {
958 .ctl_name = CTL_UNNUMBERED,
959 .procname = "slow-work",
960 .mode = 0555,
961 .child = slow_work_sysctls,
962 },
963#endif
Peter Zijlstra1ccd1542009-04-09 10:53:45 +0200964#ifdef CONFIG_PERF_COUNTERS
965 {
966 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstra07647712009-06-11 11:18:36 +0200967 .procname = "perf_counter_paranoid",
968 .data = &sysctl_perf_counter_paranoid,
969 .maxlen = sizeof(sysctl_perf_counter_paranoid),
Peter Zijlstra1ccd1542009-04-09 10:53:45 +0200970 .mode = 0644,
971 .proc_handler = &proc_dointvec,
972 },
Peter Zijlstrac5078f72009-05-05 17:50:24 +0200973 {
974 .ctl_name = CTL_UNNUMBERED,
975 .procname = "perf_counter_mlock_kb",
976 .data = &sysctl_perf_counter_mlock,
977 .maxlen = sizeof(sysctl_perf_counter_mlock),
978 .mode = 0644,
979 .proc_handler = &proc_dointvec,
980 },
Peter Zijlstraa78ac322009-05-25 17:39:05 +0200981 {
982 .ctl_name = CTL_UNNUMBERED,
Peter Zijlstradf58ab22009-06-11 11:25:05 +0200983 .procname = "perf_counter_max_sample_rate",
984 .data = &sysctl_perf_counter_sample_rate,
985 .maxlen = sizeof(sysctl_perf_counter_sample_rate),
Peter Zijlstraa78ac322009-05-25 17:39:05 +0200986 .mode = 0644,
987 .proc_handler = &proc_dointvec,
988 },
Peter Zijlstra1ccd1542009-04-09 10:53:45 +0200989#endif
Vegard Nossumdfec0722008-04-04 00:51:41 +0200990#ifdef CONFIG_KMEMCHECK
991 {
992 .ctl_name = CTL_UNNUMBERED,
993 .procname = "kmemcheck",
994 .data = &kmemcheck_enabled,
995 .maxlen = sizeof(int),
996 .mode = 0644,
997 .proc_handler = &proc_dointvec,
998 },
999#endif
1000
Andrew Mortoned2c12f2007-07-19 01:50:35 -07001001/*
1002 * NOTE: do not add new entries to this table unless you have read
1003 * Documentation/sysctl/ctl_unnumbered.txt
1004 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 { .ctl_name = 0 }
1006};
1007
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001008static struct ctl_table vm_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 {
1010 .ctl_name = VM_OVERCOMMIT_MEMORY,
1011 .procname = "overcommit_memory",
1012 .data = &sysctl_overcommit_memory,
1013 .maxlen = sizeof(sysctl_overcommit_memory),
1014 .mode = 0644,
1015 .proc_handler = &proc_dointvec,
1016 },
1017 {
KAMEZAWA Hiroyukifadd8fb2006-06-23 02:03:13 -07001018 .ctl_name = VM_PANIC_ON_OOM,
1019 .procname = "panic_on_oom",
1020 .data = &sysctl_panic_on_oom,
1021 .maxlen = sizeof(sysctl_panic_on_oom),
1022 .mode = 0644,
1023 .proc_handler = &proc_dointvec,
1024 },
1025 {
David Rientjesfe071d72007-10-16 23:25:56 -07001026 .ctl_name = CTL_UNNUMBERED,
1027 .procname = "oom_kill_allocating_task",
1028 .data = &sysctl_oom_kill_allocating_task,
1029 .maxlen = sizeof(sysctl_oom_kill_allocating_task),
1030 .mode = 0644,
1031 .proc_handler = &proc_dointvec,
1032 },
1033 {
David Rientjesfef1bdd2008-02-07 00:14:07 -08001034 .ctl_name = CTL_UNNUMBERED,
1035 .procname = "oom_dump_tasks",
1036 .data = &sysctl_oom_dump_tasks,
1037 .maxlen = sizeof(sysctl_oom_dump_tasks),
1038 .mode = 0644,
1039 .proc_handler = &proc_dointvec,
1040 },
1041 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 .ctl_name = VM_OVERCOMMIT_RATIO,
1043 .procname = "overcommit_ratio",
1044 .data = &sysctl_overcommit_ratio,
1045 .maxlen = sizeof(sysctl_overcommit_ratio),
1046 .mode = 0644,
1047 .proc_handler = &proc_dointvec,
1048 },
1049 {
1050 .ctl_name = VM_PAGE_CLUSTER,
1051 .procname = "page-cluster",
1052 .data = &page_cluster,
1053 .maxlen = sizeof(int),
1054 .mode = 0644,
1055 .proc_handler = &proc_dointvec,
1056 },
1057 {
1058 .ctl_name = VM_DIRTY_BACKGROUND,
1059 .procname = "dirty_background_ratio",
1060 .data = &dirty_background_ratio,
1061 .maxlen = sizeof(dirty_background_ratio),
1062 .mode = 0644,
David Rientjes2da02992009-01-06 14:39:31 -08001063 .proc_handler = &dirty_background_ratio_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 .strategy = &sysctl_intvec,
1065 .extra1 = &zero,
1066 .extra2 = &one_hundred,
1067 },
1068 {
David Rientjes2da02992009-01-06 14:39:31 -08001069 .ctl_name = CTL_UNNUMBERED,
1070 .procname = "dirty_background_bytes",
1071 .data = &dirty_background_bytes,
1072 .maxlen = sizeof(dirty_background_bytes),
1073 .mode = 0644,
1074 .proc_handler = &dirty_background_bytes_handler,
1075 .strategy = &sysctl_intvec,
Sven Wegenerfc3501d2009-02-11 13:04:23 -08001076 .extra1 = &one_ul,
David Rientjes2da02992009-01-06 14:39:31 -08001077 },
1078 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 .ctl_name = VM_DIRTY_RATIO,
1080 .procname = "dirty_ratio",
1081 .data = &vm_dirty_ratio,
1082 .maxlen = sizeof(vm_dirty_ratio),
1083 .mode = 0644,
Peter Zijlstra04fbfdc2007-10-16 23:25:50 -07001084 .proc_handler = &dirty_ratio_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 .strategy = &sysctl_intvec,
1086 .extra1 = &zero,
1087 .extra2 = &one_hundred,
1088 },
1089 {
David Rientjes2da02992009-01-06 14:39:31 -08001090 .ctl_name = CTL_UNNUMBERED,
1091 .procname = "dirty_bytes",
1092 .data = &vm_dirty_bytes,
1093 .maxlen = sizeof(vm_dirty_bytes),
1094 .mode = 0644,
1095 .proc_handler = &dirty_bytes_handler,
1096 .strategy = &sysctl_intvec,
Andrea Righi9e4a5bd2009-04-30 15:08:57 -07001097 .extra1 = &dirty_bytes_min,
David Rientjes2da02992009-01-06 14:39:31 -08001098 },
1099 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 .procname = "dirty_writeback_centisecs",
Bart Samwelf6ef9432006-03-24 03:15:48 -08001101 .data = &dirty_writeback_interval,
1102 .maxlen = sizeof(dirty_writeback_interval),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 .mode = 0644,
1104 .proc_handler = &dirty_writeback_centisecs_handler,
1105 },
1106 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 .procname = "dirty_expire_centisecs",
Bart Samwelf6ef9432006-03-24 03:15:48 -08001108 .data = &dirty_expire_interval,
1109 .maxlen = sizeof(dirty_expire_interval),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 .mode = 0644,
Alexey Dobriyan704503d2009-03-31 15:23:18 -07001111 .proc_handler = &proc_dointvec,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 },
1113 {
1114 .ctl_name = VM_NR_PDFLUSH_THREADS,
1115 .procname = "nr_pdflush_threads",
1116 .data = &nr_pdflush_threads,
1117 .maxlen = sizeof nr_pdflush_threads,
1118 .mode = 0444 /* read-only*/,
1119 .proc_handler = &proc_dointvec,
1120 },
1121 {
1122 .ctl_name = VM_SWAPPINESS,
1123 .procname = "swappiness",
1124 .data = &vm_swappiness,
1125 .maxlen = sizeof(vm_swappiness),
1126 .mode = 0644,
1127 .proc_handler = &proc_dointvec_minmax,
1128 .strategy = &sysctl_intvec,
1129 .extra1 = &zero,
1130 .extra2 = &one_hundred,
1131 },
1132#ifdef CONFIG_HUGETLB_PAGE
1133 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 .procname = "nr_hugepages",
Andi Kleene5ff2152008-07-23 21:27:42 -07001135 .data = NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 .maxlen = sizeof(unsigned long),
1137 .mode = 0644,
1138 .proc_handler = &hugetlb_sysctl_handler,
1139 .extra1 = (void *)&hugetlb_zero,
1140 .extra2 = (void *)&hugetlb_infinity,
1141 },
1142 {
1143 .ctl_name = VM_HUGETLB_GROUP,
1144 .procname = "hugetlb_shm_group",
1145 .data = &sysctl_hugetlb_shm_group,
1146 .maxlen = sizeof(gid_t),
1147 .mode = 0644,
1148 .proc_handler = &proc_dointvec,
1149 },
Mel Gorman396faf02007-07-17 04:03:13 -07001150 {
1151 .ctl_name = CTL_UNNUMBERED,
1152 .procname = "hugepages_treat_as_movable",
1153 .data = &hugepages_treat_as_movable,
1154 .maxlen = sizeof(int),
1155 .mode = 0644,
1156 .proc_handler = &hugetlb_treat_movable_handler,
1157 },
Adam Litke54f9f802007-10-16 01:26:20 -07001158 {
1159 .ctl_name = CTL_UNNUMBERED,
Nishanth Aravamudand1c3fb12007-12-17 16:20:12 -08001160 .procname = "nr_overcommit_hugepages",
Andi Kleene5ff2152008-07-23 21:27:42 -07001161 .data = NULL,
1162 .maxlen = sizeof(unsigned long),
Nishanth Aravamudand1c3fb12007-12-17 16:20:12 -08001163 .mode = 0644,
Nishanth Aravamudana3d0c6a2008-02-08 04:18:18 -08001164 .proc_handler = &hugetlb_overcommit_handler,
Andi Kleene5ff2152008-07-23 21:27:42 -07001165 .extra1 = (void *)&hugetlb_zero,
1166 .extra2 = (void *)&hugetlb_infinity,
Nishanth Aravamudand1c3fb12007-12-17 16:20:12 -08001167 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168#endif
1169 {
1170 .ctl_name = VM_LOWMEM_RESERVE_RATIO,
1171 .procname = "lowmem_reserve_ratio",
1172 .data = &sysctl_lowmem_reserve_ratio,
1173 .maxlen = sizeof(sysctl_lowmem_reserve_ratio),
1174 .mode = 0644,
1175 .proc_handler = &lowmem_reserve_ratio_sysctl_handler,
1176 .strategy = &sysctl_intvec,
1177 },
1178 {
Andrew Morton9d0243b2006-01-08 01:00:39 -08001179 .ctl_name = VM_DROP_PAGECACHE,
1180 .procname = "drop_caches",
1181 .data = &sysctl_drop_caches,
1182 .maxlen = sizeof(int),
1183 .mode = 0644,
1184 .proc_handler = drop_caches_sysctl_handler,
1185 .strategy = &sysctl_intvec,
1186 },
1187 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188 .ctl_name = VM_MIN_FREE_KBYTES,
1189 .procname = "min_free_kbytes",
1190 .data = &min_free_kbytes,
1191 .maxlen = sizeof(min_free_kbytes),
1192 .mode = 0644,
1193 .proc_handler = &min_free_kbytes_sysctl_handler,
1194 .strategy = &sysctl_intvec,
1195 .extra1 = &zero,
1196 },
Rohit Seth8ad4b1f2006-01-08 01:00:40 -08001197 {
1198 .ctl_name = VM_PERCPU_PAGELIST_FRACTION,
1199 .procname = "percpu_pagelist_fraction",
1200 .data = &percpu_pagelist_fraction,
1201 .maxlen = sizeof(percpu_pagelist_fraction),
1202 .mode = 0644,
1203 .proc_handler = &percpu_pagelist_fraction_sysctl_handler,
1204 .strategy = &sysctl_intvec,
1205 .extra1 = &min_percpu_pagelist_fract,
1206 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207#ifdef CONFIG_MMU
1208 {
1209 .ctl_name = VM_MAX_MAP_COUNT,
1210 .procname = "max_map_count",
1211 .data = &sysctl_max_map_count,
1212 .maxlen = sizeof(sysctl_max_map_count),
1213 .mode = 0644,
1214 .proc_handler = &proc_dointvec
1215 },
Paul Mundtdd8632a2009-01-08 12:04:47 +00001216#else
1217 {
1218 .ctl_name = CTL_UNNUMBERED,
1219 .procname = "nr_trim_pages",
1220 .data = &sysctl_nr_trim_pages,
1221 .maxlen = sizeof(sysctl_nr_trim_pages),
1222 .mode = 0644,
1223 .proc_handler = &proc_dointvec_minmax,
1224 .strategy = &sysctl_intvec,
1225 .extra1 = &zero,
1226 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227#endif
1228 {
1229 .ctl_name = VM_LAPTOP_MODE,
1230 .procname = "laptop_mode",
1231 .data = &laptop_mode,
1232 .maxlen = sizeof(laptop_mode),
1233 .mode = 0644,
Bart Samweled5b43f2006-03-24 03:15:49 -08001234 .proc_handler = &proc_dointvec_jiffies,
1235 .strategy = &sysctl_jiffies,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 },
1237 {
1238 .ctl_name = VM_BLOCK_DUMP,
1239 .procname = "block_dump",
1240 .data = &block_dump,
1241 .maxlen = sizeof(block_dump),
1242 .mode = 0644,
1243 .proc_handler = &proc_dointvec,
1244 .strategy = &sysctl_intvec,
1245 .extra1 = &zero,
1246 },
1247 {
1248 .ctl_name = VM_VFS_CACHE_PRESSURE,
1249 .procname = "vfs_cache_pressure",
1250 .data = &sysctl_vfs_cache_pressure,
1251 .maxlen = sizeof(sysctl_vfs_cache_pressure),
1252 .mode = 0644,
1253 .proc_handler = &proc_dointvec,
1254 .strategy = &sysctl_intvec,
1255 .extra1 = &zero,
1256 },
1257#ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
1258 {
1259 .ctl_name = VM_LEGACY_VA_LAYOUT,
1260 .procname = "legacy_va_layout",
1261 .data = &sysctl_legacy_va_layout,
1262 .maxlen = sizeof(sysctl_legacy_va_layout),
1263 .mode = 0644,
1264 .proc_handler = &proc_dointvec,
1265 .strategy = &sysctl_intvec,
1266 .extra1 = &zero,
1267 },
1268#endif
Christoph Lameter17436602006-01-18 17:42:32 -08001269#ifdef CONFIG_NUMA
1270 {
1271 .ctl_name = VM_ZONE_RECLAIM_MODE,
1272 .procname = "zone_reclaim_mode",
1273 .data = &zone_reclaim_mode,
1274 .maxlen = sizeof(zone_reclaim_mode),
1275 .mode = 0644,
1276 .proc_handler = &proc_dointvec,
Christoph Lameterc84db232006-02-01 03:05:29 -08001277 .strategy = &sysctl_intvec,
1278 .extra1 = &zero,
Christoph Lameter17436602006-01-18 17:42:32 -08001279 },
Christoph Lameter96146342006-07-03 00:24:13 -07001280 {
1281 .ctl_name = VM_MIN_UNMAPPED,
1282 .procname = "min_unmapped_ratio",
1283 .data = &sysctl_min_unmapped_ratio,
1284 .maxlen = sizeof(sysctl_min_unmapped_ratio),
1285 .mode = 0644,
1286 .proc_handler = &sysctl_min_unmapped_ratio_sysctl_handler,
1287 .strategy = &sysctl_intvec,
1288 .extra1 = &zero,
1289 .extra2 = &one_hundred,
1290 },
Christoph Lameter0ff38492006-09-25 23:31:52 -07001291 {
1292 .ctl_name = VM_MIN_SLAB,
1293 .procname = "min_slab_ratio",
1294 .data = &sysctl_min_slab_ratio,
1295 .maxlen = sizeof(sysctl_min_slab_ratio),
1296 .mode = 0644,
1297 .proc_handler = &sysctl_min_slab_ratio_sysctl_handler,
1298 .strategy = &sysctl_intvec,
1299 .extra1 = &zero,
1300 .extra2 = &one_hundred,
1301 },
Christoph Lameter17436602006-01-18 17:42:32 -08001302#endif
Christoph Lameter77461ab2007-05-09 02:35:13 -07001303#ifdef CONFIG_SMP
1304 {
1305 .ctl_name = CTL_UNNUMBERED,
1306 .procname = "stat_interval",
1307 .data = &sysctl_stat_interval,
1308 .maxlen = sizeof(sysctl_stat_interval),
1309 .mode = 0644,
1310 .proc_handler = &proc_dointvec_jiffies,
1311 .strategy = &sysctl_jiffies,
1312 },
1313#endif
Eric Parised032182007-06-28 15:55:21 -04001314 {
1315 .ctl_name = CTL_UNNUMBERED,
1316 .procname = "mmap_min_addr",
Eric Paris788084a2009-07-31 12:54:11 -04001317 .data = &dac_mmap_min_addr,
1318 .maxlen = sizeof(unsigned long),
Eric Parised032182007-06-28 15:55:21 -04001319 .mode = 0644,
Eric Paris788084a2009-07-31 12:54:11 -04001320 .proc_handler = &mmap_min_addr_handler,
Eric Parised032182007-06-28 15:55:21 -04001321 },
KAMEZAWA Hiroyukif0c0b2b2007-07-15 23:38:01 -07001322#ifdef CONFIG_NUMA
1323 {
1324 .ctl_name = CTL_UNNUMBERED,
1325 .procname = "numa_zonelist_order",
1326 .data = &numa_zonelist_order,
1327 .maxlen = NUMA_ZONELIST_ORDER_LEN,
1328 .mode = 0644,
1329 .proc_handler = &numa_zonelist_order_handler,
1330 .strategy = &sysctl_string,
1331 },
1332#endif
Al Viro2b8232c2007-10-13 08:16:04 +01001333#if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \
Paul Mundt5c36e652007-03-01 10:07:42 +09001334 (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
Ingo Molnare6e54942006-06-27 02:53:50 -07001335 {
1336 .ctl_name = VM_VDSO_ENABLED,
1337 .procname = "vdso_enabled",
1338 .data = &vdso_enabled,
1339 .maxlen = sizeof(vdso_enabled),
1340 .mode = 0644,
1341 .proc_handler = &proc_dointvec,
1342 .strategy = &sysctl_intvec,
1343 .extra1 = &zero,
1344 },
1345#endif
Bron Gondwana195cf452008-02-04 22:29:20 -08001346#ifdef CONFIG_HIGHMEM
1347 {
1348 .ctl_name = CTL_UNNUMBERED,
1349 .procname = "highmem_is_dirtyable",
1350 .data = &vm_highmem_is_dirtyable,
1351 .maxlen = sizeof(vm_highmem_is_dirtyable),
1352 .mode = 0644,
1353 .proc_handler = &proc_dointvec_minmax,
1354 .strategy = &sysctl_intvec,
1355 .extra1 = &zero,
1356 .extra2 = &one,
1357 },
1358#endif
Peter Zijlstra4be6f6b2009-04-13 14:39:33 -07001359 {
1360 .ctl_name = CTL_UNNUMBERED,
1361 .procname = "scan_unevictable_pages",
1362 .data = &scan_unevictable_pages,
1363 .maxlen = sizeof(scan_unevictable_pages),
1364 .mode = 0644,
1365 .proc_handler = &scan_unevictable_handler,
1366 },
Andrew Morton2be7fe02007-07-15 23:41:21 -07001367/*
1368 * NOTE: do not add new entries to this table unless you have read
1369 * Documentation/sysctl/ctl_unnumbered.txt
1370 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371 { .ctl_name = 0 }
1372};
1373
Eric W. Biederman2abc26f2007-02-14 00:34:07 -08001374#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001375static struct ctl_table binfmt_misc_table[] = {
Eric W. Biederman2abc26f2007-02-14 00:34:07 -08001376 { .ctl_name = 0 }
1377};
1378#endif
1379
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001380static struct ctl_table fs_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 {
1382 .ctl_name = FS_NRINODE,
1383 .procname = "inode-nr",
1384 .data = &inodes_stat,
1385 .maxlen = 2*sizeof(int),
1386 .mode = 0444,
1387 .proc_handler = &proc_dointvec,
1388 },
1389 {
1390 .ctl_name = FS_STATINODE,
1391 .procname = "inode-state",
1392 .data = &inodes_stat,
1393 .maxlen = 7*sizeof(int),
1394 .mode = 0444,
1395 .proc_handler = &proc_dointvec,
1396 },
1397 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398 .procname = "file-nr",
1399 .data = &files_stat,
1400 .maxlen = 3*sizeof(int),
1401 .mode = 0444,
Dipankar Sarma529bf6b2006-03-07 21:55:35 -08001402 .proc_handler = &proc_nr_files,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403 },
1404 {
1405 .ctl_name = FS_MAXFILE,
1406 .procname = "file-max",
1407 .data = &files_stat.max_files,
1408 .maxlen = sizeof(int),
1409 .mode = 0644,
1410 .proc_handler = &proc_dointvec,
1411 },
1412 {
Eric Dumazet9cfe0152008-02-06 01:37:16 -08001413 .ctl_name = CTL_UNNUMBERED,
1414 .procname = "nr_open",
1415 .data = &sysctl_nr_open,
1416 .maxlen = sizeof(int),
1417 .mode = 0644,
Al Viroeceea0b2008-05-10 10:08:32 -04001418 .proc_handler = &proc_dointvec_minmax,
1419 .extra1 = &sysctl_nr_open_min,
1420 .extra2 = &sysctl_nr_open_max,
Eric Dumazet9cfe0152008-02-06 01:37:16 -08001421 },
1422 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 .ctl_name = FS_DENTRY,
1424 .procname = "dentry-state",
1425 .data = &dentry_stat,
1426 .maxlen = 6*sizeof(int),
1427 .mode = 0444,
1428 .proc_handler = &proc_dointvec,
1429 },
1430 {
1431 .ctl_name = FS_OVERFLOWUID,
1432 .procname = "overflowuid",
1433 .data = &fs_overflowuid,
1434 .maxlen = sizeof(int),
1435 .mode = 0644,
1436 .proc_handler = &proc_dointvec_minmax,
1437 .strategy = &sysctl_intvec,
1438 .extra1 = &minolduid,
1439 .extra2 = &maxolduid,
1440 },
1441 {
1442 .ctl_name = FS_OVERFLOWGID,
1443 .procname = "overflowgid",
1444 .data = &fs_overflowgid,
1445 .maxlen = sizeof(int),
1446 .mode = 0644,
1447 .proc_handler = &proc_dointvec_minmax,
1448 .strategy = &sysctl_intvec,
1449 .extra1 = &minolduid,
1450 .extra2 = &maxolduid,
1451 },
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001452#ifdef CONFIG_FILE_LOCKING
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453 {
1454 .ctl_name = FS_LEASES,
1455 .procname = "leases-enable",
1456 .data = &leases_enable,
1457 .maxlen = sizeof(int),
1458 .mode = 0644,
1459 .proc_handler = &proc_dointvec,
1460 },
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001461#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462#ifdef CONFIG_DNOTIFY
1463 {
1464 .ctl_name = FS_DIR_NOTIFY,
1465 .procname = "dir-notify-enable",
1466 .data = &dir_notify_enable,
1467 .maxlen = sizeof(int),
1468 .mode = 0644,
1469 .proc_handler = &proc_dointvec,
1470 },
1471#endif
1472#ifdef CONFIG_MMU
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001473#ifdef CONFIG_FILE_LOCKING
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 {
1475 .ctl_name = FS_LEASE_TIME,
1476 .procname = "lease-break-time",
1477 .data = &lease_break_time,
1478 .maxlen = sizeof(int),
1479 .mode = 0644,
Matthew Wilcox8e654fb2009-04-02 16:58:33 -07001480 .proc_handler = &proc_dointvec,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 },
Thomas Petazzonibfcd17a2008-08-06 15:12:22 +02001482#endif
Thomas Petazzoniebf3f092008-10-15 22:05:12 -07001483#ifdef CONFIG_AIO
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 .procname = "aio-nr",
1486 .data = &aio_nr,
1487 .maxlen = sizeof(aio_nr),
1488 .mode = 0444,
Zach Brownd55b5fd2005-11-07 00:59:31 -08001489 .proc_handler = &proc_doulongvec_minmax,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 },
1491 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 .procname = "aio-max-nr",
1493 .data = &aio_max_nr,
1494 .maxlen = sizeof(aio_max_nr),
1495 .mode = 0644,
Zach Brownd55b5fd2005-11-07 00:59:31 -08001496 .proc_handler = &proc_doulongvec_minmax,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 },
Thomas Petazzoniebf3f092008-10-15 22:05:12 -07001498#endif /* CONFIG_AIO */
Amy Griffis2d9048e2006-06-01 13:10:59 -07001499#ifdef CONFIG_INOTIFY_USER
Robert Love0399cb02005-07-13 12:38:18 -04001500 {
1501 .ctl_name = FS_INOTIFY,
1502 .procname = "inotify",
1503 .mode = 0555,
1504 .child = inotify_table,
1505 },
1506#endif
Davide Libenzi7ef99642008-12-01 13:13:55 -08001507#ifdef CONFIG_EPOLL
1508 {
1509 .procname = "epoll",
1510 .mode = 0555,
1511 .child = epoll_table,
1512 },
1513#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514#endif
Alan Coxd6e71142005-06-23 00:09:43 -07001515 {
1516 .ctl_name = KERN_SETUID_DUMPABLE,
1517 .procname = "suid_dumpable",
1518 .data = &suid_dumpable,
1519 .maxlen = sizeof(int),
1520 .mode = 0644,
Matthew Wilcox8e654fb2009-04-02 16:58:33 -07001521 .proc_handler = &proc_dointvec_minmax,
1522 .strategy = &sysctl_intvec,
1523 .extra1 = &zero,
1524 .extra2 = &two,
Alan Coxd6e71142005-06-23 00:09:43 -07001525 },
Eric W. Biederman2abc26f2007-02-14 00:34:07 -08001526#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
1527 {
1528 .ctl_name = CTL_UNNUMBERED,
1529 .procname = "binfmt_misc",
1530 .mode = 0555,
1531 .child = binfmt_misc_table,
1532 },
1533#endif
Andrew Morton2be7fe02007-07-15 23:41:21 -07001534/*
1535 * NOTE: do not add new entries to this table unless you have read
1536 * Documentation/sysctl/ctl_unnumbered.txt
1537 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 { .ctl_name = 0 }
1539};
1540
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001541static struct ctl_table debug_table[] = {
Olof Johanssond0c3d532007-10-12 10:20:07 +10001542#if defined(CONFIG_X86) || defined(CONFIG_PPC)
Masoud Asgharifard Sharbianiabd4f752007-07-22 11:12:28 +02001543 {
1544 .ctl_name = CTL_UNNUMBERED,
1545 .procname = "exception-trace",
1546 .data = &show_unhandled_signals,
1547 .maxlen = sizeof(int),
1548 .mode = 0644,
1549 .proc_handler = proc_dointvec
1550 },
1551#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 { .ctl_name = 0 }
1553};
1554
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001555static struct ctl_table dev_table[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 { .ctl_name = 0 }
Robert Love0eeca282005-07-12 17:06:03 -04001557};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558
Al Viro330d57f2005-11-04 10:18:40 +00001559static DEFINE_SPINLOCK(sysctl_lock);
1560
1561/* called under sysctl_lock */
1562static int use_table(struct ctl_table_header *p)
1563{
1564 if (unlikely(p->unregistering))
1565 return 0;
1566 p->used++;
1567 return 1;
1568}
1569
1570/* called under sysctl_lock */
1571static void unuse_table(struct ctl_table_header *p)
1572{
1573 if (!--p->used)
1574 if (unlikely(p->unregistering))
1575 complete(p->unregistering);
1576}
1577
1578/* called under sysctl_lock, will reacquire if has to wait */
1579static void start_unregistering(struct ctl_table_header *p)
1580{
1581 /*
1582 * if p->used is 0, nobody will ever touch that entry again;
1583 * we'll eliminate all paths to it before dropping sysctl_lock
1584 */
1585 if (unlikely(p->used)) {
1586 struct completion wait;
1587 init_completion(&wait);
1588 p->unregistering = &wait;
1589 spin_unlock(&sysctl_lock);
1590 wait_for_completion(&wait);
1591 spin_lock(&sysctl_lock);
Al Virof7e6ced2008-07-15 01:44:23 -04001592 } else {
1593 /* anything non-NULL; we'll never dereference it */
1594 p->unregistering = ERR_PTR(-EINVAL);
Al Viro330d57f2005-11-04 10:18:40 +00001595 }
1596 /*
1597 * do not remove from the list until nobody holds it; walking the
1598 * list in do_sysctl() relies on that.
1599 */
1600 list_del_init(&p->ctl_entry);
1601}
1602
Al Virof7e6ced2008-07-15 01:44:23 -04001603void sysctl_head_get(struct ctl_table_header *head)
1604{
1605 spin_lock(&sysctl_lock);
1606 head->count++;
1607 spin_unlock(&sysctl_lock);
1608}
1609
1610void sysctl_head_put(struct ctl_table_header *head)
1611{
1612 spin_lock(&sysctl_lock);
1613 if (!--head->count)
1614 kfree(head);
1615 spin_unlock(&sysctl_lock);
1616}
1617
1618struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
1619{
1620 if (!head)
1621 BUG();
1622 spin_lock(&sysctl_lock);
1623 if (!use_table(head))
1624 head = ERR_PTR(-ENOENT);
1625 spin_unlock(&sysctl_lock);
1626 return head;
1627}
1628
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001629void sysctl_head_finish(struct ctl_table_header *head)
1630{
1631 if (!head)
1632 return;
1633 spin_lock(&sysctl_lock);
1634 unuse_table(head);
1635 spin_unlock(&sysctl_lock);
1636}
1637
Al Viro73455092008-07-14 21:22:20 -04001638static struct ctl_table_set *
1639lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces)
1640{
1641 struct ctl_table_set *set = &root->default_set;
1642 if (root->lookup)
1643 set = root->lookup(root, namespaces);
1644 return set;
1645}
1646
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001647static struct list_head *
1648lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001649{
Al Viro73455092008-07-14 21:22:20 -04001650 struct ctl_table_set *set = lookup_header_set(root, namespaces);
1651 return &set->list;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001652}
1653
1654struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
1655 struct ctl_table_header *prev)
1656{
1657 struct ctl_table_root *root;
1658 struct list_head *header_list;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001659 struct ctl_table_header *head;
1660 struct list_head *tmp;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001661
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001662 spin_lock(&sysctl_lock);
1663 if (prev) {
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001664 head = prev;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001665 tmp = &prev->ctl_entry;
1666 unuse_table(prev);
1667 goto next;
1668 }
1669 tmp = &root_table_header.ctl_entry;
1670 for (;;) {
1671 head = list_entry(tmp, struct ctl_table_header, ctl_entry);
1672
1673 if (!use_table(head))
1674 goto next;
1675 spin_unlock(&sysctl_lock);
1676 return head;
1677 next:
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001678 root = head->root;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001679 tmp = tmp->next;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001680 header_list = lookup_header_list(root, namespaces);
1681 if (tmp != header_list)
1682 continue;
1683
1684 do {
1685 root = list_entry(root->root_list.next,
1686 struct ctl_table_root, root_list);
1687 if (root == &sysctl_table_root)
1688 goto out;
1689 header_list = lookup_header_list(root, namespaces);
1690 } while (list_empty(header_list));
1691 tmp = header_list->next;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001692 }
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001693out:
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001694 spin_unlock(&sysctl_lock);
1695 return NULL;
1696}
1697
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001698struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
1699{
1700 return __sysctl_head_next(current->nsproxy, prev);
1701}
1702
1703void register_sysctl_root(struct ctl_table_root *root)
1704{
1705 spin_lock(&sysctl_lock);
1706 list_add_tail(&root->root_list, &sysctl_table_root.root_list);
1707 spin_unlock(&sysctl_lock);
1708}
1709
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07001710#ifdef CONFIG_SYSCTL_SYSCALL
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001711/* Perform the actual read/write of a sysctl table entry. */
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001712static int do_sysctl_strategy(struct ctl_table_root *root,
1713 struct ctl_table *table,
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001714 void __user *oldval, size_t __user *oldlenp,
1715 void __user *newval, size_t newlen)
1716{
1717 int op = 0, rc;
1718
1719 if (oldval)
Al Viroe6305c42008-07-15 21:03:57 -04001720 op |= MAY_READ;
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001721 if (newval)
Al Viroe6305c42008-07-15 21:03:57 -04001722 op |= MAY_WRITE;
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001723 if (sysctl_perm(root, table, op))
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001724 return -EPERM;
1725
1726 if (table->strategy) {
Alexey Dobriyanf221e722008-10-15 22:04:23 -07001727 rc = table->strategy(table, oldval, oldlenp, newval, newlen);
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001728 if (rc < 0)
1729 return rc;
1730 if (rc > 0)
1731 return 0;
1732 }
1733
1734 /* If there is no strategy routine, or if the strategy returns
1735 * zero, proceed with automatic r/w */
1736 if (table->data && table->maxlen) {
Alexey Dobriyanf221e722008-10-15 22:04:23 -07001737 rc = sysctl_data(table, oldval, oldlenp, newval, newlen);
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001738 if (rc < 0)
1739 return rc;
1740 }
1741 return 0;
1742}
1743
1744static int parse_table(int __user *name, int nlen,
1745 void __user *oldval, size_t __user *oldlenp,
1746 void __user *newval, size_t newlen,
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001747 struct ctl_table_root *root,
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001748 struct ctl_table *table)
1749{
1750 int n;
1751repeat:
1752 if (!nlen)
1753 return -ENOTDIR;
1754 if (get_user(n, name))
1755 return -EFAULT;
1756 for ( ; table->ctl_name || table->procname; table++) {
1757 if (!table->ctl_name)
1758 continue;
1759 if (n == table->ctl_name) {
1760 int error;
1761 if (table->child) {
Al Viroe6305c42008-07-15 21:03:57 -04001762 if (sysctl_perm(root, table, MAY_EXEC))
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001763 return -EPERM;
1764 name++;
1765 nlen--;
1766 table = table->child;
1767 goto repeat;
1768 }
Alexey Dobriyanf221e722008-10-15 22:04:23 -07001769 error = do_sysctl_strategy(root, table,
Pavel Emelyanov2c4c7152008-04-29 01:02:41 -07001770 oldval, oldlenp,
1771 newval, newlen);
1772 return error;
1773 }
1774 }
1775 return -ENOTDIR;
1776}
1777
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp,
1779 void __user *newval, size_t newlen)
1780{
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001781 struct ctl_table_header *head;
Al Viro330d57f2005-11-04 10:18:40 +00001782 int error = -ENOTDIR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783
1784 if (nlen <= 0 || nlen >= CTL_MAXNAME)
1785 return -ENOTDIR;
1786 if (oldval) {
1787 int old_len;
1788 if (!oldlenp || get_user(old_len, oldlenp))
1789 return -EFAULT;
1790 }
Al Viro330d57f2005-11-04 10:18:40 +00001791
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001792 for (head = sysctl_head_next(NULL); head;
1793 head = sysctl_head_next(head)) {
Al Viro330d57f2005-11-04 10:18:40 +00001794 error = parse_table(name, nlen, oldval, oldlenp,
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001795 newval, newlen,
1796 head->root, head->ctl_table);
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001797 if (error != -ENOTDIR) {
1798 sysctl_head_finish(head);
Al Viro330d57f2005-11-04 10:18:40 +00001799 break;
Eric W. Biederman805b5d52007-02-14 00:34:11 -08001800 }
1801 }
Al Viro330d57f2005-11-04 10:18:40 +00001802 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803}
1804
Heiko Carstens1e7bfb22009-01-14 14:14:29 +01001805SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806{
1807 struct __sysctl_args tmp;
1808 int error;
1809
1810 if (copy_from_user(&tmp, args, sizeof(tmp)))
1811 return -EFAULT;
1812
Eric W. Biederman7058cb02007-10-18 03:05:58 -07001813 error = deprecated_sysctl_warning(&tmp);
1814 if (error)
1815 goto out;
1816
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 lock_kernel();
1818 error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp,
1819 tmp.newval, tmp.newlen);
1820 unlock_kernel();
Eric W. Biederman7058cb02007-10-18 03:05:58 -07001821out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 return error;
1823}
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07001824#endif /* CONFIG_SYSCTL_SYSCALL */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
1826/*
Eric W. Biederman1ff007e2007-02-14 00:34:11 -08001827 * sysctl_perm does NOT grant the superuser all rights automatically, because
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 * some sysctl variables are readonly even to root.
1829 */
1830
1831static int test_perm(int mode, int op)
1832{
David Howells76aac0e2008-11-14 10:39:12 +11001833 if (!current_euid())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 mode >>= 6;
1835 else if (in_egroup_p(0))
1836 mode >>= 3;
Al Viroe6305c42008-07-15 21:03:57 -04001837 if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 return 0;
1839 return -EACCES;
1840}
1841
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001842int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843{
1844 int error;
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001845 int mode;
1846
Al Viroe6305c42008-07-15 21:03:57 -04001847 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 if (error)
1849 return error;
Pavel Emelyanovd7321cd2008-04-29 01:02:44 -07001850
1851 if (root->permissions)
1852 mode = root->permissions(root, current->nsproxy, table);
1853 else
1854 mode = table->mode;
1855
1856 return test_perm(mode, op);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857}
1858
Eric W. Biedermand912b0c2007-02-14 00:34:13 -08001859static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
1860{
1861 for (; table->ctl_name || table->procname; table++) {
1862 table->parent = parent;
1863 if (table->child)
1864 sysctl_set_parent(table, table->child);
1865 }
1866}
1867
1868static __init int sysctl_init(void)
1869{
1870 sysctl_set_parent(NULL, root_table);
Holger Schurig88f458e2008-04-29 01:02:36 -07001871#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
1872 {
1873 int err;
1874 err = sysctl_check_table(current->nsproxy, root_table);
1875 }
1876#endif
Eric W. Biedermand912b0c2007-02-14 00:34:13 -08001877 return 0;
1878}
1879
1880core_initcall(sysctl_init);
1881
Al Virobfbcf032008-07-27 06:31:22 +01001882static struct ctl_table *is_branch_in(struct ctl_table *branch,
1883 struct ctl_table *table)
Al Viroae7edec2008-07-15 06:33:31 -04001884{
1885 struct ctl_table *p;
1886 const char *s = branch->procname;
1887
1888 /* branch should have named subdirectory as its first element */
1889 if (!s || !branch->child)
Al Virobfbcf032008-07-27 06:31:22 +01001890 return NULL;
Al Viroae7edec2008-07-15 06:33:31 -04001891
1892 /* ... and nothing else */
1893 if (branch[1].procname || branch[1].ctl_name)
Al Virobfbcf032008-07-27 06:31:22 +01001894 return NULL;
Al Viroae7edec2008-07-15 06:33:31 -04001895
1896 /* table should contain subdirectory with the same name */
1897 for (p = table; p->procname || p->ctl_name; p++) {
1898 if (!p->child)
1899 continue;
1900 if (p->procname && strcmp(p->procname, s) == 0)
Al Virobfbcf032008-07-27 06:31:22 +01001901 return p;
Al Viroae7edec2008-07-15 06:33:31 -04001902 }
Al Virobfbcf032008-07-27 06:31:22 +01001903 return NULL;
Al Viroae7edec2008-07-15 06:33:31 -04001904}
1905
1906/* see if attaching q to p would be an improvement */
1907static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)
1908{
1909 struct ctl_table *to = p->ctl_table, *by = q->ctl_table;
Al Virobfbcf032008-07-27 06:31:22 +01001910 struct ctl_table *next;
Al Viroae7edec2008-07-15 06:33:31 -04001911 int is_better = 0;
1912 int not_in_parent = !p->attached_by;
1913
Al Virobfbcf032008-07-27 06:31:22 +01001914 while ((next = is_branch_in(by, to)) != NULL) {
Al Viroae7edec2008-07-15 06:33:31 -04001915 if (by == q->attached_by)
1916 is_better = 1;
1917 if (to == p->attached_by)
1918 not_in_parent = 1;
1919 by = by->child;
Al Virobfbcf032008-07-27 06:31:22 +01001920 to = next->child;
Al Viroae7edec2008-07-15 06:33:31 -04001921 }
1922
1923 if (is_better && not_in_parent) {
1924 q->attached_by = by;
1925 q->attached_to = to;
1926 q->parent = p;
1927 }
1928}
1929
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930/**
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11001931 * __register_sysctl_paths - register a sysctl hierarchy
1932 * @root: List of sysctl headers to register on
1933 * @namespaces: Data to compute which lists of sysctl entries are visible
Eric W. Biederman29e796f2007-11-30 23:50:18 +11001934 * @path: The path to the directory the sysctl table is in.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935 * @table: the top-level table structure
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936 *
1937 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
Eric W. Biederman29e796f2007-11-30 23:50:18 +11001938 * array. A completely 0 filled entry terminates the table.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 *
Eric W. Biedermand8217f02007-10-18 03:05:22 -07001940 * The members of the &struct ctl_table structure are used as follows:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 *
1942 * ctl_name - This is the numeric sysctl value used by sysctl(2). The number
1943 * must be unique within that level of sysctl
1944 *
1945 * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
1946 * enter a sysctl file
1947 *
1948 * data - a pointer to data for use by proc_handler
1949 *
1950 * maxlen - the maximum size in bytes of the data
1951 *
1952 * mode - the file permissions for the /proc/sys file, and for sysctl(2)
1953 *
1954 * child - a pointer to the child sysctl table if this entry is a directory, or
1955 * %NULL.
1956 *
1957 * proc_handler - the text handler routine (described below)
1958 *
1959 * strategy - the strategy routine (described below)
1960 *
1961 * de - for internal use by the sysctl routines
1962 *
1963 * extra1, extra2 - extra pointers usable by the proc handler routines
1964 *
1965 * Leaf nodes in the sysctl tree will be represented by a single file
1966 * under /proc; non-leaf nodes will be represented by directories.
1967 *
1968 * sysctl(2) can automatically manage read and write requests through
1969 * the sysctl table. The data and maxlen fields of the ctl_table
1970 * struct enable minimal validation of the values being written to be
1971 * performed, and the mode field allows minimal authentication.
1972 *
1973 * More sophisticated management can be enabled by the provision of a
1974 * strategy routine with the table entry. This will be called before
1975 * any automatic read or write of the data is performed.
1976 *
1977 * The strategy routine may return
1978 *
1979 * < 0 - Error occurred (error is passed to user process)
1980 *
1981 * 0 - OK - proceed with automatic read or write.
1982 *
1983 * > 0 - OK - read or write has been done by the strategy routine, so
1984 * return immediately.
1985 *
1986 * There must be a proc_handler routine for any terminal nodes
1987 * mirrored under /proc/sys (non-terminals are handled by a built-in
1988 * directory handler). Several default handlers are available to
1989 * cover common cases -
1990 *
1991 * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
1992 * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(),
1993 * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax()
1994 *
1995 * It is the handler's job to read the input buffer from user memory
1996 * and process it. The handler should return 0 on success.
1997 *
1998 * This routine returns %NULL on a failure to register, and a pointer
1999 * to the table header on success.
2000 */
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002001struct ctl_table_header *__register_sysctl_paths(
2002 struct ctl_table_root *root,
2003 struct nsproxy *namespaces,
2004 const struct ctl_path *path, struct ctl_table *table)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005{
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002006 struct ctl_table_header *header;
2007 struct ctl_table *new, **prevp;
2008 unsigned int n, npath;
Al Viroae7edec2008-07-15 06:33:31 -04002009 struct ctl_table_set *set;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002010
2011 /* Count the path components */
2012 for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath)
2013 ;
2014
2015 /*
2016 * For each path component, allocate a 2-element ctl_table array.
2017 * The first array element will be filled with the sysctl entry
2018 * for this, the second will be the sentinel (ctl_name == 0).
2019 *
2020 * We allocate everything in one go so that we don't have to
2021 * worry about freeing additional memory in unregister_sysctl_table.
2022 */
2023 header = kzalloc(sizeof(struct ctl_table_header) +
2024 (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
2025 if (!header)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026 return NULL;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002027
2028 new = (struct ctl_table *) (header + 1);
2029
2030 /* Now connect the dots */
2031 prevp = &header->ctl_table;
2032 for (n = 0; n < npath; ++n, ++path) {
2033 /* Copy the procname */
2034 new->procname = path->procname;
2035 new->ctl_name = path->ctl_name;
2036 new->mode = 0555;
2037
2038 *prevp = new;
2039 prevp = &new->child;
2040
2041 new += 2;
2042 }
2043 *prevp = table;
Eric W. Biederman23eb06d2007-11-30 23:52:10 +11002044 header->ctl_table_arg = table;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002045
2046 INIT_LIST_HEAD(&header->ctl_entry);
2047 header->used = 0;
2048 header->unregistering = NULL;
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002049 header->root = root;
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002050 sysctl_set_parent(NULL, header->ctl_table);
Al Virof7e6ced2008-07-15 01:44:23 -04002051 header->count = 1;
Holger Schurig88f458e2008-04-29 01:02:36 -07002052#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002053 if (sysctl_check_table(namespaces, header->ctl_table)) {
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002054 kfree(header);
Eric W. Biedermanfc6cd252007-10-18 03:05:54 -07002055 return NULL;
2056 }
Holger Schurig88f458e2008-04-29 01:02:36 -07002057#endif
Al Viro330d57f2005-11-04 10:18:40 +00002058 spin_lock(&sysctl_lock);
Al Viro73455092008-07-14 21:22:20 -04002059 header->set = lookup_header_set(root, namespaces);
Al Viroae7edec2008-07-15 06:33:31 -04002060 header->attached_by = header->ctl_table;
2061 header->attached_to = root_table;
2062 header->parent = &root_table_header;
2063 for (set = header->set; set; set = set->parent) {
2064 struct ctl_table_header *p;
2065 list_for_each_entry(p, &set->list, ctl_entry) {
2066 if (p->unregistering)
2067 continue;
2068 try_attach(p, header);
2069 }
2070 }
2071 header->parent->count++;
Al Viro73455092008-07-14 21:22:20 -04002072 list_add_tail(&header->ctl_entry, &header->set->list);
Al Viro330d57f2005-11-04 10:18:40 +00002073 spin_unlock(&sysctl_lock);
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002074
2075 return header;
2076}
2077
2078/**
Eric W. Biedermane51b6ba2007-11-30 23:54:00 +11002079 * register_sysctl_table_path - register a sysctl table hierarchy
2080 * @path: The path to the directory the sysctl table is in.
2081 * @table: the top-level table structure
2082 *
2083 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
2084 * array. A completely 0 filled entry terminates the table.
2085 *
2086 * See __register_sysctl_paths for more details.
2087 */
2088struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
2089 struct ctl_table *table)
2090{
2091 return __register_sysctl_paths(&sysctl_table_root, current->nsproxy,
2092 path, table);
2093}
2094
2095/**
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002096 * register_sysctl_table - register a sysctl table hierarchy
2097 * @table: the top-level table structure
2098 *
2099 * Register a sysctl table hierarchy. @table should be a filled in ctl_table
2100 * array. A completely 0 filled entry terminates the table.
2101 *
2102 * See register_sysctl_paths for more details.
2103 */
2104struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
2105{
2106 static const struct ctl_path null_path[] = { {} };
2107
2108 return register_sysctl_paths(null_path, table);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109}
2110
2111/**
2112 * unregister_sysctl_table - unregister a sysctl table hierarchy
2113 * @header: the header returned from register_sysctl_table
2114 *
2115 * Unregisters the sysctl table and all children. proc entries may not
2116 * actually be removed until they are no longer used by anyone.
2117 */
2118void unregister_sysctl_table(struct ctl_table_header * header)
2119{
Al Viro330d57f2005-11-04 10:18:40 +00002120 might_sleep();
Pavel Emelyanovf1dad162007-12-04 23:45:24 -08002121
2122 if (header == NULL)
2123 return;
2124
Al Viro330d57f2005-11-04 10:18:40 +00002125 spin_lock(&sysctl_lock);
2126 start_unregistering(header);
Al Viroae7edec2008-07-15 06:33:31 -04002127 if (!--header->parent->count) {
2128 WARN_ON(1);
2129 kfree(header->parent);
2130 }
Al Virof7e6ced2008-07-15 01:44:23 -04002131 if (!--header->count)
2132 kfree(header);
Al Viro330d57f2005-11-04 10:18:40 +00002133 spin_unlock(&sysctl_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134}
2135
Al Viro90434762008-07-15 08:54:06 -04002136int sysctl_is_seen(struct ctl_table_header *p)
2137{
2138 struct ctl_table_set *set = p->set;
2139 int res;
2140 spin_lock(&sysctl_lock);
2141 if (p->unregistering)
2142 res = 0;
2143 else if (!set->is_seen)
2144 res = 1;
2145 else
2146 res = set->is_seen(set);
2147 spin_unlock(&sysctl_lock);
2148 return res;
2149}
2150
Al Viro73455092008-07-14 21:22:20 -04002151void setup_sysctl_set(struct ctl_table_set *p,
2152 struct ctl_table_set *parent,
2153 int (*is_seen)(struct ctl_table_set *))
2154{
2155 INIT_LIST_HEAD(&p->list);
2156 p->parent = parent ? parent : &sysctl_table_root.default_set;
2157 p->is_seen = is_seen;
2158}
2159
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002160#else /* !CONFIG_SYSCTL */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002161struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002162{
2163 return NULL;
2164}
2165
Eric W. Biederman29e796f2007-11-30 23:50:18 +11002166struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
2167 struct ctl_table *table)
2168{
2169 return NULL;
2170}
2171
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002172void unregister_sysctl_table(struct ctl_table_header * table)
2173{
2174}
2175
Al Viro73455092008-07-14 21:22:20 -04002176void setup_sysctl_set(struct ctl_table_set *p,
2177 struct ctl_table_set *parent,
2178 int (*is_seen)(struct ctl_table_set *))
2179{
2180}
2181
Al Virof7e6ced2008-07-15 01:44:23 -04002182void sysctl_head_put(struct ctl_table_header *head)
2183{
2184}
2185
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002186#endif /* CONFIG_SYSCTL */
2187
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188/*
2189 * /proc/sys support
2190 */
2191
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002192#ifdef CONFIG_PROC_SYSCTL
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193
Adrian Bunkb1ba4dd2006-10-02 02:18:05 -07002194static int _proc_do_string(void* data, int maxlen, int write,
2195 struct file *filp, void __user *buffer,
2196 size_t *lenp, loff_t *ppos)
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002197{
2198 size_t len;
2199 char __user *p;
2200 char c;
Oleg Nesterov8d060872007-02-10 01:46:38 -08002201
2202 if (!data || !maxlen || !*lenp) {
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002203 *lenp = 0;
2204 return 0;
2205 }
Oleg Nesterov8d060872007-02-10 01:46:38 -08002206
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002207 if (write) {
2208 len = 0;
2209 p = buffer;
2210 while (len < *lenp) {
2211 if (get_user(c, p++))
2212 return -EFAULT;
2213 if (c == 0 || c == '\n')
2214 break;
2215 len++;
2216 }
2217 if (len >= maxlen)
2218 len = maxlen-1;
2219 if(copy_from_user(data, buffer, len))
2220 return -EFAULT;
2221 ((char *) data)[len] = 0;
2222 *ppos += *lenp;
2223 } else {
2224 len = strlen(data);
2225 if (len > maxlen)
2226 len = maxlen;
Oleg Nesterov8d060872007-02-10 01:46:38 -08002227
2228 if (*ppos > len) {
2229 *lenp = 0;
2230 return 0;
2231 }
2232
2233 data += *ppos;
2234 len -= *ppos;
2235
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002236 if (len > *lenp)
2237 len = *lenp;
2238 if (len)
2239 if(copy_to_user(buffer, data, len))
2240 return -EFAULT;
2241 if (len < *lenp) {
2242 if(put_user('\n', ((char __user *) buffer) + len))
2243 return -EFAULT;
2244 len++;
2245 }
2246 *lenp = len;
2247 *ppos += len;
2248 }
2249 return 0;
2250}
2251
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252/**
2253 * proc_dostring - read a string sysctl
2254 * @table: the sysctl table
2255 * @write: %TRUE if this is a write to the sysctl file
2256 * @filp: the file structure
2257 * @buffer: the user buffer
2258 * @lenp: the size of the user buffer
2259 * @ppos: file position
2260 *
2261 * Reads/writes a string from/to the user buffer. If the kernel
2262 * buffer provided is not large enough to hold the string, the
2263 * string is truncated. The copied string is %NULL-terminated.
2264 * If the string is being read by the user process, it is copied
2265 * and a newline '\n' is added. It is truncated if the buffer is
2266 * not large enough.
2267 *
2268 * Returns 0 on success.
2269 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002270int proc_dostring(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271 void __user *buffer, size_t *lenp, loff_t *ppos)
2272{
Sam Vilainf5dd3d62006-10-02 02:18:04 -07002273 return _proc_do_string(table->data, table->maxlen, write, filp,
2274 buffer, lenp, ppos);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002275}
2276
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277
2278static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp,
2279 int *valp,
2280 int write, void *data)
2281{
2282 if (write) {
2283 *valp = *negp ? -*lvalp : *lvalp;
2284 } else {
2285 int val = *valp;
2286 if (val < 0) {
2287 *negp = -1;
2288 *lvalp = (unsigned long)-val;
2289 } else {
2290 *negp = 0;
2291 *lvalp = (unsigned long)val;
2292 }
2293 }
2294 return 0;
2295}
2296
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002297static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002298 int write, struct file *filp, void __user *buffer,
2299 size_t *lenp, loff_t *ppos,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002300 int (*conv)(int *negp, unsigned long *lvalp, int *valp,
2301 int write, void *data),
2302 void *data)
2303{
2304#define TMPBUFLEN 21
Sukanto Ghosh7338f292009-06-17 16:27:50 -07002305 int *i, vleft, first = 1, neg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306 unsigned long lval;
2307 size_t left, len;
2308
2309 char buf[TMPBUFLEN], *p;
2310 char __user *s = buffer;
2311
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002312 if (!tbl_data || !table->maxlen || !*lenp ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313 (*ppos && !write)) {
2314 *lenp = 0;
2315 return 0;
2316 }
2317
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002318 i = (int *) tbl_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 vleft = table->maxlen / sizeof(*i);
2320 left = *lenp;
2321
2322 if (!conv)
2323 conv = do_proc_dointvec_conv;
2324
2325 for (; left && vleft--; i++, first=0) {
2326 if (write) {
2327 while (left) {
2328 char c;
2329 if (get_user(c, s))
2330 return -EFAULT;
2331 if (!isspace(c))
2332 break;
2333 left--;
2334 s++;
2335 }
2336 if (!left)
2337 break;
2338 neg = 0;
2339 len = left;
2340 if (len > sizeof(buf) - 1)
2341 len = sizeof(buf) - 1;
2342 if (copy_from_user(buf, s, len))
2343 return -EFAULT;
2344 buf[len] = 0;
2345 p = buf;
2346 if (*p == '-' && left > 1) {
2347 neg = 1;
BP, Praveenbd9b0ba2006-12-06 20:39:09 -08002348 p++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349 }
2350 if (*p < '0' || *p > '9')
2351 break;
2352
2353 lval = simple_strtoul(p, &p, 0);
2354
2355 len = p-buf;
2356 if ((len < left) && *p && !isspace(*p))
2357 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358 s += len;
2359 left -= len;
2360
2361 if (conv(&neg, &lval, i, 1, data))
2362 break;
2363 } else {
2364 p = buf;
2365 if (!first)
2366 *p++ = '\t';
2367
2368 if (conv(&neg, &lval, i, 0, data))
2369 break;
2370
2371 sprintf(p, "%s%lu", neg ? "-" : "", lval);
2372 len = strlen(buf);
2373 if (len > left)
2374 len = left;
2375 if(copy_to_user(s, buf, len))
2376 return -EFAULT;
2377 left -= len;
2378 s += len;
2379 }
2380 }
2381
2382 if (!write && !first && left) {
2383 if(put_user('\n', s))
2384 return -EFAULT;
2385 left--, s++;
2386 }
2387 if (write) {
2388 while (left) {
2389 char c;
2390 if (get_user(c, s++))
2391 return -EFAULT;
2392 if (!isspace(c))
2393 break;
2394 left--;
2395 }
2396 }
2397 if (write && first)
2398 return -EINVAL;
2399 *lenp -= left;
2400 *ppos += *lenp;
2401 return 0;
2402#undef TMPBUFLEN
2403}
2404
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002405static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp,
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002406 void __user *buffer, size_t *lenp, loff_t *ppos,
2407 int (*conv)(int *negp, unsigned long *lvalp, int *valp,
2408 int write, void *data),
2409 void *data)
2410{
2411 return __do_proc_dointvec(table->data, table, write, filp,
2412 buffer, lenp, ppos, conv, data);
2413}
2414
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415/**
2416 * proc_dointvec - read a vector of integers
2417 * @table: the sysctl table
2418 * @write: %TRUE if this is a write to the sysctl file
2419 * @filp: the file structure
2420 * @buffer: the user buffer
2421 * @lenp: the size of the user buffer
2422 * @ppos: file position
2423 *
2424 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2425 * values from/to the user buffer, treated as an ASCII string.
2426 *
2427 * Returns 0 on success.
2428 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002429int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430 void __user *buffer, size_t *lenp, loff_t *ppos)
2431{
2432 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
2433 NULL,NULL);
2434}
2435
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002436/*
Andi Kleen25ddbb12008-10-15 22:01:41 -07002437 * Taint values can only be increased
2438 * This means we can safely use a temporary.
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002439 */
Andi Kleen25ddbb12008-10-15 22:01:41 -07002440static int proc_taint(struct ctl_table *table, int write, struct file *filp,
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002441 void __user *buffer, size_t *lenp, loff_t *ppos)
2442{
Andi Kleen25ddbb12008-10-15 22:01:41 -07002443 struct ctl_table t;
2444 unsigned long tmptaint = get_taint();
2445 int err;
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002446
Bastian Blank91fcd412007-04-23 14:41:14 -07002447 if (write && !capable(CAP_SYS_ADMIN))
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002448 return -EPERM;
2449
Andi Kleen25ddbb12008-10-15 22:01:41 -07002450 t = *table;
2451 t.data = &tmptaint;
2452 err = proc_doulongvec_minmax(&t, write, filp, buffer, lenp, ppos);
2453 if (err < 0)
2454 return err;
2455
2456 if (write) {
2457 /*
2458 * Poor man's atomic or. Not worth adding a primitive
2459 * to everyone's atomic.h for this
2460 */
2461 int i;
2462 for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
2463 if ((tmptaint >> i) & 1)
2464 add_taint(i);
2465 }
2466 }
2467
2468 return err;
Theodore Ts'o34f5a392007-02-10 01:45:24 -08002469}
2470
Linus Torvalds1da177e2005-04-16 15:20:36 -07002471struct do_proc_dointvec_minmax_conv_param {
2472 int *min;
2473 int *max;
2474};
2475
2476static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp,
2477 int *valp,
2478 int write, void *data)
2479{
2480 struct do_proc_dointvec_minmax_conv_param *param = data;
2481 if (write) {
2482 int val = *negp ? -*lvalp : *lvalp;
2483 if ((param->min && *param->min > val) ||
2484 (param->max && *param->max < val))
2485 return -EINVAL;
2486 *valp = val;
2487 } else {
2488 int val = *valp;
2489 if (val < 0) {
2490 *negp = -1;
2491 *lvalp = (unsigned long)-val;
2492 } else {
2493 *negp = 0;
2494 *lvalp = (unsigned long)val;
2495 }
2496 }
2497 return 0;
2498}
2499
2500/**
2501 * proc_dointvec_minmax - read a vector of integers with min/max values
2502 * @table: the sysctl table
2503 * @write: %TRUE if this is a write to the sysctl file
2504 * @filp: the file structure
2505 * @buffer: the user buffer
2506 * @lenp: the size of the user buffer
2507 * @ppos: file position
2508 *
2509 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2510 * values from/to the user buffer, treated as an ASCII string.
2511 *
2512 * This routine will ensure the values are within the range specified by
2513 * table->extra1 (min) and table->extra2 (max).
2514 *
2515 * Returns 0 on success.
2516 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002517int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002518 void __user *buffer, size_t *lenp, loff_t *ppos)
2519{
2520 struct do_proc_dointvec_minmax_conv_param param = {
2521 .min = (int *) table->extra1,
2522 .max = (int *) table->extra2,
2523 };
2524 return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
2525 do_proc_dointvec_minmax_conv, &param);
2526}
2527
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002528static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 struct file *filp,
2530 void __user *buffer,
2531 size_t *lenp, loff_t *ppos,
2532 unsigned long convmul,
2533 unsigned long convdiv)
2534{
2535#define TMPBUFLEN 21
2536 unsigned long *i, *min, *max, val;
2537 int vleft, first=1, neg;
2538 size_t len, left;
2539 char buf[TMPBUFLEN], *p;
2540 char __user *s = buffer;
2541
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002542 if (!data || !table->maxlen || !*lenp ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 (*ppos && !write)) {
2544 *lenp = 0;
2545 return 0;
2546 }
2547
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002548 i = (unsigned long *) data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 min = (unsigned long *) table->extra1;
2550 max = (unsigned long *) table->extra2;
2551 vleft = table->maxlen / sizeof(unsigned long);
2552 left = *lenp;
2553
2554 for (; left && vleft--; i++, min++, max++, first=0) {
2555 if (write) {
2556 while (left) {
2557 char c;
2558 if (get_user(c, s))
2559 return -EFAULT;
2560 if (!isspace(c))
2561 break;
2562 left--;
2563 s++;
2564 }
2565 if (!left)
2566 break;
2567 neg = 0;
2568 len = left;
2569 if (len > TMPBUFLEN-1)
2570 len = TMPBUFLEN-1;
2571 if (copy_from_user(buf, s, len))
2572 return -EFAULT;
2573 buf[len] = 0;
2574 p = buf;
2575 if (*p == '-' && left > 1) {
2576 neg = 1;
BP, Praveenbd9b0ba2006-12-06 20:39:09 -08002577 p++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578 }
2579 if (*p < '0' || *p > '9')
2580 break;
2581 val = simple_strtoul(p, &p, 0) * convmul / convdiv ;
2582 len = p-buf;
2583 if ((len < left) && *p && !isspace(*p))
2584 break;
2585 if (neg)
2586 val = -val;
2587 s += len;
2588 left -= len;
2589
2590 if(neg)
2591 continue;
2592 if ((min && val < *min) || (max && val > *max))
2593 continue;
2594 *i = val;
2595 } else {
2596 p = buf;
2597 if (!first)
2598 *p++ = '\t';
2599 sprintf(p, "%lu", convdiv * (*i) / convmul);
2600 len = strlen(buf);
2601 if (len > left)
2602 len = left;
2603 if(copy_to_user(s, buf, len))
2604 return -EFAULT;
2605 left -= len;
2606 s += len;
2607 }
2608 }
2609
2610 if (!write && !first && left) {
2611 if(put_user('\n', s))
2612 return -EFAULT;
2613 left--, s++;
2614 }
2615 if (write) {
2616 while (left) {
2617 char c;
2618 if (get_user(c, s++))
2619 return -EFAULT;
2620 if (!isspace(c))
2621 break;
2622 left--;
2623 }
2624 }
2625 if (write && first)
2626 return -EINVAL;
2627 *lenp -= left;
2628 *ppos += *lenp;
2629 return 0;
2630#undef TMPBUFLEN
2631}
2632
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002633static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
Kirill Korotaevfcfbd542006-10-02 02:18:23 -07002634 struct file *filp,
2635 void __user *buffer,
2636 size_t *lenp, loff_t *ppos,
2637 unsigned long convmul,
2638 unsigned long convdiv)
2639{
2640 return __do_proc_doulongvec_minmax(table->data, table, write,
2641 filp, buffer, lenp, ppos, convmul, convdiv);
2642}
2643
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644/**
2645 * proc_doulongvec_minmax - read a vector of long integers with min/max values
2646 * @table: the sysctl table
2647 * @write: %TRUE if this is a write to the sysctl file
2648 * @filp: the file structure
2649 * @buffer: the user buffer
2650 * @lenp: the size of the user buffer
2651 * @ppos: file position
2652 *
2653 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
2654 * values from/to the user buffer, treated as an ASCII string.
2655 *
2656 * This routine will ensure the values are within the range specified by
2657 * table->extra1 (min) and table->extra2 (max).
2658 *
2659 * Returns 0 on success.
2660 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002661int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 void __user *buffer, size_t *lenp, loff_t *ppos)
2663{
2664 return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l);
2665}
2666
2667/**
2668 * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
2669 * @table: the sysctl table
2670 * @write: %TRUE if this is a write to the sysctl file
2671 * @filp: the file structure
2672 * @buffer: the user buffer
2673 * @lenp: the size of the user buffer
2674 * @ppos: file position
2675 *
2676 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
2677 * values from/to the user buffer, treated as an ASCII string. The values
2678 * are treated as milliseconds, and converted to jiffies when they are stored.
2679 *
2680 * This routine will ensure the values are within the range specified by
2681 * table->extra1 (min) and table->extra2 (max).
2682 *
2683 * Returns 0 on success.
2684 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002685int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686 struct file *filp,
2687 void __user *buffer,
2688 size_t *lenp, loff_t *ppos)
2689{
2690 return do_proc_doulongvec_minmax(table, write, filp, buffer,
2691 lenp, ppos, HZ, 1000l);
2692}
2693
2694
2695static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp,
2696 int *valp,
2697 int write, void *data)
2698{
2699 if (write) {
Bart Samwelcba9f332006-03-24 03:15:50 -08002700 if (*lvalp > LONG_MAX / HZ)
2701 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702 *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ);
2703 } else {
2704 int val = *valp;
2705 unsigned long lval;
2706 if (val < 0) {
2707 *negp = -1;
2708 lval = (unsigned long)-val;
2709 } else {
2710 *negp = 0;
2711 lval = (unsigned long)val;
2712 }
2713 *lvalp = lval / HZ;
2714 }
2715 return 0;
2716}
2717
2718static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp,
2719 int *valp,
2720 int write, void *data)
2721{
2722 if (write) {
Bart Samwelcba9f332006-03-24 03:15:50 -08002723 if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ)
2724 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725 *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp);
2726 } else {
2727 int val = *valp;
2728 unsigned long lval;
2729 if (val < 0) {
2730 *negp = -1;
2731 lval = (unsigned long)-val;
2732 } else {
2733 *negp = 0;
2734 lval = (unsigned long)val;
2735 }
2736 *lvalp = jiffies_to_clock_t(lval);
2737 }
2738 return 0;
2739}
2740
2741static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp,
2742 int *valp,
2743 int write, void *data)
2744{
2745 if (write) {
2746 *valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp);
2747 } else {
2748 int val = *valp;
2749 unsigned long lval;
2750 if (val < 0) {
2751 *negp = -1;
2752 lval = (unsigned long)-val;
2753 } else {
2754 *negp = 0;
2755 lval = (unsigned long)val;
2756 }
2757 *lvalp = jiffies_to_msecs(lval);
2758 }
2759 return 0;
2760}
2761
2762/**
2763 * proc_dointvec_jiffies - read a vector of integers as seconds
2764 * @table: the sysctl table
2765 * @write: %TRUE if this is a write to the sysctl file
2766 * @filp: the file structure
2767 * @buffer: the user buffer
2768 * @lenp: the size of the user buffer
2769 * @ppos: file position
2770 *
2771 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2772 * values from/to the user buffer, treated as an ASCII string.
2773 * The values read are assumed to be in seconds, and are converted into
2774 * jiffies.
2775 *
2776 * Returns 0 on success.
2777 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002778int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779 void __user *buffer, size_t *lenp, loff_t *ppos)
2780{
2781 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
2782 do_proc_dointvec_jiffies_conv,NULL);
2783}
2784
2785/**
2786 * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
2787 * @table: the sysctl table
2788 * @write: %TRUE if this is a write to the sysctl file
2789 * @filp: the file structure
2790 * @buffer: the user buffer
2791 * @lenp: the size of the user buffer
Randy Dunlap1e5d5332005-11-07 01:01:06 -08002792 * @ppos: pointer to the file position
Linus Torvalds1da177e2005-04-16 15:20:36 -07002793 *
2794 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2795 * values from/to the user buffer, treated as an ASCII string.
2796 * The values read are assumed to be in 1/USER_HZ seconds, and
2797 * are converted into jiffies.
2798 *
2799 * Returns 0 on success.
2800 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002801int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002802 void __user *buffer, size_t *lenp, loff_t *ppos)
2803{
2804 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
2805 do_proc_dointvec_userhz_jiffies_conv,NULL);
2806}
2807
2808/**
2809 * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds
2810 * @table: the sysctl table
2811 * @write: %TRUE if this is a write to the sysctl file
2812 * @filp: the file structure
2813 * @buffer: the user buffer
2814 * @lenp: the size of the user buffer
Martin Waitz67be2dd2005-05-01 08:59:26 -07002815 * @ppos: file position
2816 * @ppos: the current position in the file
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 *
2818 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2819 * values from/to the user buffer, treated as an ASCII string.
2820 * The values read are assumed to be in 1/1000 seconds, and
2821 * are converted into jiffies.
2822 *
2823 * Returns 0 on success.
2824 */
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002825int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 void __user *buffer, size_t *lenp, loff_t *ppos)
2827{
2828 return do_proc_dointvec(table, write, filp, buffer, lenp, ppos,
2829 do_proc_dointvec_ms_jiffies_conv, NULL);
2830}
2831
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002832static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp,
Cedric Le Goater9ec52092006-10-02 02:19:00 -07002833 void __user *buffer, size_t *lenp, loff_t *ppos)
2834{
2835 struct pid *new_pid;
2836 pid_t tmp;
2837 int r;
2838
Pavel Emelyanov6c5f3e72008-02-08 04:19:20 -08002839 tmp = pid_vnr(cad_pid);
Cedric Le Goater9ec52092006-10-02 02:19:00 -07002840
2841 r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
2842 lenp, ppos, NULL, NULL);
2843 if (r || !write)
2844 return r;
2845
2846 new_pid = find_get_pid(tmp);
2847 if (!new_pid)
2848 return -ESRCH;
2849
2850 put_pid(xchg(&cad_pid, new_pid));
2851 return 0;
2852}
2853
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854#else /* CONFIG_PROC_FS */
2855
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002856int proc_dostring(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857 void __user *buffer, size_t *lenp, loff_t *ppos)
2858{
2859 return -ENOSYS;
2860}
2861
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002862int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863 void __user *buffer, size_t *lenp, loff_t *ppos)
2864{
2865 return -ENOSYS;
2866}
2867
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002868int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869 void __user *buffer, size_t *lenp, loff_t *ppos)
2870{
2871 return -ENOSYS;
2872}
2873
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002874int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875 void __user *buffer, size_t *lenp, loff_t *ppos)
2876{
2877 return -ENOSYS;
2878}
2879
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002880int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881 void __user *buffer, size_t *lenp, loff_t *ppos)
2882{
2883 return -ENOSYS;
2884}
2885
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002886int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887 void __user *buffer, size_t *lenp, loff_t *ppos)
2888{
2889 return -ENOSYS;
2890}
2891
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002892int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002893 void __user *buffer, size_t *lenp, loff_t *ppos)
2894{
2895 return -ENOSYS;
2896}
2897
Eric W. Biedermand8217f02007-10-18 03:05:22 -07002898int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002899 struct file *filp,
2900 void __user *buffer,
2901 size_t *lenp, loff_t *ppos)
2902{
2903 return -ENOSYS;
2904}
2905
2906
2907#endif /* CONFIG_PROC_FS */
2908
2909
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07002910#ifdef CONFIG_SYSCTL_SYSCALL
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911/*
2912 * General sysctl support routines
2913 */
2914
Eric W. Biederman49a0c452007-10-18 03:05:23 -07002915/* The generic sysctl data routine (used if no strategy routine supplied) */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07002916int sysctl_data(struct ctl_table *table,
Eric W. Biederman49a0c452007-10-18 03:05:23 -07002917 void __user *oldval, size_t __user *oldlenp,
2918 void __user *newval, size_t newlen)
2919{
2920 size_t len;
2921
2922 /* Get out of I don't have a variable */
2923 if (!table->data || !table->maxlen)
2924 return -ENOTDIR;
2925
2926 if (oldval && oldlenp) {
2927 if (get_user(len, oldlenp))
2928 return -EFAULT;
2929 if (len) {
2930 if (len > table->maxlen)
2931 len = table->maxlen;
2932 if (copy_to_user(oldval, table->data, len))
2933 return -EFAULT;
2934 if (put_user(len, oldlenp))
2935 return -EFAULT;
2936 }
2937 }
2938
2939 if (newval && newlen) {
2940 if (newlen > table->maxlen)
2941 newlen = table->maxlen;
2942
2943 if (copy_from_user(table->data, newval, newlen))
2944 return -EFAULT;
2945 }
2946 return 1;
2947}
2948
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949/* The generic string strategy routine: */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07002950int sysctl_string(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08002952 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954 if (!table->data || !table->maxlen)
2955 return -ENOTDIR;
2956
2957 if (oldval && oldlenp) {
Linus Torvaldsde9e0072005-12-31 17:00:29 -08002958 size_t bufsize;
2959 if (get_user(bufsize, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960 return -EFAULT;
Linus Torvaldsde9e0072005-12-31 17:00:29 -08002961 if (bufsize) {
2962 size_t len = strlen(table->data), copied;
2963
2964 /* This shouldn't trigger for a well-formed sysctl */
2965 if (len > table->maxlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966 len = table->maxlen;
Linus Torvaldsde9e0072005-12-31 17:00:29 -08002967
2968 /* Copy up to a max of bufsize-1 bytes of the string */
2969 copied = (len >= bufsize) ? bufsize - 1 : len;
2970
2971 if (copy_to_user(oldval, table->data, copied) ||
2972 put_user(0, (char __user *)(oldval + copied)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973 return -EFAULT;
Linus Torvaldsde9e0072005-12-31 17:00:29 -08002974 if (put_user(len, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975 return -EFAULT;
2976 }
2977 }
2978 if (newval && newlen) {
Linus Torvaldsde9e0072005-12-31 17:00:29 -08002979 size_t len = newlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002980 if (len > table->maxlen)
2981 len = table->maxlen;
2982 if(copy_from_user(table->data, newval, len))
2983 return -EFAULT;
2984 if (len == table->maxlen)
2985 len--;
2986 ((char *) table->data)[len] = 0;
2987 }
Yi Yang82c9df82005-12-30 16:37:10 +08002988 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002989}
2990
2991/*
2992 * This function makes sure that all of the integers in the vector
2993 * are between the minimum and maximum values given in the arrays
2994 * table->extra1 and table->extra2, respectively.
2995 */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07002996int sysctl_intvec(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08002998 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999{
3000
3001 if (newval && newlen) {
3002 int __user *vec = (int __user *) newval;
3003 int *min = (int *) table->extra1;
3004 int *max = (int *) table->extra2;
3005 size_t length;
3006 int i;
3007
3008 if (newlen % sizeof(int) != 0)
3009 return -EINVAL;
3010
3011 if (!table->extra1 && !table->extra2)
3012 return 0;
3013
3014 if (newlen > table->maxlen)
3015 newlen = table->maxlen;
3016 length = newlen / sizeof(int);
3017
3018 for (i = 0; i < length; i++) {
3019 int value;
3020 if (get_user(value, vec + i))
3021 return -EFAULT;
3022 if (min && value < min[i])
3023 return -EINVAL;
3024 if (max && value > max[i])
3025 return -EINVAL;
3026 }
3027 }
3028 return 0;
3029}
3030
3031/* Strategy function to convert jiffies to seconds */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003032int sysctl_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003034 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003035{
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003036 if (oldval && oldlenp) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037 size_t olen;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003038
3039 if (get_user(olen, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040 return -EFAULT;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003041 if (olen) {
3042 int val;
3043
3044 if (olen < sizeof(int))
3045 return -EINVAL;
3046
3047 val = *(int *)(table->data) / HZ;
3048 if (put_user(val, (int __user *)oldval))
3049 return -EFAULT;
3050 if (put_user(sizeof(int), oldlenp))
3051 return -EFAULT;
3052 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003053 }
3054 if (newval && newlen) {
3055 int new;
3056 if (newlen != sizeof(int))
3057 return -EINVAL;
3058 if (get_user(new, (int __user *)newval))
3059 return -EFAULT;
3060 *(int *)(table->data) = new*HZ;
3061 }
3062 return 1;
3063}
3064
3065/* Strategy function to convert jiffies to seconds */
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003066int sysctl_ms_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003068 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003069{
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003070 if (oldval && oldlenp) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071 size_t olen;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003072
3073 if (get_user(olen, oldlenp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074 return -EFAULT;
Alexey Dobriyan3ee75ac2007-02-10 01:44:39 -08003075 if (olen) {
3076 int val;
3077
3078 if (olen < sizeof(int))
3079 return -EINVAL;
3080
3081 val = jiffies_to_msecs(*(int *)(table->data));
3082 if (put_user(val, (int __user *)oldval))
3083 return -EFAULT;
3084 if (put_user(sizeof(int), oldlenp))
3085 return -EFAULT;
3086 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003087 }
3088 if (newval && newlen) {
3089 int new;
3090 if (newlen != sizeof(int))
3091 return -EINVAL;
3092 if (get_user(new, (int __user *)newval))
3093 return -EFAULT;
3094 *(int *)(table->data) = msecs_to_jiffies(new);
3095 }
3096 return 1;
3097}
3098
Eric W. Biedermanc4b8b762006-12-08 02:39:55 -08003099
Eric W. Biedermanc4b8b762006-12-08 02:39:55 -08003100
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07003101#else /* CONFIG_SYSCTL_SYSCALL */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003102
3103
Heiko Carstens1e7bfb22009-01-14 14:14:29 +01003104SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105{
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003106 struct __sysctl_args tmp;
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003107 int error;
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003108
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003109 if (copy_from_user(&tmp, args, sizeof(tmp)))
3110 return -EFAULT;
Eric W. Biederman0e009be2006-11-05 23:52:11 -08003111
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003112 error = deprecated_sysctl_warning(&tmp);
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07003113
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003114 /* If no error reading the parameters then just -ENOSYS ... */
3115 if (!error)
3116 error = -ENOSYS;
3117
3118 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119}
3120
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003121int sysctl_data(struct ctl_table *table,
Eric W. Biederman49a0c452007-10-18 03:05:23 -07003122 void __user *oldval, size_t __user *oldlenp,
3123 void __user *newval, size_t newlen)
3124{
3125 return -ENOSYS;
3126}
3127
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003128int sysctl_string(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003129 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003130 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131{
3132 return -ENOSYS;
3133}
3134
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003135int sysctl_intvec(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003137 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138{
3139 return -ENOSYS;
3140}
3141
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003142int sysctl_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003143 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003144 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145{
3146 return -ENOSYS;
3147}
3148
Alexey Dobriyanf221e722008-10-15 22:04:23 -07003149int sysctl_ms_jiffies(struct ctl_table *table,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150 void __user *oldval, size_t __user *oldlenp,
Alexey Dobriyan1f29bcd2006-12-10 02:19:10 -08003151 void __user *newval, size_t newlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003152{
3153 return -ENOSYS;
3154}
3155
Eric W. Biedermanb89a8172006-09-27 01:51:04 -07003156#endif /* CONFIG_SYSCTL_SYSCALL */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003158static int deprecated_sysctl_warning(struct __sysctl_args *args)
3159{
3160 static int msg_count;
3161 int name[CTL_MAXNAME];
3162 int i;
3163
Tetsuo Handa6fc48af2007-11-14 16:58:38 -08003164 /* Check args->nlen. */
3165 if (args->nlen < 0 || args->nlen > CTL_MAXNAME)
3166 return -ENOTDIR;
3167
Eric W. Biederman7058cb02007-10-18 03:05:58 -07003168 /* Read in the sysctl name for better debug message logging */
3169 for (i = 0; i < args->nlen; i++)
3170 if (get_user(name[i], args->name + i))
3171 return -EFAULT;
3172
3173 /* Ignore accesses to kernel.version */
3174 if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION))
3175 return 0;
3176
3177 if (msg_count < 5) {
3178 msg_count++;
3179 printk(KERN_INFO
3180 "warning: process `%s' used the deprecated sysctl "
3181 "system call with ", current->comm);
3182 for (i = 0; i < args->nlen; i++)
3183 printk("%d.", name[i]);
3184 printk("\n");
3185 }
3186 return 0;
3187}
3188
Linus Torvalds1da177e2005-04-16 15:20:36 -07003189/*
3190 * No sense putting this after each symbol definition, twice,
3191 * exception granted :-)
3192 */
3193EXPORT_SYMBOL(proc_dointvec);
3194EXPORT_SYMBOL(proc_dointvec_jiffies);
3195EXPORT_SYMBOL(proc_dointvec_minmax);
3196EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
3197EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
3198EXPORT_SYMBOL(proc_dostring);
3199EXPORT_SYMBOL(proc_doulongvec_minmax);
3200EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
3201EXPORT_SYMBOL(register_sysctl_table);
Eric W. Biederman29e796f2007-11-30 23:50:18 +11003202EXPORT_SYMBOL(register_sysctl_paths);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203EXPORT_SYMBOL(sysctl_intvec);
3204EXPORT_SYMBOL(sysctl_jiffies);
3205EXPORT_SYMBOL(sysctl_ms_jiffies);
3206EXPORT_SYMBOL(sysctl_string);
Eric W. Biederman49a0c452007-10-18 03:05:23 -07003207EXPORT_SYMBOL(sysctl_data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003208EXPORT_SYMBOL(unregister_sysctl_table);