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