Branch data Line data Source code
1 : : /*
2 : : * sysctl.c: General linux system control interface
3 : : *
4 : : * Begun 24 March 1995, Stephen Tweedie
5 : : * Added /proc support, Dec 1995
6 : : * Added bdflush entry and intvec min/max checking, 2/23/96, Tom Dyas.
7 : : * Added hooks for /proc/sys/net (minor, minor patch), 96/4/1, Mike Shaver.
8 : : * Added kernel/java-{interpreter,appletviewer}, 96/5/10, Mike Shaver.
9 : : * Dynamic registration fixes, Stephen Tweedie.
10 : : * Added kswapd-interval, ctrl-alt-del, printk stuff, 1/8/97, Chris Horn.
11 : : * Made sysctl support optional via CONFIG_SYSCTL, 1/10/97, Chris
12 : : * Horn.
13 : : * Added proc_doulongvec_ms_jiffies_minmax, 09/08/99, Carlos H. Bauer.
14 : : * Added proc_doulongvec_minmax, 09/08/99, Carlos H. Bauer.
15 : : * Changed linked lists to use list.h instead of lists.h, 02/24/00, Bill
16 : : * Wendling.
17 : : * The list_for_each() macro wasn't appropriate for the sysctl loop.
18 : : * Removed it and replaced it with older style, 03/23/00, Bill Wendling
19 : : */
20 : :
21 : : #include <linux/module.h>
22 : : #include <linux/mm.h>
23 : : #include <linux/swap.h>
24 : : #include <linux/slab.h>
25 : : #include <linux/sysctl.h>
26 : : #include <linux/bitmap.h>
27 : : #include <linux/signal.h>
28 : : #include <linux/printk.h>
29 : : #include <linux/proc_fs.h>
30 : : #include <linux/security.h>
31 : : #include <linux/ctype.h>
32 : : #include <linux/kmemcheck.h>
33 : : #include <linux/kmemleak.h>
34 : : #include <linux/fs.h>
35 : : #include <linux/init.h>
36 : : #include <linux/kernel.h>
37 : : #include <linux/kobject.h>
38 : : #include <linux/net.h>
39 : : #include <linux/sysrq.h>
40 : : #include <linux/highuid.h>
41 : : #include <linux/writeback.h>
42 : : #include <linux/ratelimit.h>
43 : : #include <linux/compaction.h>
44 : : #include <linux/hugetlb.h>
45 : : #include <linux/initrd.h>
46 : : #include <linux/key.h>
47 : : #include <linux/times.h>
48 : : #include <linux/limits.h>
49 : : #include <linux/dcache.h>
50 : : #include <linux/dnotify.h>
51 : : #include <linux/syscalls.h>
52 : : #include <linux/vmstat.h>
53 : : #include <linux/nfs_fs.h>
54 : : #include <linux/acpi.h>
55 : : #include <linux/reboot.h>
56 : : #include <linux/ftrace.h>
57 : : #include <linux/perf_event.h>
58 : : #include <linux/kprobes.h>
59 : : #include <linux/pipe_fs_i.h>
60 : : #include <linux/oom.h>
61 : : #include <linux/kmod.h>
62 : : #include <linux/capability.h>
63 : : #include <linux/binfmts.h>
64 : : #include <linux/sched/sysctl.h>
65 : : #include <linux/kexec.h>
66 : :
67 : : #include <asm/uaccess.h>
68 : : #include <asm/processor.h>
69 : :
70 : : #ifdef CONFIG_X86
71 : : #include <asm/nmi.h>
72 : : #include <asm/stacktrace.h>
73 : : #include <asm/io.h>
74 : : #endif
75 : : #ifdef CONFIG_SPARC
76 : : #include <asm/setup.h>
77 : : #endif
78 : : #ifdef CONFIG_BSD_PROCESS_ACCT
79 : : #include <linux/acct.h>
80 : : #endif
81 : : #ifdef CONFIG_RT_MUTEXES
82 : : #include <linux/rtmutex.h>
83 : : #endif
84 : : #if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_LOCK_STAT)
85 : : #include <linux/lockdep.h>
86 : : #endif
87 : : #ifdef CONFIG_CHR_DEV_SG
88 : : #include <scsi/sg.h>
89 : : #endif
90 : :
91 : : #ifdef CONFIG_LOCKUP_DETECTOR
92 : : #include <linux/nmi.h>
93 : : #endif
94 : :
95 : :
96 : : #if defined(CONFIG_SYSCTL)
97 : :
98 : : /* External variables not in a header file. */
99 : : extern int max_threads;
100 : : extern int suid_dumpable;
101 : : #ifdef CONFIG_COREDUMP
102 : : extern int core_uses_pid;
103 : : extern char core_pattern[];
104 : : extern unsigned int core_pipe_limit;
105 : : #endif
106 : : extern int pid_max;
107 : : extern int extra_free_kbytes;
108 : : extern int min_free_order_shift;
109 : : extern int pid_max_min, pid_max_max;
110 : : extern int percpu_pagelist_fraction;
111 : : extern int compat_log;
112 : : extern int latencytop_enabled;
113 : : extern int sysctl_nr_open_min, sysctl_nr_open_max;
114 : : #ifndef CONFIG_MMU
115 : : extern int sysctl_nr_trim_pages;
116 : : #endif
117 : : #ifdef CONFIG_BLOCK
118 : : extern int blk_iopoll_enabled;
119 : : #endif
120 : :
121 : : /* Constants used for minimum and maximum */
122 : : #ifdef CONFIG_LOCKUP_DETECTOR
123 : : static int sixty = 60;
124 : : #endif
125 : :
126 : : static int __maybe_unused neg_one = -1;
127 : :
128 : : static int zero;
129 : : static int __maybe_unused one = 1;
130 : : static int __maybe_unused two = 2;
131 : : static int __maybe_unused three = 3;
132 : : static unsigned long one_ul = 1;
133 : : static int one_hundred = 100;
134 : : #ifdef CONFIG_PRINTK
135 : : static int ten_thousand = 10000;
136 : : #endif
137 : :
138 : : /* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
139 : : static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
140 : :
141 : : /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
142 : : static int maxolduid = 65535;
143 : : static int minolduid;
144 : : static int min_percpu_pagelist_fract = 8;
145 : :
146 : : static int ngroups_max = NGROUPS_MAX;
147 : : static const int cap_last_cap = CAP_LAST_CAP;
148 : :
149 : : #ifdef CONFIG_INOTIFY_USER
150 : : #include <linux/inotify.h>
151 : : #endif
152 : : #ifdef CONFIG_SPARC
153 : : #endif
154 : :
155 : : #ifdef CONFIG_SPARC64
156 : : extern int sysctl_tsb_ratio;
157 : : #endif
158 : :
159 : : #ifdef __hppa__
160 : : extern int pwrsw_enabled;
161 : : #endif
162 : :
163 : : #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW
164 : : extern int unaligned_enabled;
165 : : #endif
166 : :
167 : : #ifdef CONFIG_IA64
168 : : extern int unaligned_dump_stack;
169 : : #endif
170 : :
171 : : #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN
172 : : extern int no_unaligned_warning;
173 : : #endif
174 : :
175 : : #ifdef CONFIG_PROC_SYSCTL
176 : : static int proc_do_cad_pid(struct ctl_table *table, int write,
177 : : void __user *buffer, size_t *lenp, loff_t *ppos);
178 : : static int proc_taint(struct ctl_table *table, int write,
179 : : void __user *buffer, size_t *lenp, loff_t *ppos);
180 : : #endif
181 : :
182 : : #ifdef CONFIG_PRINTK
183 : : static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
184 : : void __user *buffer, size_t *lenp, loff_t *ppos);
185 : : #endif
186 : :
187 : : static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
188 : : void __user *buffer, size_t *lenp, loff_t *ppos);
189 : : #ifdef CONFIG_COREDUMP
190 : : static int proc_dostring_coredump(struct ctl_table *table, int write,
191 : : void __user *buffer, size_t *lenp, loff_t *ppos);
192 : : #endif
193 : :
194 : : #ifdef CONFIG_MAGIC_SYSRQ
195 : : /* Note: sysrq code uses it's own private copy */
196 : : static int __sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;
197 : :
198 : 0 : static int sysrq_sysctl_handler(ctl_table *table, int write,
199 : : void __user *buffer, size_t *lenp,
200 : : loff_t *ppos)
201 : : {
202 : : int error;
203 : :
204 : : error = proc_dointvec(table, write, buffer, lenp, ppos);
205 [ + - ]: 2 : if (error)
206 : : return error;
207 : :
208 [ - + ]: 2 : if (write)
209 : 0 : sysrq_toggle_support(__sysrq_enabled);
210 : :
211 : : return 0;
212 : : }
213 : :
214 : : #endif
215 : :
216 : : static struct ctl_table kern_table[];
217 : : static struct ctl_table vm_table[];
218 : : static struct ctl_table fs_table[];
219 : : static struct ctl_table debug_table[];
220 : : static struct ctl_table dev_table[];
221 : : extern struct ctl_table random_table[];
222 : : #ifdef CONFIG_EPOLL
223 : : extern struct ctl_table epoll_table[];
224 : : #endif
225 : :
226 : : #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
227 : : int sysctl_legacy_va_layout;
228 : : #endif
229 : :
230 : : /* The default sysctl tables: */
231 : :
232 : : static struct ctl_table sysctl_base_table[] = {
233 : : {
234 : : .procname = "kernel",
235 : : .mode = 0555,
236 : : .child = kern_table,
237 : : },
238 : : {
239 : : .procname = "vm",
240 : : .mode = 0555,
241 : : .child = vm_table,
242 : : },
243 : : {
244 : : .procname = "fs",
245 : : .mode = 0555,
246 : : .child = fs_table,
247 : : },
248 : : {
249 : : .procname = "debug",
250 : : .mode = 0555,
251 : : .child = debug_table,
252 : : },
253 : : {
254 : : .procname = "dev",
255 : : .mode = 0555,
256 : : .child = dev_table,
257 : : },
258 : : { }
259 : : };
260 : :
261 : : #ifdef CONFIG_SCHED_DEBUG
262 : : static int min_sched_granularity_ns = 100000; /* 100 usecs */
263 : : static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */
264 : : static int min_wakeup_granularity_ns; /* 0 usecs */
265 : : static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */
266 : : #ifdef CONFIG_SMP
267 : : static int min_sched_tunable_scaling = SCHED_TUNABLESCALING_NONE;
268 : : static int max_sched_tunable_scaling = SCHED_TUNABLESCALING_END-1;
269 : : #endif /* CONFIG_SMP */
270 : : #endif /* CONFIG_SCHED_DEBUG */
271 : :
272 : : #ifdef CONFIG_COMPACTION
273 : : static int min_extfrag_threshold;
274 : : static int max_extfrag_threshold = 1000;
275 : : #endif
276 : :
277 : : static struct ctl_table kern_table[] = {
278 : : {
279 : : .procname = "sched_child_runs_first",
280 : : .data = &sysctl_sched_child_runs_first,
281 : : .maxlen = sizeof(unsigned int),
282 : : .mode = 0644,
283 : : .proc_handler = proc_dointvec,
284 : : },
285 : : #ifdef CONFIG_SCHED_DEBUG
286 : : {
287 : : .procname = "sched_min_granularity_ns",
288 : : .data = &sysctl_sched_min_granularity,
289 : : .maxlen = sizeof(unsigned int),
290 : : .mode = 0644,
291 : : .proc_handler = sched_proc_update_handler,
292 : : .extra1 = &min_sched_granularity_ns,
293 : : .extra2 = &max_sched_granularity_ns,
294 : : },
295 : : {
296 : : .procname = "sched_latency_ns",
297 : : .data = &sysctl_sched_latency,
298 : : .maxlen = sizeof(unsigned int),
299 : : .mode = 0644,
300 : : .proc_handler = sched_proc_update_handler,
301 : : .extra1 = &min_sched_granularity_ns,
302 : : .extra2 = &max_sched_granularity_ns,
303 : : },
304 : : {
305 : : .procname = "sched_wakeup_granularity_ns",
306 : : .data = &sysctl_sched_wakeup_granularity,
307 : : .maxlen = sizeof(unsigned int),
308 : : .mode = 0644,
309 : : .proc_handler = sched_proc_update_handler,
310 : : .extra1 = &min_wakeup_granularity_ns,
311 : : .extra2 = &max_wakeup_granularity_ns,
312 : : },
313 : : #ifdef CONFIG_SMP
314 : : {
315 : : .procname = "sched_tunable_scaling",
316 : : .data = &sysctl_sched_tunable_scaling,
317 : : .maxlen = sizeof(enum sched_tunable_scaling),
318 : : .mode = 0644,
319 : : .proc_handler = sched_proc_update_handler,
320 : : .extra1 = &min_sched_tunable_scaling,
321 : : .extra2 = &max_sched_tunable_scaling,
322 : : },
323 : : {
324 : : .procname = "sched_migration_cost_ns",
325 : : .data = &sysctl_sched_migration_cost,
326 : : .maxlen = sizeof(unsigned int),
327 : : .mode = 0644,
328 : : .proc_handler = proc_dointvec,
329 : : },
330 : : {
331 : : .procname = "sched_nr_migrate",
332 : : .data = &sysctl_sched_nr_migrate,
333 : : .maxlen = sizeof(unsigned int),
334 : : .mode = 0644,
335 : : .proc_handler = proc_dointvec,
336 : : },
337 : : {
338 : : .procname = "sched_time_avg_ms",
339 : : .data = &sysctl_sched_time_avg,
340 : : .maxlen = sizeof(unsigned int),
341 : : .mode = 0644,
342 : : .proc_handler = proc_dointvec,
343 : : },
344 : : {
345 : : .procname = "sched_shares_window_ns",
346 : : .data = &sysctl_sched_shares_window,
347 : : .maxlen = sizeof(unsigned int),
348 : : .mode = 0644,
349 : : .proc_handler = proc_dointvec,
350 : : },
351 : : {
352 : : .procname = "timer_migration",
353 : : .data = &sysctl_timer_migration,
354 : : .maxlen = sizeof(unsigned int),
355 : : .mode = 0644,
356 : : .proc_handler = proc_dointvec_minmax,
357 : : .extra1 = &zero,
358 : : .extra2 = &one,
359 : : },
360 : : #endif /* CONFIG_SMP */
361 : : #ifdef CONFIG_NUMA_BALANCING
362 : : {
363 : : .procname = "numa_balancing_scan_delay_ms",
364 : : .data = &sysctl_numa_balancing_scan_delay,
365 : : .maxlen = sizeof(unsigned int),
366 : : .mode = 0644,
367 : : .proc_handler = proc_dointvec,
368 : : },
369 : : {
370 : : .procname = "numa_balancing_scan_period_min_ms",
371 : : .data = &sysctl_numa_balancing_scan_period_min,
372 : : .maxlen = sizeof(unsigned int),
373 : : .mode = 0644,
374 : : .proc_handler = proc_dointvec,
375 : : },
376 : : {
377 : : .procname = "numa_balancing_scan_period_max_ms",
378 : : .data = &sysctl_numa_balancing_scan_period_max,
379 : : .maxlen = sizeof(unsigned int),
380 : : .mode = 0644,
381 : : .proc_handler = proc_dointvec,
382 : : },
383 : : {
384 : : .procname = "numa_balancing_scan_size_mb",
385 : : .data = &sysctl_numa_balancing_scan_size,
386 : : .maxlen = sizeof(unsigned int),
387 : : .mode = 0644,
388 : : .proc_handler = proc_dointvec,
389 : : },
390 : : {
391 : : .procname = "numa_balancing_migrate_deferred",
392 : : .data = &sysctl_numa_balancing_migrate_deferred,
393 : : .maxlen = sizeof(unsigned int),
394 : : .mode = 0644,
395 : : .proc_handler = proc_dointvec,
396 : : },
397 : : {
398 : : .procname = "numa_balancing",
399 : : .data = NULL, /* filled in by handler */
400 : : .maxlen = sizeof(unsigned int),
401 : : .mode = 0644,
402 : : .proc_handler = sysctl_numa_balancing,
403 : : .extra1 = &zero,
404 : : .extra2 = &one,
405 : : },
406 : : #endif /* CONFIG_NUMA_BALANCING */
407 : : #endif /* CONFIG_SCHED_DEBUG */
408 : : {
409 : : .procname = "sched_rt_period_us",
410 : : .data = &sysctl_sched_rt_period,
411 : : .maxlen = sizeof(unsigned int),
412 : : .mode = 0644,
413 : : .proc_handler = sched_rt_handler,
414 : : },
415 : : {
416 : : .procname = "sched_rt_runtime_us",
417 : : .data = &sysctl_sched_rt_runtime,
418 : : .maxlen = sizeof(int),
419 : : .mode = 0644,
420 : : .proc_handler = sched_rt_handler,
421 : : },
422 : : {
423 : : .procname = "sched_rr_timeslice_ms",
424 : : .data = &sched_rr_timeslice,
425 : : .maxlen = sizeof(int),
426 : : .mode = 0644,
427 : : .proc_handler = sched_rr_handler,
428 : : },
429 : : #ifdef CONFIG_SCHED_AUTOGROUP
430 : : {
431 : : .procname = "sched_autogroup_enabled",
432 : : .data = &sysctl_sched_autogroup_enabled,
433 : : .maxlen = sizeof(unsigned int),
434 : : .mode = 0644,
435 : : .proc_handler = proc_dointvec_minmax,
436 : : .extra1 = &zero,
437 : : .extra2 = &one,
438 : : },
439 : : #endif
440 : : #ifdef CONFIG_CFS_BANDWIDTH
441 : : {
442 : : .procname = "sched_cfs_bandwidth_slice_us",
443 : : .data = &sysctl_sched_cfs_bandwidth_slice,
444 : : .maxlen = sizeof(unsigned int),
445 : : .mode = 0644,
446 : : .proc_handler = proc_dointvec_minmax,
447 : : .extra1 = &one,
448 : : },
449 : : #endif
450 : : #ifdef CONFIG_PROVE_LOCKING
451 : : {
452 : : .procname = "prove_locking",
453 : : .data = &prove_locking,
454 : : .maxlen = sizeof(int),
455 : : .mode = 0644,
456 : : .proc_handler = proc_dointvec,
457 : : },
458 : : #endif
459 : : #ifdef CONFIG_LOCK_STAT
460 : : {
461 : : .procname = "lock_stat",
462 : : .data = &lock_stat,
463 : : .maxlen = sizeof(int),
464 : : .mode = 0644,
465 : : .proc_handler = proc_dointvec,
466 : : },
467 : : #endif
468 : : {
469 : : .procname = "panic",
470 : : .data = &panic_timeout,
471 : : .maxlen = sizeof(int),
472 : : .mode = 0644,
473 : : .proc_handler = proc_dointvec,
474 : : },
475 : : #ifdef CONFIG_COREDUMP
476 : : {
477 : : .procname = "core_uses_pid",
478 : : .data = &core_uses_pid,
479 : : .maxlen = sizeof(int),
480 : : .mode = 0644,
481 : : .proc_handler = proc_dointvec,
482 : : },
483 : : {
484 : : .procname = "core_pattern",
485 : : .data = core_pattern,
486 : : .maxlen = CORENAME_MAX_SIZE,
487 : : .mode = 0644,
488 : : .proc_handler = proc_dostring_coredump,
489 : : },
490 : : {
491 : : .procname = "core_pipe_limit",
492 : : .data = &core_pipe_limit,
493 : : .maxlen = sizeof(unsigned int),
494 : : .mode = 0644,
495 : : .proc_handler = proc_dointvec,
496 : : },
497 : : #endif
498 : : #ifdef CONFIG_PROC_SYSCTL
499 : : {
500 : : .procname = "tainted",
501 : : .maxlen = sizeof(long),
502 : : .mode = 0644,
503 : : .proc_handler = proc_taint,
504 : : },
505 : : #endif
506 : : #ifdef CONFIG_LATENCYTOP
507 : : {
508 : : .procname = "latencytop",
509 : : .data = &latencytop_enabled,
510 : : .maxlen = sizeof(int),
511 : : .mode = 0644,
512 : : .proc_handler = proc_dointvec,
513 : : },
514 : : #endif
515 : : #ifdef CONFIG_BLK_DEV_INITRD
516 : : {
517 : : .procname = "real-root-dev",
518 : : .data = &real_root_dev,
519 : : .maxlen = sizeof(int),
520 : : .mode = 0644,
521 : : .proc_handler = proc_dointvec,
522 : : },
523 : : #endif
524 : : {
525 : : .procname = "print-fatal-signals",
526 : : .data = &print_fatal_signals,
527 : : .maxlen = sizeof(int),
528 : : .mode = 0644,
529 : : .proc_handler = proc_dointvec,
530 : : },
531 : : #ifdef CONFIG_SPARC
532 : : {
533 : : .procname = "reboot-cmd",
534 : : .data = reboot_command,
535 : : .maxlen = 256,
536 : : .mode = 0644,
537 : : .proc_handler = proc_dostring,
538 : : },
539 : : {
540 : : .procname = "stop-a",
541 : : .data = &stop_a_enabled,
542 : : .maxlen = sizeof (int),
543 : : .mode = 0644,
544 : : .proc_handler = proc_dointvec,
545 : : },
546 : : {
547 : : .procname = "scons-poweroff",
548 : : .data = &scons_pwroff,
549 : : .maxlen = sizeof (int),
550 : : .mode = 0644,
551 : : .proc_handler = proc_dointvec,
552 : : },
553 : : #endif
554 : : #ifdef CONFIG_SPARC64
555 : : {
556 : : .procname = "tsb-ratio",
557 : : .data = &sysctl_tsb_ratio,
558 : : .maxlen = sizeof (int),
559 : : .mode = 0644,
560 : : .proc_handler = proc_dointvec,
561 : : },
562 : : #endif
563 : : #ifdef __hppa__
564 : : {
565 : : .procname = "soft-power",
566 : : .data = &pwrsw_enabled,
567 : : .maxlen = sizeof (int),
568 : : .mode = 0644,
569 : : .proc_handler = proc_dointvec,
570 : : },
571 : : #endif
572 : : #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW
573 : : {
574 : : .procname = "unaligned-trap",
575 : : .data = &unaligned_enabled,
576 : : .maxlen = sizeof (int),
577 : : .mode = 0644,
578 : : .proc_handler = proc_dointvec,
579 : : },
580 : : #endif
581 : : {
582 : : .procname = "ctrl-alt-del",
583 : : .data = &C_A_D,
584 : : .maxlen = sizeof(int),
585 : : .mode = 0644,
586 : : .proc_handler = proc_dointvec,
587 : : },
588 : : #ifdef CONFIG_FUNCTION_TRACER
589 : : {
590 : : .procname = "ftrace_enabled",
591 : : .data = &ftrace_enabled,
592 : : .maxlen = sizeof(int),
593 : : .mode = 0644,
594 : : .proc_handler = ftrace_enable_sysctl,
595 : : },
596 : : #endif
597 : : #ifdef CONFIG_STACK_TRACER
598 : : {
599 : : .procname = "stack_tracer_enabled",
600 : : .data = &stack_tracer_enabled,
601 : : .maxlen = sizeof(int),
602 : : .mode = 0644,
603 : : .proc_handler = stack_trace_sysctl,
604 : : },
605 : : #endif
606 : : #ifdef CONFIG_TRACING
607 : : {
608 : : .procname = "ftrace_dump_on_oops",
609 : : .data = &ftrace_dump_on_oops,
610 : : .maxlen = sizeof(int),
611 : : .mode = 0644,
612 : : .proc_handler = proc_dointvec,
613 : : },
614 : : {
615 : : .procname = "traceoff_on_warning",
616 : : .data = &__disable_trace_on_warning,
617 : : .maxlen = sizeof(__disable_trace_on_warning),
618 : : .mode = 0644,
619 : : .proc_handler = proc_dointvec,
620 : : },
621 : : #endif
622 : : #ifdef CONFIG_KEXEC
623 : : {
624 : : .procname = "kexec_load_disabled",
625 : : .data = &kexec_load_disabled,
626 : : .maxlen = sizeof(int),
627 : : .mode = 0644,
628 : : /* only handle a transition from default "0" to "1" */
629 : : .proc_handler = proc_dointvec_minmax,
630 : : .extra1 = &one,
631 : : .extra2 = &one,
632 : : },
633 : : #endif
634 : : #ifdef CONFIG_MODULES
635 : : {
636 : : .procname = "modprobe",
637 : : .data = &modprobe_path,
638 : : .maxlen = KMOD_PATH_LEN,
639 : : .mode = 0644,
640 : : .proc_handler = proc_dostring,
641 : : },
642 : : {
643 : : .procname = "modules_disabled",
644 : : .data = &modules_disabled,
645 : : .maxlen = sizeof(int),
646 : : .mode = 0644,
647 : : /* only handle a transition from default "0" to "1" */
648 : : .proc_handler = proc_dointvec_minmax,
649 : : .extra1 = &one,
650 : : .extra2 = &one,
651 : : },
652 : : #endif
653 : :
654 : : {
655 : : .procname = "hotplug",
656 : : .data = &uevent_helper,
657 : : .maxlen = UEVENT_HELPER_PATH_LEN,
658 : : .mode = 0644,
659 : : .proc_handler = proc_dostring,
660 : : },
661 : :
662 : : #ifdef CONFIG_CHR_DEV_SG
663 : : {
664 : : .procname = "sg-big-buff",
665 : : .data = &sg_big_buff,
666 : : .maxlen = sizeof (int),
667 : : .mode = 0444,
668 : : .proc_handler = proc_dointvec,
669 : : },
670 : : #endif
671 : : #ifdef CONFIG_BSD_PROCESS_ACCT
672 : : {
673 : : .procname = "acct",
674 : : .data = &acct_parm,
675 : : .maxlen = 3*sizeof(int),
676 : : .mode = 0644,
677 : : .proc_handler = proc_dointvec,
678 : : },
679 : : #endif
680 : : #ifdef CONFIG_MAGIC_SYSRQ
681 : : {
682 : : .procname = "sysrq",
683 : : .data = &__sysrq_enabled,
684 : : .maxlen = sizeof (int),
685 : : .mode = 0644,
686 : : .proc_handler = sysrq_sysctl_handler,
687 : : },
688 : : #endif
689 : : #ifdef CONFIG_PROC_SYSCTL
690 : : {
691 : : .procname = "cad_pid",
692 : : .data = NULL,
693 : : .maxlen = sizeof (int),
694 : : .mode = 0600,
695 : : .proc_handler = proc_do_cad_pid,
696 : : },
697 : : #endif
698 : : {
699 : : .procname = "threads-max",
700 : : .data = &max_threads,
701 : : .maxlen = sizeof(int),
702 : : .mode = 0644,
703 : : .proc_handler = proc_dointvec,
704 : : },
705 : : {
706 : : .procname = "random",
707 : : .mode = 0555,
708 : : .child = random_table,
709 : : },
710 : : {
711 : : .procname = "usermodehelper",
712 : : .mode = 0555,
713 : : .child = usermodehelper_table,
714 : : },
715 : : {
716 : : .procname = "overflowuid",
717 : : .data = &overflowuid,
718 : : .maxlen = sizeof(int),
719 : : .mode = 0644,
720 : : .proc_handler = proc_dointvec_minmax,
721 : : .extra1 = &minolduid,
722 : : .extra2 = &maxolduid,
723 : : },
724 : : {
725 : : .procname = "overflowgid",
726 : : .data = &overflowgid,
727 : : .maxlen = sizeof(int),
728 : : .mode = 0644,
729 : : .proc_handler = proc_dointvec_minmax,
730 : : .extra1 = &minolduid,
731 : : .extra2 = &maxolduid,
732 : : },
733 : : #ifdef CONFIG_S390
734 : : #ifdef CONFIG_MATHEMU
735 : : {
736 : : .procname = "ieee_emulation_warnings",
737 : : .data = &sysctl_ieee_emulation_warnings,
738 : : .maxlen = sizeof(int),
739 : : .mode = 0644,
740 : : .proc_handler = proc_dointvec,
741 : : },
742 : : #endif
743 : : {
744 : : .procname = "userprocess_debug",
745 : : .data = &show_unhandled_signals,
746 : : .maxlen = sizeof(int),
747 : : .mode = 0644,
748 : : .proc_handler = proc_dointvec,
749 : : },
750 : : #endif
751 : : {
752 : : .procname = "pid_max",
753 : : .data = &pid_max,
754 : : .maxlen = sizeof (int),
755 : : .mode = 0644,
756 : : .proc_handler = proc_dointvec_minmax,
757 : : .extra1 = &pid_max_min,
758 : : .extra2 = &pid_max_max,
759 : : },
760 : : {
761 : : .procname = "panic_on_oops",
762 : : .data = &panic_on_oops,
763 : : .maxlen = sizeof(int),
764 : : .mode = 0644,
765 : : .proc_handler = proc_dointvec,
766 : : },
767 : : #if defined CONFIG_PRINTK
768 : : {
769 : : .procname = "printk",
770 : : .data = &console_loglevel,
771 : : .maxlen = 4*sizeof(int),
772 : : .mode = 0644,
773 : : .proc_handler = proc_dointvec,
774 : : },
775 : : {
776 : : .procname = "printk_ratelimit",
777 : : .data = &printk_ratelimit_state.interval,
778 : : .maxlen = sizeof(int),
779 : : .mode = 0644,
780 : : .proc_handler = proc_dointvec_jiffies,
781 : : },
782 : : {
783 : : .procname = "printk_ratelimit_burst",
784 : : .data = &printk_ratelimit_state.burst,
785 : : .maxlen = sizeof(int),
786 : : .mode = 0644,
787 : : .proc_handler = proc_dointvec,
788 : : },
789 : : {
790 : : .procname = "printk_delay",
791 : : .data = &printk_delay_msec,
792 : : .maxlen = sizeof(int),
793 : : .mode = 0644,
794 : : .proc_handler = proc_dointvec_minmax,
795 : : .extra1 = &zero,
796 : : .extra2 = &ten_thousand,
797 : : },
798 : : {
799 : : .procname = "dmesg_restrict",
800 : : .data = &dmesg_restrict,
801 : : .maxlen = sizeof(int),
802 : : .mode = 0644,
803 : : .proc_handler = proc_dointvec_minmax_sysadmin,
804 : : .extra1 = &zero,
805 : : .extra2 = &one,
806 : : },
807 : : {
808 : : .procname = "kptr_restrict",
809 : : .data = &kptr_restrict,
810 : : .maxlen = sizeof(int),
811 : : .mode = 0644,
812 : : .proc_handler = proc_dointvec_minmax_sysadmin,
813 : : .extra1 = &zero,
814 : : .extra2 = &two,
815 : : },
816 : : #endif
817 : : {
818 : : .procname = "ngroups_max",
819 : : .data = &ngroups_max,
820 : : .maxlen = sizeof (int),
821 : : .mode = 0444,
822 : : .proc_handler = proc_dointvec,
823 : : },
824 : : {
825 : : .procname = "cap_last_cap",
826 : : .data = (void *)&cap_last_cap,
827 : : .maxlen = sizeof(int),
828 : : .mode = 0444,
829 : : .proc_handler = proc_dointvec,
830 : : },
831 : : #if defined(CONFIG_LOCKUP_DETECTOR)
832 : : {
833 : : .procname = "watchdog",
834 : : .data = &watchdog_user_enabled,
835 : : .maxlen = sizeof (int),
836 : : .mode = 0644,
837 : : .proc_handler = proc_dowatchdog,
838 : : .extra1 = &zero,
839 : : .extra2 = &one,
840 : : },
841 : : {
842 : : .procname = "watchdog_thresh",
843 : : .data = &watchdog_thresh,
844 : : .maxlen = sizeof(int),
845 : : .mode = 0644,
846 : : .proc_handler = proc_dowatchdog,
847 : : .extra1 = &zero,
848 : : .extra2 = &sixty,
849 : : },
850 : : {
851 : : .procname = "softlockup_panic",
852 : : .data = &softlockup_panic,
853 : : .maxlen = sizeof(int),
854 : : .mode = 0644,
855 : : .proc_handler = proc_dointvec_minmax,
856 : : .extra1 = &zero,
857 : : .extra2 = &one,
858 : : },
859 : : {
860 : : .procname = "nmi_watchdog",
861 : : .data = &watchdog_user_enabled,
862 : : .maxlen = sizeof (int),
863 : : .mode = 0644,
864 : : .proc_handler = proc_dowatchdog,
865 : : .extra1 = &zero,
866 : : .extra2 = &one,
867 : : },
868 : : #endif
869 : : #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
870 : : {
871 : : .procname = "unknown_nmi_panic",
872 : : .data = &unknown_nmi_panic,
873 : : .maxlen = sizeof (int),
874 : : .mode = 0644,
875 : : .proc_handler = proc_dointvec,
876 : : },
877 : : #endif
878 : : #if defined(CONFIG_X86)
879 : : {
880 : : .procname = "panic_on_unrecovered_nmi",
881 : : .data = &panic_on_unrecovered_nmi,
882 : : .maxlen = sizeof(int),
883 : : .mode = 0644,
884 : : .proc_handler = proc_dointvec,
885 : : },
886 : : {
887 : : .procname = "panic_on_io_nmi",
888 : : .data = &panic_on_io_nmi,
889 : : .maxlen = sizeof(int),
890 : : .mode = 0644,
891 : : .proc_handler = proc_dointvec,
892 : : },
893 : : #ifdef CONFIG_DEBUG_STACKOVERFLOW
894 : : {
895 : : .procname = "panic_on_stackoverflow",
896 : : .data = &sysctl_panic_on_stackoverflow,
897 : : .maxlen = sizeof(int),
898 : : .mode = 0644,
899 : : .proc_handler = proc_dointvec,
900 : : },
901 : : #endif
902 : : {
903 : : .procname = "bootloader_type",
904 : : .data = &bootloader_type,
905 : : .maxlen = sizeof (int),
906 : : .mode = 0444,
907 : : .proc_handler = proc_dointvec,
908 : : },
909 : : {
910 : : .procname = "bootloader_version",
911 : : .data = &bootloader_version,
912 : : .maxlen = sizeof (int),
913 : : .mode = 0444,
914 : : .proc_handler = proc_dointvec,
915 : : },
916 : : {
917 : : .procname = "kstack_depth_to_print",
918 : : .data = &kstack_depth_to_print,
919 : : .maxlen = sizeof(int),
920 : : .mode = 0644,
921 : : .proc_handler = proc_dointvec,
922 : : },
923 : : {
924 : : .procname = "io_delay_type",
925 : : .data = &io_delay_type,
926 : : .maxlen = sizeof(int),
927 : : .mode = 0644,
928 : : .proc_handler = proc_dointvec,
929 : : },
930 : : #endif
931 : : #if defined(CONFIG_MMU)
932 : : {
933 : : .procname = "randomize_va_space",
934 : : .data = &randomize_va_space,
935 : : .maxlen = sizeof(int),
936 : : .mode = 0644,
937 : : .proc_handler = proc_dointvec,
938 : : },
939 : : #endif
940 : : #if defined(CONFIG_S390) && defined(CONFIG_SMP)
941 : : {
942 : : .procname = "spin_retry",
943 : : .data = &spin_retry,
944 : : .maxlen = sizeof (int),
945 : : .mode = 0644,
946 : : .proc_handler = proc_dointvec,
947 : : },
948 : : #endif
949 : : #if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86)
950 : : {
951 : : .procname = "acpi_video_flags",
952 : : .data = &acpi_realmode_flags,
953 : : .maxlen = sizeof (unsigned long),
954 : : .mode = 0644,
955 : : .proc_handler = proc_doulongvec_minmax,
956 : : },
957 : : #endif
958 : : #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN
959 : : {
960 : : .procname = "ignore-unaligned-usertrap",
961 : : .data = &no_unaligned_warning,
962 : : .maxlen = sizeof (int),
963 : : .mode = 0644,
964 : : .proc_handler = proc_dointvec,
965 : : },
966 : : #endif
967 : : #ifdef CONFIG_IA64
968 : : {
969 : : .procname = "unaligned-dump-stack",
970 : : .data = &unaligned_dump_stack,
971 : : .maxlen = sizeof (int),
972 : : .mode = 0644,
973 : : .proc_handler = proc_dointvec,
974 : : },
975 : : #endif
976 : : #ifdef CONFIG_DETECT_HUNG_TASK
977 : : {
978 : : .procname = "hung_task_panic",
979 : : .data = &sysctl_hung_task_panic,
980 : : .maxlen = sizeof(int),
981 : : .mode = 0644,
982 : : .proc_handler = proc_dointvec_minmax,
983 : : .extra1 = &zero,
984 : : .extra2 = &one,
985 : : },
986 : : {
987 : : .procname = "hung_task_check_count",
988 : : .data = &sysctl_hung_task_check_count,
989 : : .maxlen = sizeof(int),
990 : : .mode = 0644,
991 : : .proc_handler = proc_dointvec_minmax,
992 : : .extra1 = &zero,
993 : : },
994 : : {
995 : : .procname = "hung_task_timeout_secs",
996 : : .data = &sysctl_hung_task_timeout_secs,
997 : : .maxlen = sizeof(unsigned long),
998 : : .mode = 0644,
999 : : .proc_handler = proc_dohung_task_timeout_secs,
1000 : : },
1001 : : {
1002 : : .procname = "hung_task_warnings",
1003 : : .data = &sysctl_hung_task_warnings,
1004 : : .maxlen = sizeof(int),
1005 : : .mode = 0644,
1006 : : .proc_handler = proc_dointvec_minmax,
1007 : : .extra1 = &neg_one,
1008 : : },
1009 : : #endif
1010 : : #ifdef CONFIG_COMPAT
1011 : : {
1012 : : .procname = "compat-log",
1013 : : .data = &compat_log,
1014 : : .maxlen = sizeof (int),
1015 : : .mode = 0644,
1016 : : .proc_handler = proc_dointvec,
1017 : : },
1018 : : #endif
1019 : : #ifdef CONFIG_RT_MUTEXES
1020 : : {
1021 : : .procname = "max_lock_depth",
1022 : : .data = &max_lock_depth,
1023 : : .maxlen = sizeof(int),
1024 : : .mode = 0644,
1025 : : .proc_handler = proc_dointvec,
1026 : : },
1027 : : #endif
1028 : : {
1029 : : .procname = "poweroff_cmd",
1030 : : .data = &poweroff_cmd,
1031 : : .maxlen = POWEROFF_CMD_PATH_LEN,
1032 : : .mode = 0644,
1033 : : .proc_handler = proc_dostring,
1034 : : },
1035 : : #ifdef CONFIG_KEYS
1036 : : {
1037 : : .procname = "keys",
1038 : : .mode = 0555,
1039 : : .child = key_sysctls,
1040 : : },
1041 : : #endif
1042 : : #ifdef CONFIG_RCU_TORTURE_TEST
1043 : : {
1044 : : .procname = "rcutorture_runnable",
1045 : : .data = &rcutorture_runnable,
1046 : : .maxlen = sizeof(int),
1047 : : .mode = 0644,
1048 : : .proc_handler = proc_dointvec,
1049 : : },
1050 : : #endif
1051 : : #ifdef CONFIG_PERF_EVENTS
1052 : : /*
1053 : : * User-space scripts rely on the existence of this file
1054 : : * as a feature check for perf_events being enabled.
1055 : : *
1056 : : * So it's an ABI, do not remove!
1057 : : */
1058 : : {
1059 : : .procname = "perf_event_paranoid",
1060 : : .data = &sysctl_perf_event_paranoid,
1061 : : .maxlen = sizeof(sysctl_perf_event_paranoid),
1062 : : .mode = 0644,
1063 : : .proc_handler = proc_dointvec,
1064 : : },
1065 : : {
1066 : : .procname = "perf_event_mlock_kb",
1067 : : .data = &sysctl_perf_event_mlock,
1068 : : .maxlen = sizeof(sysctl_perf_event_mlock),
1069 : : .mode = 0644,
1070 : : .proc_handler = proc_dointvec,
1071 : : },
1072 : : {
1073 : : .procname = "perf_event_max_sample_rate",
1074 : : .data = &sysctl_perf_event_sample_rate,
1075 : : .maxlen = sizeof(sysctl_perf_event_sample_rate),
1076 : : .mode = 0644,
1077 : : .proc_handler = perf_proc_update_handler,
1078 : : .extra1 = &one,
1079 : : },
1080 : : {
1081 : : .procname = "perf_cpu_time_max_percent",
1082 : : .data = &sysctl_perf_cpu_time_max_percent,
1083 : : .maxlen = sizeof(sysctl_perf_cpu_time_max_percent),
1084 : : .mode = 0644,
1085 : : .proc_handler = perf_cpu_time_max_percent_handler,
1086 : : .extra1 = &zero,
1087 : : .extra2 = &one_hundred,
1088 : : },
1089 : : #endif
1090 : : #ifdef CONFIG_KMEMCHECK
1091 : : {
1092 : : .procname = "kmemcheck",
1093 : : .data = &kmemcheck_enabled,
1094 : : .maxlen = sizeof(int),
1095 : : .mode = 0644,
1096 : : .proc_handler = proc_dointvec,
1097 : : },
1098 : : #endif
1099 : : #ifdef CONFIG_BLOCK
1100 : : {
1101 : : .procname = "blk_iopoll",
1102 : : .data = &blk_iopoll_enabled,
1103 : : .maxlen = sizeof(int),
1104 : : .mode = 0644,
1105 : : .proc_handler = proc_dointvec,
1106 : : },
1107 : : #endif
1108 : : { }
1109 : : };
1110 : :
1111 : : static struct ctl_table vm_table[] = {
1112 : : {
1113 : : .procname = "overcommit_memory",
1114 : : .data = &sysctl_overcommit_memory,
1115 : : .maxlen = sizeof(sysctl_overcommit_memory),
1116 : : .mode = 0644,
1117 : : .proc_handler = proc_dointvec_minmax,
1118 : : .extra1 = &zero,
1119 : : .extra2 = &two,
1120 : : },
1121 : : {
1122 : : .procname = "panic_on_oom",
1123 : : .data = &sysctl_panic_on_oom,
1124 : : .maxlen = sizeof(sysctl_panic_on_oom),
1125 : : .mode = 0644,
1126 : : .proc_handler = proc_dointvec_minmax,
1127 : : .extra1 = &zero,
1128 : : .extra2 = &two,
1129 : : },
1130 : : {
1131 : : .procname = "oom_kill_allocating_task",
1132 : : .data = &sysctl_oom_kill_allocating_task,
1133 : : .maxlen = sizeof(sysctl_oom_kill_allocating_task),
1134 : : .mode = 0644,
1135 : : .proc_handler = proc_dointvec,
1136 : : },
1137 : : {
1138 : : .procname = "oom_dump_tasks",
1139 : : .data = &sysctl_oom_dump_tasks,
1140 : : .maxlen = sizeof(sysctl_oom_dump_tasks),
1141 : : .mode = 0644,
1142 : : .proc_handler = proc_dointvec,
1143 : : },
1144 : : {
1145 : : .procname = "overcommit_ratio",
1146 : : .data = &sysctl_overcommit_ratio,
1147 : : .maxlen = sizeof(sysctl_overcommit_ratio),
1148 : : .mode = 0644,
1149 : : .proc_handler = overcommit_ratio_handler,
1150 : : },
1151 : : {
1152 : : .procname = "overcommit_kbytes",
1153 : : .data = &sysctl_overcommit_kbytes,
1154 : : .maxlen = sizeof(sysctl_overcommit_kbytes),
1155 : : .mode = 0644,
1156 : : .proc_handler = overcommit_kbytes_handler,
1157 : : },
1158 : : {
1159 : : .procname = "page-cluster",
1160 : : .data = &page_cluster,
1161 : : .maxlen = sizeof(int),
1162 : : .mode = 0644,
1163 : : .proc_handler = proc_dointvec_minmax,
1164 : : .extra1 = &zero,
1165 : : },
1166 : : {
1167 : : .procname = "dirty_background_ratio",
1168 : : .data = &dirty_background_ratio,
1169 : : .maxlen = sizeof(dirty_background_ratio),
1170 : : .mode = 0644,
1171 : : .proc_handler = dirty_background_ratio_handler,
1172 : : .extra1 = &zero,
1173 : : .extra2 = &one_hundred,
1174 : : },
1175 : : {
1176 : : .procname = "dirty_background_bytes",
1177 : : .data = &dirty_background_bytes,
1178 : : .maxlen = sizeof(dirty_background_bytes),
1179 : : .mode = 0644,
1180 : : .proc_handler = dirty_background_bytes_handler,
1181 : : .extra1 = &one_ul,
1182 : : },
1183 : : {
1184 : : .procname = "dirty_ratio",
1185 : : .data = &vm_dirty_ratio,
1186 : : .maxlen = sizeof(vm_dirty_ratio),
1187 : : .mode = 0644,
1188 : : .proc_handler = dirty_ratio_handler,
1189 : : .extra1 = &zero,
1190 : : .extra2 = &one_hundred,
1191 : : },
1192 : : {
1193 : : .procname = "dirty_bytes",
1194 : : .data = &vm_dirty_bytes,
1195 : : .maxlen = sizeof(vm_dirty_bytes),
1196 : : .mode = 0644,
1197 : : .proc_handler = dirty_bytes_handler,
1198 : : .extra1 = &dirty_bytes_min,
1199 : : },
1200 : : {
1201 : : .procname = "dirty_writeback_centisecs",
1202 : : .data = &dirty_writeback_interval,
1203 : : .maxlen = sizeof(dirty_writeback_interval),
1204 : : .mode = 0644,
1205 : : .proc_handler = dirty_writeback_centisecs_handler,
1206 : : },
1207 : : {
1208 : : .procname = "dirty_expire_centisecs",
1209 : : .data = &dirty_expire_interval,
1210 : : .maxlen = sizeof(dirty_expire_interval),
1211 : : .mode = 0644,
1212 : : .proc_handler = proc_dointvec_minmax,
1213 : : .extra1 = &zero,
1214 : : },
1215 : : {
1216 : : .procname = "nr_pdflush_threads",
1217 : : .mode = 0444 /* read-only */,
1218 : : .proc_handler = pdflush_proc_obsolete,
1219 : : },
1220 : : {
1221 : : .procname = "swappiness",
1222 : : .data = &vm_swappiness,
1223 : : .maxlen = sizeof(vm_swappiness),
1224 : : .mode = 0644,
1225 : : .proc_handler = proc_dointvec_minmax,
1226 : : .extra1 = &zero,
1227 : : .extra2 = &one_hundred,
1228 : : },
1229 : : #ifdef CONFIG_HUGETLB_PAGE
1230 : : {
1231 : : .procname = "nr_hugepages",
1232 : : .data = NULL,
1233 : : .maxlen = sizeof(unsigned long),
1234 : : .mode = 0644,
1235 : : .proc_handler = hugetlb_sysctl_handler,
1236 : : .extra1 = (void *)&hugetlb_zero,
1237 : : .extra2 = (void *)&hugetlb_infinity,
1238 : : },
1239 : : #ifdef CONFIG_NUMA
1240 : : {
1241 : : .procname = "nr_hugepages_mempolicy",
1242 : : .data = NULL,
1243 : : .maxlen = sizeof(unsigned long),
1244 : : .mode = 0644,
1245 : : .proc_handler = &hugetlb_mempolicy_sysctl_handler,
1246 : : .extra1 = (void *)&hugetlb_zero,
1247 : : .extra2 = (void *)&hugetlb_infinity,
1248 : : },
1249 : : #endif
1250 : : {
1251 : : .procname = "hugetlb_shm_group",
1252 : : .data = &sysctl_hugetlb_shm_group,
1253 : : .maxlen = sizeof(gid_t),
1254 : : .mode = 0644,
1255 : : .proc_handler = proc_dointvec,
1256 : : },
1257 : : {
1258 : : .procname = "hugepages_treat_as_movable",
1259 : : .data = &hugepages_treat_as_movable,
1260 : : .maxlen = sizeof(int),
1261 : : .mode = 0644,
1262 : : .proc_handler = proc_dointvec,
1263 : : },
1264 : : {
1265 : : .procname = "nr_overcommit_hugepages",
1266 : : .data = NULL,
1267 : : .maxlen = sizeof(unsigned long),
1268 : : .mode = 0644,
1269 : : .proc_handler = hugetlb_overcommit_handler,
1270 : : .extra1 = (void *)&hugetlb_zero,
1271 : : .extra2 = (void *)&hugetlb_infinity,
1272 : : },
1273 : : #endif
1274 : : {
1275 : : .procname = "lowmem_reserve_ratio",
1276 : : .data = &sysctl_lowmem_reserve_ratio,
1277 : : .maxlen = sizeof(sysctl_lowmem_reserve_ratio),
1278 : : .mode = 0644,
1279 : : .proc_handler = lowmem_reserve_ratio_sysctl_handler,
1280 : : },
1281 : : {
1282 : : .procname = "drop_caches",
1283 : : .data = &sysctl_drop_caches,
1284 : : .maxlen = sizeof(int),
1285 : : .mode = 0644,
1286 : : .proc_handler = drop_caches_sysctl_handler,
1287 : : .extra1 = &one,
1288 : : .extra2 = &three,
1289 : : },
1290 : : #ifdef CONFIG_COMPACTION
1291 : : {
1292 : : .procname = "compact_memory",
1293 : : .data = &sysctl_compact_memory,
1294 : : .maxlen = sizeof(int),
1295 : : .mode = 0200,
1296 : : .proc_handler = sysctl_compaction_handler,
1297 : : },
1298 : : {
1299 : : .procname = "extfrag_threshold",
1300 : : .data = &sysctl_extfrag_threshold,
1301 : : .maxlen = sizeof(int),
1302 : : .mode = 0644,
1303 : : .proc_handler = sysctl_extfrag_handler,
1304 : : .extra1 = &min_extfrag_threshold,
1305 : : .extra2 = &max_extfrag_threshold,
1306 : : },
1307 : :
1308 : : #endif /* CONFIG_COMPACTION */
1309 : : {
1310 : : .procname = "min_free_kbytes",
1311 : : .data = &min_free_kbytes,
1312 : : .maxlen = sizeof(min_free_kbytes),
1313 : : .mode = 0644,
1314 : : .proc_handler = min_free_kbytes_sysctl_handler,
1315 : : .extra1 = &zero,
1316 : : },
1317 : : {
1318 : : .procname = "extra_free_kbytes",
1319 : : .data = &extra_free_kbytes,
1320 : : .maxlen = sizeof(extra_free_kbytes),
1321 : : .mode = 0644,
1322 : : .proc_handler = min_free_kbytes_sysctl_handler,
1323 : : .extra1 = &zero,
1324 : : },
1325 : : {
1326 : : .procname = "min_free_order_shift",
1327 : : .data = &min_free_order_shift,
1328 : : .maxlen = sizeof(min_free_order_shift),
1329 : : .mode = 0644,
1330 : : .proc_handler = &proc_dointvec
1331 : : },
1332 : : {
1333 : : .procname = "percpu_pagelist_fraction",
1334 : : .data = &percpu_pagelist_fraction,
1335 : : .maxlen = sizeof(percpu_pagelist_fraction),
1336 : : .mode = 0644,
1337 : : .proc_handler = percpu_pagelist_fraction_sysctl_handler,
1338 : : .extra1 = &min_percpu_pagelist_fract,
1339 : : },
1340 : : #ifdef CONFIG_MMU
1341 : : {
1342 : : .procname = "max_map_count",
1343 : : .data = &sysctl_max_map_count,
1344 : : .maxlen = sizeof(sysctl_max_map_count),
1345 : : .mode = 0644,
1346 : : .proc_handler = proc_dointvec_minmax,
1347 : : .extra1 = &zero,
1348 : : },
1349 : : #else
1350 : : {
1351 : : .procname = "nr_trim_pages",
1352 : : .data = &sysctl_nr_trim_pages,
1353 : : .maxlen = sizeof(sysctl_nr_trim_pages),
1354 : : .mode = 0644,
1355 : : .proc_handler = proc_dointvec_minmax,
1356 : : .extra1 = &zero,
1357 : : },
1358 : : #endif
1359 : : {
1360 : : .procname = "laptop_mode",
1361 : : .data = &laptop_mode,
1362 : : .maxlen = sizeof(laptop_mode),
1363 : : .mode = 0644,
1364 : : .proc_handler = proc_dointvec_jiffies,
1365 : : },
1366 : : {
1367 : : .procname = "block_dump",
1368 : : .data = &block_dump,
1369 : : .maxlen = sizeof(block_dump),
1370 : : .mode = 0644,
1371 : : .proc_handler = proc_dointvec,
1372 : : .extra1 = &zero,
1373 : : },
1374 : : {
1375 : : .procname = "vfs_cache_pressure",
1376 : : .data = &sysctl_vfs_cache_pressure,
1377 : : .maxlen = sizeof(sysctl_vfs_cache_pressure),
1378 : : .mode = 0644,
1379 : : .proc_handler = proc_dointvec,
1380 : : .extra1 = &zero,
1381 : : },
1382 : : #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
1383 : : {
1384 : : .procname = "legacy_va_layout",
1385 : : .data = &sysctl_legacy_va_layout,
1386 : : .maxlen = sizeof(sysctl_legacy_va_layout),
1387 : : .mode = 0644,
1388 : : .proc_handler = proc_dointvec,
1389 : : .extra1 = &zero,
1390 : : },
1391 : : #endif
1392 : : #ifdef CONFIG_NUMA
1393 : : {
1394 : : .procname = "zone_reclaim_mode",
1395 : : .data = &zone_reclaim_mode,
1396 : : .maxlen = sizeof(zone_reclaim_mode),
1397 : : .mode = 0644,
1398 : : .proc_handler = proc_dointvec,
1399 : : .extra1 = &zero,
1400 : : },
1401 : : {
1402 : : .procname = "min_unmapped_ratio",
1403 : : .data = &sysctl_min_unmapped_ratio,
1404 : : .maxlen = sizeof(sysctl_min_unmapped_ratio),
1405 : : .mode = 0644,
1406 : : .proc_handler = sysctl_min_unmapped_ratio_sysctl_handler,
1407 : : .extra1 = &zero,
1408 : : .extra2 = &one_hundred,
1409 : : },
1410 : : {
1411 : : .procname = "min_slab_ratio",
1412 : : .data = &sysctl_min_slab_ratio,
1413 : : .maxlen = sizeof(sysctl_min_slab_ratio),
1414 : : .mode = 0644,
1415 : : .proc_handler = sysctl_min_slab_ratio_sysctl_handler,
1416 : : .extra1 = &zero,
1417 : : .extra2 = &one_hundred,
1418 : : },
1419 : : #endif
1420 : : #ifdef CONFIG_SMP
1421 : : {
1422 : : .procname = "stat_interval",
1423 : : .data = &sysctl_stat_interval,
1424 : : .maxlen = sizeof(sysctl_stat_interval),
1425 : : .mode = 0644,
1426 : : .proc_handler = proc_dointvec_jiffies,
1427 : : },
1428 : : #endif
1429 : : #ifdef CONFIG_MMU
1430 : : {
1431 : : .procname = "mmap_min_addr",
1432 : : .data = &dac_mmap_min_addr,
1433 : : .maxlen = sizeof(unsigned long),
1434 : : .mode = 0644,
1435 : : .proc_handler = mmap_min_addr_handler,
1436 : : },
1437 : : #endif
1438 : : #ifdef CONFIG_NUMA
1439 : : {
1440 : : .procname = "numa_zonelist_order",
1441 : : .data = &numa_zonelist_order,
1442 : : .maxlen = NUMA_ZONELIST_ORDER_LEN,
1443 : : .mode = 0644,
1444 : : .proc_handler = numa_zonelist_order_handler,
1445 : : },
1446 : : #endif
1447 : : #if (defined(CONFIG_X86_32) && !defined(CONFIG_UML))|| \
1448 : : (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
1449 : : {
1450 : : .procname = "vdso_enabled",
1451 : : .data = &vdso_enabled,
1452 : : .maxlen = sizeof(vdso_enabled),
1453 : : .mode = 0644,
1454 : : .proc_handler = proc_dointvec,
1455 : : .extra1 = &zero,
1456 : : },
1457 : : #endif
1458 : : #ifdef CONFIG_HIGHMEM
1459 : : {
1460 : : .procname = "highmem_is_dirtyable",
1461 : : .data = &vm_highmem_is_dirtyable,
1462 : : .maxlen = sizeof(vm_highmem_is_dirtyable),
1463 : : .mode = 0644,
1464 : : .proc_handler = proc_dointvec_minmax,
1465 : : .extra1 = &zero,
1466 : : .extra2 = &one,
1467 : : },
1468 : : #endif
1469 : : {
1470 : : .procname = "scan_unevictable_pages",
1471 : : .data = &scan_unevictable_pages,
1472 : : .maxlen = sizeof(scan_unevictable_pages),
1473 : : .mode = 0644,
1474 : : .proc_handler = scan_unevictable_handler,
1475 : : },
1476 : : #ifdef CONFIG_MEMORY_FAILURE
1477 : : {
1478 : : .procname = "memory_failure_early_kill",
1479 : : .data = &sysctl_memory_failure_early_kill,
1480 : : .maxlen = sizeof(sysctl_memory_failure_early_kill),
1481 : : .mode = 0644,
1482 : : .proc_handler = proc_dointvec_minmax,
1483 : : .extra1 = &zero,
1484 : : .extra2 = &one,
1485 : : },
1486 : : {
1487 : : .procname = "memory_failure_recovery",
1488 : : .data = &sysctl_memory_failure_recovery,
1489 : : .maxlen = sizeof(sysctl_memory_failure_recovery),
1490 : : .mode = 0644,
1491 : : .proc_handler = proc_dointvec_minmax,
1492 : : .extra1 = &zero,
1493 : : .extra2 = &one,
1494 : : },
1495 : : #endif
1496 : : {
1497 : : .procname = "user_reserve_kbytes",
1498 : : .data = &sysctl_user_reserve_kbytes,
1499 : : .maxlen = sizeof(sysctl_user_reserve_kbytes),
1500 : : .mode = 0644,
1501 : : .proc_handler = proc_doulongvec_minmax,
1502 : : },
1503 : : {
1504 : : .procname = "admin_reserve_kbytes",
1505 : : .data = &sysctl_admin_reserve_kbytes,
1506 : : .maxlen = sizeof(sysctl_admin_reserve_kbytes),
1507 : : .mode = 0644,
1508 : : .proc_handler = proc_doulongvec_minmax,
1509 : : },
1510 : : { }
1511 : : };
1512 : :
1513 : : #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
1514 : : static struct ctl_table binfmt_misc_table[] = {
1515 : : { }
1516 : : };
1517 : : #endif
1518 : :
1519 : : static struct ctl_table fs_table[] = {
1520 : : {
1521 : : .procname = "inode-nr",
1522 : : .data = &inodes_stat,
1523 : : .maxlen = 2*sizeof(long),
1524 : : .mode = 0444,
1525 : : .proc_handler = proc_nr_inodes,
1526 : : },
1527 : : {
1528 : : .procname = "inode-state",
1529 : : .data = &inodes_stat,
1530 : : .maxlen = 7*sizeof(long),
1531 : : .mode = 0444,
1532 : : .proc_handler = proc_nr_inodes,
1533 : : },
1534 : : {
1535 : : .procname = "file-nr",
1536 : : .data = &files_stat,
1537 : : .maxlen = sizeof(files_stat),
1538 : : .mode = 0444,
1539 : : .proc_handler = proc_nr_files,
1540 : : },
1541 : : {
1542 : : .procname = "file-max",
1543 : : .data = &files_stat.max_files,
1544 : : .maxlen = sizeof(files_stat.max_files),
1545 : : .mode = 0644,
1546 : : .proc_handler = proc_doulongvec_minmax,
1547 : : },
1548 : : {
1549 : : .procname = "nr_open",
1550 : : .data = &sysctl_nr_open,
1551 : : .maxlen = sizeof(int),
1552 : : .mode = 0644,
1553 : : .proc_handler = proc_dointvec_minmax,
1554 : : .extra1 = &sysctl_nr_open_min,
1555 : : .extra2 = &sysctl_nr_open_max,
1556 : : },
1557 : : {
1558 : : .procname = "dentry-state",
1559 : : .data = &dentry_stat,
1560 : : .maxlen = 6*sizeof(long),
1561 : : .mode = 0444,
1562 : : .proc_handler = proc_nr_dentry,
1563 : : },
1564 : : {
1565 : : .procname = "overflowuid",
1566 : : .data = &fs_overflowuid,
1567 : : .maxlen = sizeof(int),
1568 : : .mode = 0644,
1569 : : .proc_handler = proc_dointvec_minmax,
1570 : : .extra1 = &minolduid,
1571 : : .extra2 = &maxolduid,
1572 : : },
1573 : : {
1574 : : .procname = "overflowgid",
1575 : : .data = &fs_overflowgid,
1576 : : .maxlen = sizeof(int),
1577 : : .mode = 0644,
1578 : : .proc_handler = proc_dointvec_minmax,
1579 : : .extra1 = &minolduid,
1580 : : .extra2 = &maxolduid,
1581 : : },
1582 : : #ifdef CONFIG_FILE_LOCKING
1583 : : {
1584 : : .procname = "leases-enable",
1585 : : .data = &leases_enable,
1586 : : .maxlen = sizeof(int),
1587 : : .mode = 0644,
1588 : : .proc_handler = proc_dointvec,
1589 : : },
1590 : : #endif
1591 : : #ifdef CONFIG_DNOTIFY
1592 : : {
1593 : : .procname = "dir-notify-enable",
1594 : : .data = &dir_notify_enable,
1595 : : .maxlen = sizeof(int),
1596 : : .mode = 0644,
1597 : : .proc_handler = proc_dointvec,
1598 : : },
1599 : : #endif
1600 : : #ifdef CONFIG_MMU
1601 : : #ifdef CONFIG_FILE_LOCKING
1602 : : {
1603 : : .procname = "lease-break-time",
1604 : : .data = &lease_break_time,
1605 : : .maxlen = sizeof(int),
1606 : : .mode = 0644,
1607 : : .proc_handler = proc_dointvec,
1608 : : },
1609 : : #endif
1610 : : #ifdef CONFIG_AIO
1611 : : {
1612 : : .procname = "aio-nr",
1613 : : .data = &aio_nr,
1614 : : .maxlen = sizeof(aio_nr),
1615 : : .mode = 0444,
1616 : : .proc_handler = proc_doulongvec_minmax,
1617 : : },
1618 : : {
1619 : : .procname = "aio-max-nr",
1620 : : .data = &aio_max_nr,
1621 : : .maxlen = sizeof(aio_max_nr),
1622 : : .mode = 0644,
1623 : : .proc_handler = proc_doulongvec_minmax,
1624 : : },
1625 : : #endif /* CONFIG_AIO */
1626 : : #ifdef CONFIG_INOTIFY_USER
1627 : : {
1628 : : .procname = "inotify",
1629 : : .mode = 0555,
1630 : : .child = inotify_table,
1631 : : },
1632 : : #endif
1633 : : #ifdef CONFIG_EPOLL
1634 : : {
1635 : : .procname = "epoll",
1636 : : .mode = 0555,
1637 : : .child = epoll_table,
1638 : : },
1639 : : #endif
1640 : : #endif
1641 : : {
1642 : : .procname = "protected_symlinks",
1643 : : .data = &sysctl_protected_symlinks,
1644 : : .maxlen = sizeof(int),
1645 : : .mode = 0600,
1646 : : .proc_handler = proc_dointvec_minmax,
1647 : : .extra1 = &zero,
1648 : : .extra2 = &one,
1649 : : },
1650 : : {
1651 : : .procname = "protected_hardlinks",
1652 : : .data = &sysctl_protected_hardlinks,
1653 : : .maxlen = sizeof(int),
1654 : : .mode = 0600,
1655 : : .proc_handler = proc_dointvec_minmax,
1656 : : .extra1 = &zero,
1657 : : .extra2 = &one,
1658 : : },
1659 : : {
1660 : : .procname = "suid_dumpable",
1661 : : .data = &suid_dumpable,
1662 : : .maxlen = sizeof(int),
1663 : : .mode = 0644,
1664 : : .proc_handler = proc_dointvec_minmax_coredump,
1665 : : .extra1 = &zero,
1666 : : .extra2 = &two,
1667 : : },
1668 : : #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
1669 : : {
1670 : : .procname = "binfmt_misc",
1671 : : .mode = 0555,
1672 : : .child = binfmt_misc_table,
1673 : : },
1674 : : #endif
1675 : : {
1676 : : .procname = "pipe-max-size",
1677 : : .data = &pipe_max_size,
1678 : : .maxlen = sizeof(int),
1679 : : .mode = 0644,
1680 : : .proc_handler = &pipe_proc_fn,
1681 : : .extra1 = &pipe_min_size,
1682 : : },
1683 : : { }
1684 : : };
1685 : :
1686 : : static struct ctl_table debug_table[] = {
1687 : : #ifdef CONFIG_SYSCTL_EXCEPTION_TRACE
1688 : : {
1689 : : .procname = "exception-trace",
1690 : : .data = &show_unhandled_signals,
1691 : : .maxlen = sizeof(int),
1692 : : .mode = 0644,
1693 : : .proc_handler = proc_dointvec
1694 : : },
1695 : : #endif
1696 : : #if defined(CONFIG_OPTPROBES)
1697 : : {
1698 : : .procname = "kprobes-optimization",
1699 : : .data = &sysctl_kprobes_optimization,
1700 : : .maxlen = sizeof(int),
1701 : : .mode = 0644,
1702 : : .proc_handler = proc_kprobes_optimization_handler,
1703 : : .extra1 = &zero,
1704 : : .extra2 = &one,
1705 : : },
1706 : : #endif
1707 : : { }
1708 : : };
1709 : :
1710 : : static struct ctl_table dev_table[] = {
1711 : : { }
1712 : : };
1713 : :
1714 : 0 : int __init sysctl_init(void)
1715 : : {
1716 : : struct ctl_table_header *hdr;
1717 : :
1718 : 0 : hdr = register_sysctl_table(sysctl_base_table);
1719 : : kmemleak_not_leak(hdr);
1720 : 0 : return 0;
1721 : : }
1722 : :
1723 : : #endif /* CONFIG_SYSCTL */
1724 : :
1725 : : /*
1726 : : * /proc/sys support
1727 : : */
1728 : :
1729 : : #ifdef CONFIG_PROC_SYSCTL
1730 : :
1731 : 0 : static int _proc_do_string(void* data, int maxlen, int write,
1732 : : void __user *buffer,
1733 : : size_t *lenp, loff_t *ppos)
1734 : : {
1735 : : size_t len;
1736 : : char __user *p;
1737 : : char c;
1738 : :
1739 [ + - ][ - + ]: 76 : if (!data || !maxlen || !*lenp) {
1740 : 0 : *lenp = 0;
1741 : 0 : return 0;
1742 : : }
1743 : :
1744 [ - + ]: 76 : if (write) {
1745 : : len = 0;
1746 : : p = buffer;
1747 [ # # ]: 0 : while (len < *lenp) {
1748 [ # # ]: 0 : if (get_user(c, p++))
1749 : : return -EFAULT;
1750 [ # # ]: 0 : if (c == 0 || c == '\n')
1751 : : break;
1752 : 0 : len++;
1753 : : }
1754 [ # # ]: 0 : if (len >= maxlen)
1755 : 0 : len = maxlen-1;
1756 [ # # ]: 0 : if(copy_from_user(data, buffer, len))
1757 : : return -EFAULT;
1758 : 0 : ((char *) data)[len] = 0;
1759 : 0 : *ppos += *lenp;
1760 : : } else {
1761 : 76 : len = strlen(data);
1762 [ - + ]: 76 : if (len > maxlen)
1763 : : len = maxlen;
1764 : :
1765 [ + + ]: 76 : if (*ppos > len) {
1766 : 38 : *lenp = 0;
1767 : 38 : return 0;
1768 : : }
1769 : :
1770 : 38 : data += *ppos;
1771 : 38 : len -= *ppos;
1772 : :
1773 [ - + ]: 38 : if (len > *lenp)
1774 : : len = *lenp;
1775 [ + - ]: 38 : if (len)
1776 [ + - ]: 114 : if(copy_to_user(buffer, data, len))
1777 : : return -EFAULT;
1778 [ + - ]: 38 : if (len < *lenp) {
1779 [ + - ]: 38 : if(put_user('\n', ((char __user *) buffer) + len))
1780 : : return -EFAULT;
1781 : 38 : len++;
1782 : : }
1783 : 38 : *lenp = len;
1784 : 38 : *ppos += len;
1785 : : }
1786 : : return 0;
1787 : : }
1788 : :
1789 : : /**
1790 : : * proc_dostring - read a string sysctl
1791 : : * @table: the sysctl table
1792 : : * @write: %TRUE if this is a write to the sysctl file
1793 : : * @buffer: the user buffer
1794 : : * @lenp: the size of the user buffer
1795 : : * @ppos: file position
1796 : : *
1797 : : * Reads/writes a string from/to the user buffer. If the kernel
1798 : : * buffer provided is not large enough to hold the string, the
1799 : : * string is truncated. The copied string is %NULL-terminated.
1800 : : * If the string is being read by the user process, it is copied
1801 : : * and a newline '\n' is added. It is truncated if the buffer is
1802 : : * not large enough.
1803 : : *
1804 : : * Returns 0 on success.
1805 : : */
1806 : 0 : int proc_dostring(struct ctl_table *table, int write,
1807 : : void __user *buffer, size_t *lenp, loff_t *ppos)
1808 : : {
1809 : 76 : return _proc_do_string(table->data, table->maxlen, write,
1810 : : buffer, lenp, ppos);
1811 : : }
1812 : :
1813 : : static size_t proc_skip_spaces(char **buf)
1814 : : {
1815 : : size_t ret;
1816 : 81 : char *tmp = skip_spaces(*buf);
1817 : 81 : ret = tmp - *buf;
1818 : 81 : *buf = tmp;
1819 : : return ret;
1820 : : }
1821 : :
1822 : : static void proc_skip_char(char **buf, size_t *size, const char v)
1823 : : {
1824 [ # # ][ # # ]: 0 : while (*size) {
1825 [ # # ][ # # ]: 0 : if (**buf != v)
1826 : : break;
1827 : 0 : (*size)--;
1828 : 0 : (*buf)++;
1829 : : }
1830 : : }
1831 : :
1832 : : #define TMPBUFLEN 22
1833 : : /**
1834 : : * proc_get_long - reads an ASCII formatted integer from a user buffer
1835 : : *
1836 : : * @buf: a kernel buffer
1837 : : * @size: size of the kernel buffer
1838 : : * @val: this is where the number will be stored
1839 : : * @neg: set to %TRUE if number is negative
1840 : : * @perm_tr: a vector which contains the allowed trailers
1841 : : * @perm_tr_len: size of the perm_tr vector
1842 : : * @tr: pointer to store the trailer character
1843 : : *
1844 : : * In case of success %0 is returned and @buf and @size are updated with
1845 : : * the amount of bytes read. If @tr is non-NULL and a trailing
1846 : : * character exists (size is non-zero after returning from this
1847 : : * function), @tr is updated with the trailing character.
1848 : : */
1849 : 0 : static int proc_get_long(char **buf, size_t *size,
1850 : : unsigned long *val, bool *neg,
1851 : : const char *perm_tr, unsigned perm_tr_len, char *tr)
1852 : : {
1853 : : int len;
1854 : : char *p, tmp[TMPBUFLEN];
1855 : :
1856 [ + ]: 81 : if (!*size)
1857 : : return -EINVAL;
1858 : :
1859 : 81 : len = *size;
1860 [ - + ]: 162 : if (len > TMPBUFLEN - 1)
1861 : : len = TMPBUFLEN - 1;
1862 : :
1863 : 81 : memcpy(tmp, *buf, len);
1864 : :
1865 : 81 : tmp[len] = 0;
1866 : 81 : p = tmp;
1867 [ - + ][ # # ]: 81 : if (*p == '-' && *size > 1) {
1868 : 0 : *neg = true;
1869 : 0 : p++;
1870 : : } else
1871 : 81 : *neg = false;
1872 [ + - ]: 81 : if (!isdigit(*p))
1873 : : return -EINVAL;
1874 : :
1875 : 81 : *val = simple_strtoul(p, &p, 0);
1876 : :
1877 : 81 : len = p - tmp;
1878 : :
1879 : : /* We don't know if the next char is whitespace thus we may accept
1880 : : * invalid integers (e.g. 1234...a) or two integers instead of one
1881 : : * (e.g. 123...1). So lets not allow such large numbers. */
1882 [ + - ]: 81 : if (len == TMPBUFLEN - 1)
1883 : : return -EINVAL;
1884 : :
1885 [ - + ][ # # ]: 81 : if (len < *size && perm_tr_len && !memchr(perm_tr, *p, perm_tr_len))
[ # # ]
1886 : : return -EINVAL;
1887 : :
1888 [ - + ][ # # ]: 81 : if (tr && (len < *size))
1889 : 0 : *tr = *p;
1890 : :
1891 : 81 : *buf += len;
1892 : 81 : *size -= len;
1893 : :
1894 : 81 : return 0;
1895 : : }
1896 : :
1897 : : /**
1898 : : * proc_put_long - converts an integer to a decimal ASCII formatted string
1899 : : *
1900 : : * @buf: the user buffer
1901 : : * @size: the size of the user buffer
1902 : : * @val: the integer to be converted
1903 : : * @neg: sign of the number, %TRUE for negative
1904 : : *
1905 : : * In case of success %0 is returned and @buf and @size are updated with
1906 : : * the amount of bytes written.
1907 : : */
1908 : 0 : static int proc_put_long(void __user **buf, size_t *size, unsigned long val,
1909 : : bool neg)
1910 : : {
1911 : : int len;
1912 : : char tmp[TMPBUFLEN], *p = tmp;
1913 : :
1914 [ + + ]: 1493 : sprintf(p, "%s%lu", neg ? "-" : "", val);
1915 : 1493 : len = strlen(tmp);
1916 [ - + ]: 1493 : if (len > *size)
1917 : 0 : len = *size;
1918 [ + - ]: 1493 : if (copy_to_user(*buf, tmp, len))
1919 : : return -EFAULT;
1920 : 1493 : *size -= len;
1921 : 1493 : *buf += len;
1922 : 1493 : return 0;
1923 : : }
1924 : : #undef TMPBUFLEN
1925 : :
1926 : 0 : static int proc_put_char(void __user **buf, size_t *size, char c)
1927 : : {
1928 [ + - ]: 1488 : if (*size) {
1929 : : char __user **buffer = (char __user **)buf;
1930 [ + - ]: 1488 : if (put_user(c, *buffer))
1931 : : return -EFAULT;
1932 : 1488 : (*size)--, (*buffer)++;
1933 : : *buf = *buffer;
1934 : : }
1935 : : return 0;
1936 : : }
1937 : :
1938 : 0 : static int do_proc_dointvec_conv(bool *negp, unsigned long *lvalp,
1939 : : int *valp,
1940 : : int write, void *data)
1941 : : {
1942 [ - + ]: 721 : if (write) {
1943 [ # # ]: 0 : *valp = *negp ? -*lvalp : *lvalp;
1944 : : } else {
1945 : 721 : int val = *valp;
1946 [ + + ]: 721 : if (val < 0) {
1947 : 6 : *negp = true;
1948 : 6 : *lvalp = (unsigned long)-val;
1949 : : } else {
1950 : 715 : *negp = false;
1951 : 715 : *lvalp = (unsigned long)val;
1952 : : }
1953 : : }
1954 : 721 : return 0;
1955 : : }
1956 : :
1957 : : static const char proc_wspace_sep[] = { ' ', '\t', '\n' };
1958 : :
1959 : 2253 : static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
1960 : : int write, void __user *buffer,
1961 : : size_t *lenp, loff_t *ppos,
1962 : : int (*conv)(bool *negp, unsigned long *lvalp, int *valp,
1963 : : int write, void *data),
1964 : : void *data)
1965 : : {
1966 : : int *i, vleft, first = 1, err = 0;
1967 : : unsigned long page = 0;
1968 : : size_t left;
1969 : : char *kbuf;
1970 : :
1971 [ + - ][ + - ]: 2253 : if (!tbl_data || !table->maxlen || !*lenp || (*ppos && !write)) {
[ + - ][ + + ]
[ + - ]
1972 : 762 : *lenp = 0;
1973 : : return 0;
1974 : : }
1975 : :
1976 : : i = (int *) tbl_data;
1977 : 1491 : vleft = table->maxlen / sizeof(*i);
1978 : 1491 : left = *lenp;
1979 : :
1980 [ + + ]: 1491 : if (!conv)
1981 : : conv = do_proc_dointvec_conv;
1982 : :
1983 [ + + ]: 1491 : if (write) {
1984 [ - + ]: 81 : if (left > PAGE_SIZE - 1)
1985 : 0 : left = PAGE_SIZE - 1;
1986 : 81 : page = __get_free_page(GFP_TEMPORARY);
1987 : 81 : kbuf = (char *) page;
1988 [ + - ]: 81 : if (!kbuf)
1989 : : return -ENOMEM;
1990 [ + + ]: 2334 : if (copy_from_user(kbuf, buffer, left)) {
1991 : : err = -EFAULT;
1992 : : goto free;
1993 : : }
1994 : 1491 : kbuf[left] = 0;
1995 : : }
1996 : :
1997 [ + + ][ + + ]: 3000 : for (; left && vleft--; i++, first=0) {
1998 : : unsigned long lval;
1999 : : bool neg;
2000 : :
2001 [ + + ]: 1509 : if (write) {
2002 : 81 : left -= proc_skip_spaces(&kbuf);
2003 : :
2004 [ + - ]: 81 : if (!left)
2005 : : break;
2006 : 81 : err = proc_get_long(&kbuf, &left, &lval, &neg,
2007 : : proc_wspace_sep,
2008 : : sizeof(proc_wspace_sep), NULL);
2009 [ + - ]: 81 : if (err)
2010 : : break;
2011 [ + - ]: 81 : if (conv(&neg, &lval, i, 1, data)) {
2012 : : err = -EINVAL;
2013 : : break;
2014 : : }
2015 : : } else {
2016 [ + - ]: 1428 : if (conv(&neg, &lval, i, 0, data)) {
2017 : : err = -EINVAL;
2018 : : break;
2019 : : }
2020 [ + + ]: 1428 : if (!first)
2021 : 18 : err = proc_put_char(&buffer, &left, '\t');
2022 [ + - ]: 1428 : if (err)
2023 : : break;
2024 : 1428 : err = proc_put_long(&buffer, &left, lval, neg);
2025 [ + - ]: 1428 : if (err)
2026 : : break;
2027 : : }
2028 : : }
2029 : :
2030 [ + + ][ + + ]: 1491 : if (!write && !first && left && !err)
[ + - ]
2031 : 1404 : err = proc_put_char(&buffer, &left, '\n');
2032 [ + + ][ - + ]: 1491 : if (write && !err && left)
2033 : 0 : left -= proc_skip_spaces(&kbuf);
2034 : : free:
2035 [ + + ]: 3744 : if (write) {
2036 : 81 : free_page(page);
2037 [ - + ]: 81 : if (first)
2038 [ # # ]: 0 : return err ? : -EINVAL;
2039 : : }
2040 : 1491 : *lenp -= left;
2041 : 1491 : *ppos += *lenp;
2042 : : return err;
2043 : : }
2044 : :
2045 : : static int do_proc_dointvec(struct ctl_table *table, int write,
2046 : : void __user *buffer, size_t *lenp, loff_t *ppos,
2047 : : int (*conv)(bool *negp, unsigned long *lvalp, int *valp,
2048 : : int write, void *data),
2049 : : void *data)
2050 : : {
2051 : 2251 : return __do_proc_dointvec(table->data, table, write,
2052 : : buffer, lenp, ppos, conv, data);
2053 : : }
2054 : :
2055 : : /**
2056 : : * proc_dointvec - read a vector of integers
2057 : : * @table: the sysctl table
2058 : : * @write: %TRUE if this is a write to the sysctl file
2059 : : * @buffer: the user buffer
2060 : : * @lenp: the size of the user buffer
2061 : : * @ppos: file position
2062 : : *
2063 : : * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2064 : : * values from/to the user buffer, treated as an ASCII string.
2065 : : *
2066 : : * Returns 0 on success.
2067 : : */
2068 : 0 : int proc_dointvec(struct ctl_table *table, int write,
2069 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2070 : : {
2071 : 1129 : return do_proc_dointvec(table,write,buffer,lenp,ppos,
2072 : : NULL,NULL);
2073 : : }
2074 : :
2075 : : /*
2076 : : * Taint values can only be increased
2077 : : * This means we can safely use a temporary.
2078 : : */
2079 : 0 : static int proc_taint(struct ctl_table *table, int write,
2080 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2081 : : {
2082 : : struct ctl_table t;
2083 : 2 : unsigned long tmptaint = get_taint();
2084 : : int err;
2085 : :
2086 [ - + ][ # # ]: 2 : if (write && !capable(CAP_SYS_ADMIN))
2087 : : return -EPERM;
2088 : :
2089 : 2 : t = *table;
2090 : 2 : t.data = &tmptaint;
2091 : : err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos);
2092 [ + - ]: 2 : if (err < 0)
2093 : : return err;
2094 : :
2095 [ - + ]: 2 : if (write) {
2096 : : /*
2097 : : * Poor man's atomic or. Not worth adding a primitive
2098 : : * to everyone's atomic.h for this
2099 : : */
2100 : : int i;
2101 [ # # ][ # # ]: 0 : for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
2102 [ # # ]: 0 : if ((tmptaint >> i) & 1)
2103 : 0 : add_taint(i, LOCKDEP_STILL_OK);
2104 : : }
2105 : : }
2106 : :
2107 : 2 : return err;
2108 : : }
2109 : :
2110 : : #ifdef CONFIG_PRINTK
2111 : 0 : static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
2112 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2113 : : {
2114 [ - + ][ # # ]: 4 : if (write && !capable(CAP_SYS_ADMIN))
2115 : : return -EPERM;
2116 : :
2117 : 4 : return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
2118 : : }
2119 : : #endif
2120 : :
2121 : : struct do_proc_dointvec_minmax_conv_param {
2122 : : int *min;
2123 : : int *max;
2124 : : };
2125 : :
2126 : 0 : static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp,
2127 : : int *valp,
2128 : : int write, void *data)
2129 : : {
2130 : : struct do_proc_dointvec_minmax_conv_param *param = data;
2131 [ + + ]: 671 : if (write) {
2132 [ - + ]: 81 : int val = *negp ? -*lvalp : *lvalp;
2133 [ + - ][ + ]: 81 : if ((param->min && *param->min > val) ||
[ + + ]
2134 [ + - ]: 10 : (param->max && *param->max < val))
2135 : : return -EINVAL;
2136 : 81 : *valp = val;
2137 : : } else {
2138 : 590 : int val = *valp;
2139 [ - + ]: 590 : if (val < 0) {
2140 : 0 : *negp = true;
2141 : 0 : *lvalp = (unsigned long)-val;
2142 : : } else {
2143 : 590 : *negp = false;
2144 : 590 : *lvalp = (unsigned long)val;
2145 : : }
2146 : : }
2147 : : return 0;
2148 : : }
2149 : :
2150 : : /**
2151 : : * proc_dointvec_minmax - read a vector of integers with min/max values
2152 : : * @table: the sysctl table
2153 : : * @write: %TRUE if this is a write to the sysctl file
2154 : : * @buffer: the user buffer
2155 : : * @lenp: the size of the user buffer
2156 : : * @ppos: file position
2157 : : *
2158 : : * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2159 : : * values from/to the user buffer, treated as an ASCII string.
2160 : : *
2161 : : * This routine will ensure the values are within the range specified by
2162 : : * table->extra1 (min) and table->extra2 (max).
2163 : : *
2164 : : * Returns 0 on success.
2165 : : */
2166 : 0 : int proc_dointvec_minmax(struct ctl_table *table, int write,
2167 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2168 : : {
2169 : 1772 : struct do_proc_dointvec_minmax_conv_param param = {
2170 : 886 : .min = (int *) table->extra1,
2171 : 886 : .max = (int *) table->extra2,
2172 : : };
2173 : 886 : return do_proc_dointvec(table, write, buffer, lenp, ppos,
2174 : : do_proc_dointvec_minmax_conv, ¶m);
2175 : : }
2176 : :
2177 : 0 : static void validate_coredump_safety(void)
2178 : : {
2179 : : #ifdef CONFIG_COREDUMP
2180 [ - + ][ # # ]: 4 : if (suid_dumpable == SUID_DUMP_ROOT &&
2181 [ # # ]: 0 : core_pattern[0] != '/' && core_pattern[0] != '|') {
2182 : 0 : printk(KERN_WARNING "Unsafe core_pattern used with "\
2183 : : "suid_dumpable=2. Pipe handler or fully qualified "\
2184 : : "core dump path required.\n");
2185 : : }
2186 : : #endif
2187 : 0 : }
2188 : :
2189 : 0 : static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
2190 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2191 : : {
2192 : 2 : int error = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
2193 [ + - ]: 2 : if (!error)
2194 : 2 : validate_coredump_safety();
2195 : 0 : return error;
2196 : : }
2197 : :
2198 : : #ifdef CONFIG_COREDUMP
2199 : 0 : static int proc_dostring_coredump(struct ctl_table *table, int write,
2200 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2201 : : {
2202 : : int error = proc_dostring(table, write, buffer, lenp, ppos);
2203 [ + - ]: 2 : if (!error)
2204 : 2 : validate_coredump_safety();
2205 : 0 : return error;
2206 : : }
2207 : : #endif
2208 : :
2209 : 0 : static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write,
2210 : : void __user *buffer,
2211 : : size_t *lenp, loff_t *ppos,
2212 : : unsigned long convmul,
2213 : : unsigned long convdiv)
2214 : : {
2215 : : unsigned long *i, *min, *max;
2216 : : int vleft, first = 1, err = 0;
2217 : : unsigned long page = 0;
2218 : : size_t left;
2219 : : char *kbuf;
2220 : :
2221 [ + - ][ + - ]: 89 : if (!data || !table->maxlen || !*lenp || (*ppos && !write)) {
[ + - ][ + + ]
[ + - ]
2222 : 44 : *lenp = 0;
2223 : 44 : return 0;
2224 : : }
2225 : :
2226 : : i = (unsigned long *) data;
2227 : 45 : min = (unsigned long *) table->extra1;
2228 : 45 : max = (unsigned long *) table->extra2;
2229 : 45 : vleft = table->maxlen / sizeof(unsigned long);
2230 : 45 : left = *lenp;
2231 : :
2232 [ - + ]: 45 : if (write) {
2233 [ # # ]: 0 : if (left > PAGE_SIZE - 1)
2234 : 0 : left = PAGE_SIZE - 1;
2235 : 0 : page = __get_free_page(GFP_TEMPORARY);
2236 : 0 : kbuf = (char *) page;
2237 [ # # ]: 0 : if (!kbuf)
2238 : : return -ENOMEM;
2239 [ # # ]: 0 : if (copy_from_user(kbuf, buffer, left)) {
2240 : : err = -EFAULT;
2241 : : goto free;
2242 : : }
2243 : 45 : kbuf[left] = 0;
2244 : : }
2245 : :
2246 [ + - ][ + + ]: 110 : for (; left && vleft--; i++, first = 0) {
2247 : : unsigned long val;
2248 : :
2249 [ - + ]: 65 : if (write) {
2250 : : bool neg;
2251 : :
2252 : 0 : left -= proc_skip_spaces(&kbuf);
2253 : :
2254 : 0 : err = proc_get_long(&kbuf, &left, &val, &neg,
2255 : : proc_wspace_sep,
2256 : : sizeof(proc_wspace_sep), NULL);
2257 [ # # ]: 89 : if (err)
2258 : : break;
2259 [ # # ]: 0 : if (neg)
2260 : 0 : continue;
2261 [ # # ][ # # ]: 0 : if ((min && val < *min) || (max && val > *max))
[ # # ][ # # ]
2262 : 0 : continue;
2263 : 0 : *i = val;
2264 : : } else {
2265 : 65 : val = convdiv * (*i) / convmul;
2266 [ + + ]: 65 : if (!first) {
2267 : 20 : err = proc_put_char(&buffer, &left, '\t');
2268 [ + - ]: 20 : if (err)
2269 : : break;
2270 : : }
2271 : 65 : err = proc_put_long(&buffer, &left, val, false);
2272 [ + - ]: 65 : if (err)
2273 : : break;
2274 : : }
2275 : : }
2276 : :
2277 [ + - ][ + - ]: 45 : if (!write && !first && left && !err)
[ + - ]
2278 : 45 : err = proc_put_char(&buffer, &left, '\n');
2279 [ - + ]: 45 : if (write && !err)
2280 : 0 : left -= proc_skip_spaces(&kbuf);
2281 : : free:
2282 [ - + ]: 45 : if (write) {
2283 : 0 : free_page(page);
2284 [ # # ]: 0 : if (first)
2285 [ # # ]: 0 : return err ? : -EINVAL;
2286 : : }
2287 : 45 : *lenp -= left;
2288 : 45 : *ppos += *lenp;
2289 : 45 : return err;
2290 : : }
2291 : :
2292 : : static int do_proc_doulongvec_minmax(struct ctl_table *table, int write,
2293 : : void __user *buffer,
2294 : : size_t *lenp, loff_t *ppos,
2295 : : unsigned long convmul,
2296 : : unsigned long convdiv)
2297 : : {
2298 : 89 : return __do_proc_doulongvec_minmax(table->data, table, write,
2299 : : buffer, lenp, ppos, convmul, convdiv);
2300 : : }
2301 : :
2302 : : /**
2303 : : * proc_doulongvec_minmax - read a vector of long integers with min/max values
2304 : : * @table: the sysctl table
2305 : : * @write: %TRUE if this is a write to the sysctl file
2306 : : * @buffer: the user buffer
2307 : : * @lenp: the size of the user buffer
2308 : : * @ppos: file position
2309 : : *
2310 : : * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
2311 : : * values from/to the user buffer, treated as an ASCII string.
2312 : : *
2313 : : * This routine will ensure the values are within the range specified by
2314 : : * table->extra1 (min) and table->extra2 (max).
2315 : : *
2316 : : * Returns 0 on success.
2317 : : */
2318 : 0 : int proc_doulongvec_minmax(struct ctl_table *table, int write,
2319 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2320 : : {
2321 : 87 : return do_proc_doulongvec_minmax(table, write, buffer, lenp, ppos, 1l, 1l);
2322 : : }
2323 : :
2324 : : /**
2325 : : * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values
2326 : : * @table: the sysctl table
2327 : : * @write: %TRUE if this is a write to the sysctl file
2328 : : * @buffer: the user buffer
2329 : : * @lenp: the size of the user buffer
2330 : : * @ppos: file position
2331 : : *
2332 : : * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
2333 : : * values from/to the user buffer, treated as an ASCII string. The values
2334 : : * are treated as milliseconds, and converted to jiffies when they are stored.
2335 : : *
2336 : : * This routine will ensure the values are within the range specified by
2337 : : * table->extra1 (min) and table->extra2 (max).
2338 : : *
2339 : : * Returns 0 on success.
2340 : : */
2341 : 0 : int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
2342 : : void __user *buffer,
2343 : : size_t *lenp, loff_t *ppos)
2344 : : {
2345 : 0 : return do_proc_doulongvec_minmax(table, write, buffer,
2346 : : lenp, ppos, HZ, 1000l);
2347 : : }
2348 : :
2349 : :
2350 : 0 : static int do_proc_dointvec_jiffies_conv(bool *negp, unsigned long *lvalp,
2351 : : int *valp,
2352 : : int write, void *data)
2353 : : {
2354 [ - + ]: 59 : if (write) {
2355 [ # # ]: 0 : if (*lvalp > LONG_MAX / HZ)
2356 : : return 1;
2357 [ # # ]: 59 : *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ);
2358 : : } else {
2359 : 59 : int val = *valp;
2360 : : unsigned long lval;
2361 [ - + ]: 59 : if (val < 0) {
2362 : 0 : *negp = true;
2363 : 0 : lval = (unsigned long)-val;
2364 : : } else {
2365 : 59 : *negp = false;
2366 : 59 : lval = (unsigned long)val;
2367 : : }
2368 : 59 : *lvalp = lval / HZ;
2369 : : }
2370 : : return 0;
2371 : : }
2372 : :
2373 : 0 : static int do_proc_dointvec_userhz_jiffies_conv(bool *negp, unsigned long *lvalp,
2374 : : int *valp,
2375 : : int write, void *data)
2376 : : {
2377 [ - + ]: 28 : if (write) {
2378 : : if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ)
2379 : : return 1;
2380 [ # # ]: 0 : *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp);
2381 : : } else {
2382 : 28 : int val = *valp;
2383 : : unsigned long lval;
2384 [ - + ]: 28 : if (val < 0) {
2385 : 0 : *negp = true;
2386 : 0 : lval = (unsigned long)-val;
2387 : : } else {
2388 : 28 : *negp = false;
2389 : 28 : lval = (unsigned long)val;
2390 : : }
2391 : 28 : *lvalp = jiffies_to_clock_t(lval);
2392 : : }
2393 : : return 0;
2394 : : }
2395 : :
2396 : 0 : static int do_proc_dointvec_ms_jiffies_conv(bool *negp, unsigned long *lvalp,
2397 : : int *valp,
2398 : : int write, void *data)
2399 : : {
2400 [ - + ]: 30 : if (write) {
2401 [ # # ]: 0 : unsigned long jif = msecs_to_jiffies(*negp ? -*lvalp : *lvalp);
2402 : :
2403 [ # # ]: 0 : if (jif > INT_MAX)
2404 : : return 1;
2405 : 0 : *valp = (int)jif;
2406 : : } else {
2407 : 30 : int val = *valp;
2408 : : unsigned long lval;
2409 [ - + ]: 30 : if (val < 0) {
2410 : 0 : *negp = true;
2411 : 0 : lval = (unsigned long)-val;
2412 : : } else {
2413 : 30 : *negp = false;
2414 : 30 : lval = (unsigned long)val;
2415 : : }
2416 : 30 : *lvalp = jiffies_to_msecs(lval);
2417 : : }
2418 : : return 0;
2419 : : }
2420 : :
2421 : : /**
2422 : : * proc_dointvec_jiffies - read a vector of integers as seconds
2423 : : * @table: the sysctl table
2424 : : * @write: %TRUE if this is a write to the sysctl file
2425 : : * @buffer: the user buffer
2426 : : * @lenp: the size of the user buffer
2427 : : * @ppos: file position
2428 : : *
2429 : : * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2430 : : * values from/to the user buffer, treated as an ASCII string.
2431 : : * The values read are assumed to be in seconds, and are converted into
2432 : : * jiffies.
2433 : : *
2434 : : * Returns 0 on success.
2435 : : */
2436 : 0 : int proc_dointvec_jiffies(struct ctl_table *table, int write,
2437 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2438 : : {
2439 : 118 : return do_proc_dointvec(table,write,buffer,lenp,ppos,
2440 : : do_proc_dointvec_jiffies_conv,NULL);
2441 : : }
2442 : :
2443 : : /**
2444 : : * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds
2445 : : * @table: the sysctl table
2446 : : * @write: %TRUE if this is a write to the sysctl file
2447 : : * @buffer: the user buffer
2448 : : * @lenp: the size of the user buffer
2449 : : * @ppos: pointer to the file position
2450 : : *
2451 : : * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2452 : : * values from/to the user buffer, treated as an ASCII string.
2453 : : * The values read are assumed to be in 1/USER_HZ seconds, and
2454 : : * are converted into jiffies.
2455 : : *
2456 : : * Returns 0 on success.
2457 : : */
2458 : 0 : int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write,
2459 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2460 : : {
2461 : 56 : return do_proc_dointvec(table,write,buffer,lenp,ppos,
2462 : : do_proc_dointvec_userhz_jiffies_conv,NULL);
2463 : : }
2464 : :
2465 : : /**
2466 : : * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds
2467 : : * @table: the sysctl table
2468 : : * @write: %TRUE if this is a write to the sysctl file
2469 : : * @buffer: the user buffer
2470 : : * @lenp: the size of the user buffer
2471 : : * @ppos: file position
2472 : : * @ppos: the current position in the file
2473 : : *
2474 : : * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
2475 : : * values from/to the user buffer, treated as an ASCII string.
2476 : : * The values read are assumed to be in 1/1000 seconds, and
2477 : : * are converted into jiffies.
2478 : : *
2479 : : * Returns 0 on success.
2480 : : */
2481 : 0 : int proc_dointvec_ms_jiffies(struct ctl_table *table, int write,
2482 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2483 : : {
2484 : 60 : return do_proc_dointvec(table, write, buffer, lenp, ppos,
2485 : : do_proc_dointvec_ms_jiffies_conv, NULL);
2486 : : }
2487 : :
2488 : 0 : static int proc_do_cad_pid(struct ctl_table *table, int write,
2489 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2490 : : {
2491 : : struct pid *new_pid;
2492 : : pid_t tmp;
2493 : : int r;
2494 : :
2495 : 2 : tmp = pid_vnr(cad_pid);
2496 : :
2497 : 2 : r = __do_proc_dointvec(&tmp, table, write, buffer,
2498 : : lenp, ppos, NULL, NULL);
2499 [ - + ]: 2 : if (r || !write)
2500 : : return r;
2501 : :
2502 : 0 : new_pid = find_get_pid(tmp);
2503 [ # # ]: 0 : if (!new_pid)
2504 : : return -ESRCH;
2505 : :
2506 : 0 : put_pid(xchg(&cad_pid, new_pid));
2507 : 0 : return 0;
2508 : : }
2509 : :
2510 : : /**
2511 : : * proc_do_large_bitmap - read/write from/to a large bitmap
2512 : : * @table: the sysctl table
2513 : : * @write: %TRUE if this is a write to the sysctl file
2514 : : * @buffer: the user buffer
2515 : : * @lenp: the size of the user buffer
2516 : : * @ppos: file position
2517 : : *
2518 : : * The bitmap is stored at table->data and the bitmap length (in bits)
2519 : : * in table->maxlen.
2520 : : *
2521 : : * We use a range comma separated format (e.g. 1,3-4,10-10) so that
2522 : : * large bitmaps may be represented in a compact manner. Writing into
2523 : : * the file will clear the bitmap then update it with the given input.
2524 : : *
2525 : : * Returns 0 on success.
2526 : : */
2527 : 0 : int proc_do_large_bitmap(struct ctl_table *table, int write,
2528 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2529 : : {
2530 : : int err = 0;
2531 : : bool first = 1;
2532 : 2 : size_t left = *lenp;
2533 : 2 : unsigned long bitmap_len = table->maxlen;
2534 : 2 : unsigned long *bitmap = (unsigned long *) table->data;
2535 : : unsigned long *tmp_bitmap = NULL;
2536 : 2 : char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c;
2537 : :
2538 [ + - ][ + + ]: 2 : if (!bitmap_len || !left || (*ppos && !write)) {
[ + - ]
2539 : 1 : *lenp = 0;
2540 : 1 : return 0;
2541 : : }
2542 : :
2543 [ + - ]: 1 : if (write) {
2544 : : unsigned long page = 0;
2545 : : char *kbuf;
2546 : :
2547 [ # # ]: 0 : if (left > PAGE_SIZE - 1)
2548 : 0 : left = PAGE_SIZE - 1;
2549 : :
2550 : 0 : page = __get_free_page(GFP_TEMPORARY);
2551 : 0 : kbuf = (char *) page;
2552 [ # # ]: 0 : if (!kbuf)
2553 : 0 : return -ENOMEM;
2554 [ - + ]: 2 : if (copy_from_user(kbuf, buffer, left)) {
2555 : 0 : free_page(page);
2556 : 0 : return -EFAULT;
2557 : : }
2558 : 0 : kbuf[left] = 0;
2559 : :
2560 : 0 : tmp_bitmap = kzalloc(BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long),
2561 : : GFP_KERNEL);
2562 [ # # ]: 0 : if (!tmp_bitmap) {
2563 : 0 : free_page(page);
2564 : 0 : return -ENOMEM;
2565 : : }
2566 : : proc_skip_char(&kbuf, &left, '\n');
2567 [ # # ][ # # ]: 0 : while (!err && left) {
2568 : : unsigned long val_a, val_b;
2569 : : bool neg;
2570 : :
2571 : 0 : err = proc_get_long(&kbuf, &left, &val_a, &neg, tr_a,
2572 : : sizeof(tr_a), &c);
2573 [ # # ]: 0 : if (err)
2574 : : break;
2575 [ # # ][ # # ]: 0 : if (val_a >= bitmap_len || neg) {
2576 : : err = -EINVAL;
2577 : : break;
2578 : : }
2579 : :
2580 : 0 : val_b = val_a;
2581 [ # # ]: 0 : if (left) {
2582 : 0 : kbuf++;
2583 : 0 : left--;
2584 : : }
2585 : :
2586 [ # # ]: 0 : if (c == '-') {
2587 : 0 : err = proc_get_long(&kbuf, &left, &val_b,
2588 : : &neg, tr_b, sizeof(tr_b),
2589 : : &c);
2590 [ # # ]: 0 : if (err)
2591 : : break;
2592 [ # # ][ # # ]: 0 : if (val_b >= bitmap_len || neg ||
[ # # ]
2593 : 0 : val_a > val_b) {
2594 : : err = -EINVAL;
2595 : : break;
2596 : : }
2597 [ # # ]: 0 : if (left) {
2598 : 0 : kbuf++;
2599 : 0 : left--;
2600 : : }
2601 : : }
2602 : :
2603 : 0 : bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1);
2604 : : first = 0;
2605 : : proc_skip_char(&kbuf, &left, '\n');
2606 : : }
2607 : 0 : free_page(page);
2608 : : } else {
2609 : : unsigned long bit_a, bit_b = 0;
2610 : :
2611 [ + - ]: 1 : while (left) {
2612 : 1 : bit_a = find_next_bit(bitmap, bitmap_len, bit_b);
2613 [ - + ]: 1 : if (bit_a >= bitmap_len)
2614 : : break;
2615 : 0 : bit_b = find_next_zero_bit(bitmap, bitmap_len,
2616 : 0 : bit_a + 1) - 1;
2617 : :
2618 [ # # ]: 0 : if (!first) {
2619 : 0 : err = proc_put_char(&buffer, &left, ',');
2620 [ # # ]: 0 : if (err)
2621 : : break;
2622 : : }
2623 : 0 : err = proc_put_long(&buffer, &left, bit_a, false);
2624 [ # # ]: 0 : if (err)
2625 : : break;
2626 [ # # ]: 0 : if (bit_a != bit_b) {
2627 : 0 : err = proc_put_char(&buffer, &left, '-');
2628 [ # # ]: 0 : if (err)
2629 : : break;
2630 : 0 : err = proc_put_long(&buffer, &left, bit_b, false);
2631 [ # # ]: 0 : if (err)
2632 : : break;
2633 : : }
2634 : :
2635 : 0 : first = 0; bit_b++;
2636 : : }
2637 [ + - ]: 1 : if (!err)
2638 : 1 : err = proc_put_char(&buffer, &left, '\n');
2639 : : }
2640 : :
2641 [ + - ]: 1 : if (!err) {
2642 [ - + ]: 1 : if (write) {
2643 [ # # ]: 0 : if (*ppos)
2644 : : bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len);
2645 : : else
2646 : : bitmap_copy(bitmap, tmp_bitmap, bitmap_len);
2647 : : }
2648 : 1 : kfree(tmp_bitmap);
2649 : 1 : *lenp -= left;
2650 : 1 : *ppos += *lenp;
2651 : 1 : return 0;
2652 : : } else {
2653 : 0 : kfree(tmp_bitmap);
2654 : 0 : return err;
2655 : : }
2656 : : }
2657 : :
2658 : : #else /* CONFIG_PROC_SYSCTL */
2659 : :
2660 : : int proc_dostring(struct ctl_table *table, int write,
2661 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2662 : : {
2663 : : return -ENOSYS;
2664 : : }
2665 : :
2666 : : int proc_dointvec(struct ctl_table *table, int write,
2667 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2668 : : {
2669 : : return -ENOSYS;
2670 : : }
2671 : :
2672 : : int proc_dointvec_minmax(struct ctl_table *table, int write,
2673 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2674 : : {
2675 : : return -ENOSYS;
2676 : : }
2677 : :
2678 : : int proc_dointvec_jiffies(struct ctl_table *table, int write,
2679 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2680 : : {
2681 : : return -ENOSYS;
2682 : : }
2683 : :
2684 : : int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write,
2685 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2686 : : {
2687 : : return -ENOSYS;
2688 : : }
2689 : :
2690 : : int proc_dointvec_ms_jiffies(struct ctl_table *table, int write,
2691 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2692 : : {
2693 : : return -ENOSYS;
2694 : : }
2695 : :
2696 : : int proc_doulongvec_minmax(struct ctl_table *table, int write,
2697 : : void __user *buffer, size_t *lenp, loff_t *ppos)
2698 : : {
2699 : : return -ENOSYS;
2700 : : }
2701 : :
2702 : : int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
2703 : : void __user *buffer,
2704 : : size_t *lenp, loff_t *ppos)
2705 : : {
2706 : : return -ENOSYS;
2707 : : }
2708 : :
2709 : :
2710 : : #endif /* CONFIG_PROC_SYSCTL */
2711 : :
2712 : : /*
2713 : : * No sense putting this after each symbol definition, twice,
2714 : : * exception granted :-)
2715 : : */
2716 : : EXPORT_SYMBOL(proc_dointvec);
2717 : : EXPORT_SYMBOL(proc_dointvec_jiffies);
2718 : : EXPORT_SYMBOL(proc_dointvec_minmax);
2719 : : EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
2720 : : EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
2721 : : EXPORT_SYMBOL(proc_dostring);
2722 : : EXPORT_SYMBOL(proc_doulongvec_minmax);
2723 : : EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
|