Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * sysctl.c: General linux system control interface
4 */
5
6#include <linux/sysctl.h>
7#include <linux/bitmap.h>
8#include <linux/proc_fs.h>
9#include <linux/ctype.h>
10#include <linux/init.h>
11#include <linux/kernel.h>
12#include <linux/kobject.h>
13#include <linux/highuid.h>
14#include <linux/writeback.h>
15#include <linux/initrd.h>
16#include <linux/limits.h>
17#include <linux/syscalls.h>
18#include <linux/capability.h>
19
20#include "../lib/kstrtox.h"
21
22#include <linux/uaccess.h>
23#include <asm/processor.h>
24
25/* shared constants to be used in various sysctls */
26const int sysctl_vals[] = { 0, 1, 2, 3, 4, 100, 200, 1000, 3000, INT_MAX, 65535, -1 };
27EXPORT_SYMBOL(sysctl_vals);
28
29const unsigned long sysctl_long_vals[] = { 0, 1, LONG_MAX };
30EXPORT_SYMBOL_GPL(sysctl_long_vals);
31
32#if defined(CONFIG_SYSCTL)
33
34/* Constants used for minimum and maximum */
35static const int ngroups_max = NGROUPS_MAX;
36static const int cap_last_cap = CAP_LAST_CAP;
37
38#ifdef CONFIG_PROC_SYSCTL
39
40/**
41 * enum sysctl_writes_mode - supported sysctl write modes
42 *
43 * @SYSCTL_WRITES_LEGACY: each write syscall must fully contain the sysctl value
44 * to be written, and multiple writes on the same sysctl file descriptor
45 * will rewrite the sysctl value, regardless of file position. No warning
46 * is issued when the initial position is not 0.
47 * @SYSCTL_WRITES_WARN: same as above but warn when the initial file position is
48 * not 0.
49 * @SYSCTL_WRITES_STRICT: writes to numeric sysctl entries must always be at
50 * file position 0 and the value must be fully contained in the buffer
51 * sent to the write syscall. If dealing with strings respect the file
52 * position, but restrict this to the max length of the buffer, anything
53 * passed the max length will be ignored. Multiple writes will append
54 * to the buffer.
55 *
56 * These write modes control how current file position affects the behavior of
57 * updating internal kernel (SYSCTL_USER_TO_KERN) sysctl values through the proc
58 * interface on each write.
59 */
60enum sysctl_writes_mode {
61 SYSCTL_WRITES_LEGACY = -1,
62 SYSCTL_WRITES_WARN = 0,
63 SYSCTL_WRITES_STRICT = 1,
64};
65
66static enum sysctl_writes_mode sysctl_writes_strict = SYSCTL_WRITES_STRICT;
67#endif /* CONFIG_PROC_SYSCTL */
68#endif /* CONFIG_SYSCTL */
69
70/*
71 * /proc/sys support
72 */
73
74#ifdef CONFIG_PROC_SYSCTL
75
76static int _proc_do_string(char *data, int maxlen, int dir,
77 char *buffer, size_t *lenp, loff_t *ppos)
78{
79 size_t len;
80 char c, *p;
81
82 if (!data || !maxlen || !*lenp) {
83 *lenp = 0;
84 return 0;
85 }
86
87 if (SYSCTL_USER_TO_KERN(dir)) {
88 if (sysctl_writes_strict == SYSCTL_WRITES_STRICT) {
89 /* Only continue writes not past the end of buffer. */
90 len = strlen(data);
91 if (len > maxlen - 1)
92 len = maxlen - 1;
93
94 if (*ppos > len)
95 return 0;
96 len = *ppos;
97 } else {
98 /* Start writing from beginning of buffer. */
99 len = 0;
100 }
101
102 *ppos += *lenp;
103 p = buffer;
104 while ((p - buffer) < *lenp && len < maxlen - 1) {
105 c = *(p++);
106 if (c == 0 || c == '\n')
107 break;
108 data[len++] = c;
109 }
110 data[len] = 0;
111 } else {
112 len = strlen(data);
113 if (len > maxlen)
114 len = maxlen;
115
116 if (*ppos > len) {
117 *lenp = 0;
118 return 0;
119 }
120
121 data += *ppos;
122 len -= *ppos;
123
124 if (len > *lenp)
125 len = *lenp;
126 if (len)
127 memcpy(buffer, data, len);
128 if (len < *lenp) {
129 buffer[len] = '\n';
130 len++;
131 }
132 *lenp = len;
133 *ppos += len;
134 }
135 return 0;
136}
137
138static void warn_sysctl_write(const struct ctl_table *table)
139{
140 pr_warn_once("%s wrote to %s when file position was not 0!\n"
141 "This will not be supported in the future. To silence this\n"
142 "warning, set kernel.sysctl_writes_strict = -1\n",
143 current->comm, table->procname);
144}
145
146/**
147 * proc_first_pos_non_zero_ignore - check if first position is allowed
148 * @ppos: file position
149 * @table: the sysctl table
150 *
151 * Returns true if the first position is non-zero and the sysctl_writes_strict
152 * mode indicates this is not allowed for numeric input types. String proc
153 * handlers can ignore the return value.
154 */
155static bool proc_first_pos_non_zero_ignore(loff_t *ppos,
156 const struct ctl_table *table)
157{
158 if (!*ppos)
159 return false;
160
161 switch (sysctl_writes_strict) {
162 case SYSCTL_WRITES_STRICT:
163 return true;
164 case SYSCTL_WRITES_WARN:
165 warn_sysctl_write(table);
166 return false;
167 default:
168 return false;
169 }
170}
171
172/**
173 * proc_dostring - read a string sysctl
174 * @table: the sysctl table
175 * @dir: %TRUE if this is a write to the sysctl file
176 * @buffer: the user buffer
177 * @lenp: the size of the user buffer
178 * @ppos: file position
179 *
180 * Reads/writes a string from/to the user buffer. If the kernel
181 * buffer provided is not large enough to hold the string, the
182 * string is truncated. The copied string is %NULL-terminated.
183 * If the string is being read by the user process, it is copied
184 * and a newline '\n' is added. It is truncated if the buffer is
185 * not large enough.
186 *
187 * Returns 0 on success.
188 */
189int proc_dostring(const struct ctl_table *table, int dir,
190 void *buffer, size_t *lenp, loff_t *ppos)
191{
192 if (SYSCTL_USER_TO_KERN(dir))
193 proc_first_pos_non_zero_ignore(ppos, table);
194
195 return _proc_do_string(table->data, table->maxlen, dir, buffer, lenp,
196 ppos);
197}
198
199static void proc_skip_spaces(char **buf, size_t *size)
200{
201 while (*size) {
202 if (!isspace(**buf))
203 break;
204 (*size)--;
205 (*buf)++;
206 }
207}
208
209static void proc_skip_char(char **buf, size_t *size, const char v)
210{
211 while (*size) {
212 if (**buf != v)
213 break;
214 (*size)--;
215 (*buf)++;
216 }
217}
218
219/**
220 * strtoul_lenient - parse an ASCII formatted integer from a buffer and only
221 * fail on overflow
222 *
223 * @cp: kernel buffer containing the string to parse
224 * @endp: pointer to store the trailing characters
225 * @base: the base to use
226 * @res: where the parsed integer will be stored
227 *
228 * In case of success 0 is returned and @res will contain the parsed integer,
229 * @endp will hold any trailing characters.
230 * This function will fail the parse on overflow. If there wasn't an overflow
231 * the function will defer the decision what characters count as invalid to the
232 * caller.
233 */
234static int strtoul_lenient(const char *cp, char **endp, unsigned int base,
235 unsigned long *res)
236{
237 unsigned long long result;
238 unsigned int rv;
239
240 cp = _parse_integer_fixup_radix(cp, &base);
241 rv = _parse_integer(cp, base, &result);
242 if ((rv & KSTRTOX_OVERFLOW) || (result != (unsigned long)result))
243 return -ERANGE;
244
245 cp += rv;
246
247 if (endp)
248 *endp = (char *)cp;
249
250 *res = (unsigned long)result;
251 return 0;
252}
253
254#define TMPBUFLEN 22
255/**
256 * proc_get_long - reads an ASCII formatted integer from a user buffer
257 *
258 * @buf: a kernel buffer
259 * @size: size of the kernel buffer
260 * @val: this is where the number will be stored
261 * @neg: set to %TRUE if number is negative
262 * @perm_tr: a vector which contains the allowed trailers
263 * @perm_tr_len: size of the perm_tr vector
264 * @tr: pointer to store the trailer character
265 *
266 * In case of success %0 is returned and @buf and @size are updated with
267 * the amount of bytes read. If @tr is non-NULL and a trailing
268 * character exists (size is non-zero after returning from this
269 * function), @tr is updated with the trailing character.
270 */
271static int proc_get_long(char **buf, size_t *size,
272 unsigned long *val, bool *neg,
273 const char *perm_tr, unsigned perm_tr_len, char *tr)
274{
275 char *p, tmp[TMPBUFLEN];
276 ssize_t len = *size;
277
278 if (len <= 0)
279 return -EINVAL;
280
281 if (len > TMPBUFLEN - 1)
282 len = TMPBUFLEN - 1;
283
284 memcpy(tmp, *buf, len);
285
286 tmp[len] = 0;
287 p = tmp;
288 if (*p == '-' && *size > 1) {
289 *neg = true;
290 p++;
291 } else
292 *neg = false;
293 if (!isdigit(*p))
294 return -EINVAL;
295
296 if (strtoul_lenient(p, &p, 0, val))
297 return -EINVAL;
298
299 len = p - tmp;
300
301 /* We don't know if the next char is whitespace thus we may accept
302 * invalid integers (e.g. 1234...a) or two integers instead of one
303 * (e.g. 123...1). So lets not allow such large numbers. */
304 if (len == TMPBUFLEN - 1)
305 return -EINVAL;
306
307 if (len < *size && perm_tr_len && !memchr(perm_tr, *p, perm_tr_len))
308 return -EINVAL;
309
310 if (tr && (len < *size))
311 *tr = *p;
312
313 *buf += len;
314 *size -= len;
315
316 return 0;
317}
318
319/**
320 * proc_put_long - converts an integer to a decimal ASCII formatted string
321 *
322 * @buf: the user buffer
323 * @size: the size of the user buffer
324 * @val: the integer to be converted
325 * @neg: sign of the number, %TRUE for negative
326 *
327 * In case of success @buf and @size are updated with the amount of bytes
328 * written.
329 */
330static void proc_put_long(void **buf, size_t *size, unsigned long val, bool neg)
331{
332 int len;
333 char tmp[TMPBUFLEN], *p = tmp;
334
335 sprintf(p, "%s%lu", neg ? "-" : "", val);
336 len = strlen(tmp);
337 if (len > *size)
338 len = *size;
339 memcpy(*buf, tmp, len);
340 *size -= len;
341 *buf += len;
342}
343#undef TMPBUFLEN
344
345static void proc_put_char(void **buf, size_t *size, char c)
346{
347 if (*size) {
348 char **buffer = (char **)buf;
349 **buffer = c;
350
351 (*size)--;
352 (*buffer)++;
353 *buf = *buffer;
354 }
355}
356
357/**
358 * proc_uint_u2k_conv_uop - Assign user value to a kernel pointer
359 *
360 * @u_ptr: pointer to user space variable
361 * @k_ptr: pointer to kernel variable
362 * @u_ptr_op: execute this function before assigning to k_ptr
363 *
364 * Uses WRITE_ONCE to assign value to k_ptr. Executes u_ptr_op if
365 * not NULL. Check that the values are less than UINT_MAX to avoid
366 * having to support wrap around from userspace.
367 *
368 * returns 0 on success.
369 */
370int proc_uint_u2k_conv_uop(const ulong *u_ptr, uint *k_ptr,
371 ulong (*u_ptr_op)(const ulong))
372{
373 ulong u = u_ptr_op ? u_ptr_op(*u_ptr) : *u_ptr;
374
375 if (u > UINT_MAX)
376 return -EINVAL;
377 WRITE_ONCE(*k_ptr, u);
378 return 0;
379}
380
381/**
382 * proc_uint_k2u_conv - Assign kernel value to a user space pointer
383 *
384 * @u_ptr: pointer to user space variable
385 * @k_ptr: pointer to kernel variable
386 *
387 * Uses READ_ONCE to assign value to u_ptr.
388 *
389 * returns 0 on success.
390 */
391int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr)
392{
393 uint val = READ_ONCE(*k_ptr);
394 *u_ptr = (ulong)val;
395 return 0;
396}
397
398/**
399 * proc_uint_conv - Change user or kernel pointer based on direction
400 *
401 * @u_ptr: pointer to user variable
402 * @k_ptr: pointer to kernel variable
403 * @dir: %TRUE if this is a write to the sysctl file
404 * @tbl: the sysctl table
405 * @k_ptr_range_check: Check range for k_ptr when %TRUE
406 * @user_to_kern: Callback used to assign value from user to kernel var
407 * @kern_to_user: Callback used to assign value from kernel to user var
408 *
409 * When direction is kernel to user, then the u_ptr is modified.
410 * When direction is user to kernel, then the k_ptr is modified.
411 *
412 * Returns 0 on success
413 */
414int proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir,
415 const struct ctl_table *tbl, bool k_ptr_range_check,
416 int (*user_to_kern)(const ulong *u_ptr, uint *k_ptr),
417 int (*kern_to_user)(ulong *u_ptr, const uint *k_ptr))
418{
419 if (SYSCTL_KERN_TO_USER(dir))
420 return kern_to_user(u_ptr, k_ptr);
421
422 if (k_ptr_range_check) {
423 uint tmp_k;
424 int ret;
425
426 if (!tbl)
427 return -EINVAL;
428 ret = user_to_kern(u_ptr, &tmp_k);
429 if (ret)
430 return ret;
431 if ((tbl->extra1 &&
432 *(uint *)tbl->extra1 > tmp_k) ||
433 (tbl->extra2 &&
434 *(uint *)tbl->extra2 < tmp_k))
435 return -ERANGE;
436 WRITE_ONCE(*k_ptr, tmp_k);
437 } else
438 return user_to_kern(u_ptr, k_ptr);
439 return 0;
440}
441
442static int proc_uint_u2k_conv(const ulong *u_ptr, uint *k_ptr)
443{
444 return proc_uint_u2k_conv_uop(u_ptr, k_ptr, NULL);
445}
446
447static int do_proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir,
448 const struct ctl_table *tbl)
449{
450 return proc_uint_conv(u_ptr, k_ptr, dir, tbl, false,
451 proc_uint_u2k_conv, proc_uint_k2u_conv);
452}
453
454static int do_proc_uint_conv_minmax(ulong *u_ptr, uint *k_ptr, int dir,
455 const struct ctl_table *tbl)
456{
457 return proc_uint_conv(u_ptr, k_ptr, dir, tbl, true,
458 proc_uint_u2k_conv, proc_uint_k2u_conv);
459}
460
461/**
462 * proc_int_k2u_conv_kop - Assign kernel value to a user space pointer
463 * @u_ptr: pointer to user space variable
464 * @k_ptr: pointer to kernel variable
465 * @negp: assigned %TRUE if the converted kernel value is negative;
466 * %FALSE otherweise
467 * @k_ptr_op: execute this function before assigning to u_ptr
468 *
469 * Uses READ_ONCE to get value from k_ptr. Executes k_ptr_op before assigning
470 * to u_ptr if not NULL. Does **not** check for overflow.
471 *
472 * Returns: 0 on success.
473 */
474int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp,
475 ulong (*k_ptr_op)(const ulong))
476{
477 int val = READ_ONCE(*k_ptr);
478
479 if (val < 0) {
480 *negp = true;
481 *u_ptr = k_ptr_op ? -k_ptr_op((ulong)val) : -(ulong)val;
482 } else {
483 *negp = false;
484 *u_ptr = k_ptr_op ? k_ptr_op((ulong)val) : (ulong) val;
485 }
486 return 0;
487}
488
489/**
490 * proc_int_u2k_conv_uop - Assign user value to a kernel pointer
491 * @u_ptr: pointer to user space variable
492 * @k_ptr: pointer to kernel variable
493 * @negp: If %TRUE, the converted user value is made negative.
494 * @u_ptr_op: execute this function before assigning to k_ptr
495 *
496 * Uses WRITE_ONCE to assign value to k_ptr. Executes u_ptr_op if
497 * not NULL. Check for overflow with UINT_MAX.
498 *
499 * Returns: 0 on success.
500 */
501int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp,
502 ulong (*u_ptr_op)(const ulong))
503{
504 ulong u = u_ptr_op ? u_ptr_op(*u_ptr) : *u_ptr;
505
506 if (*negp) {
507 if (u > (ulong) INT_MAX + 1)
508 return -EINVAL;
509 WRITE_ONCE(*k_ptr, -u);
510 } else {
511 if (u > (ulong) INT_MAX)
512 return -EINVAL;
513 WRITE_ONCE(*k_ptr, u);
514 }
515 return 0;
516}
517
518int proc_int_conv(bool *negp, ulong *u_ptr, int *k_ptr, int dir,
519 const struct ctl_table *tbl, bool k_ptr_range_check,
520 int (*user_to_kern)(const bool *negp, const ulong *u_ptr, int *k_ptr),
521 int (*kern_to_user)(bool *negp, ulong *u_ptr, const int *k_ptr))
522{
523 if (SYSCTL_KERN_TO_USER(dir))
524 return kern_to_user(negp, u_ptr, k_ptr);
525
526 if (k_ptr_range_check) {
527 int tmp_k, ret;
528
529 if (!tbl)
530 return -EINVAL;
531 ret = user_to_kern(negp, u_ptr, &tmp_k);
532 if (ret)
533 return ret;
534 if ((tbl->extra1 && *(int *)tbl->extra1 > tmp_k) ||
535 (tbl->extra2 && *(int *)tbl->extra2 < tmp_k))
536 return -EINVAL;
537 WRITE_ONCE(*k_ptr, tmp_k);
538 } else
539 return user_to_kern(negp, u_ptr, k_ptr);
540 return 0;
541}
542
543
544
545static int sysctl_user_to_kern_int_conv(const bool *negp, const ulong *u_ptr,
546 int *k_ptr)
547{
548 return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, NULL);
549}
550
551static int sysctl_kern_to_user_int_conv(bool *negp, ulong *u_ptr, const int *k_ptr)
552{
553 return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, NULL);
554}
555
556static int do_proc_int_conv(bool *negp, unsigned long *u_ptr, int *k_ptr,
557 int dir, const struct ctl_table *tbl)
558{
559 return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false,
560 sysctl_user_to_kern_int_conv,
561 sysctl_kern_to_user_int_conv);
562
563}
564
565static int do_proc_int_conv_minmax(bool *negp, unsigned long *u_ptr, int *k_ptr,
566 int dir, const struct ctl_table *tbl)
567{
568 return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, true,
569 sysctl_user_to_kern_int_conv,
570 sysctl_kern_to_user_int_conv);
571}
572
573static const char proc_wspace_sep[] = { ' ', '\t', '\n' };
574
575static int do_proc_dointvec(const struct ctl_table *table, int dir,
576 void *buffer, size_t *lenp, loff_t *ppos,
577 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
578 int dir, const struct ctl_table *table))
579{
580 int *i, vleft, first = 1, err = 0;
581 size_t left;
582 char *p;
583
584 if (!table->data || !table->maxlen || !*lenp ||
585 (*ppos && SYSCTL_KERN_TO_USER(dir))) {
586 *lenp = 0;
587 return 0;
588 }
589
590 i = (int *) table->data;
591 vleft = table->maxlen / sizeof(*i);
592 left = *lenp;
593
594 if (!conv)
595 conv = do_proc_int_conv;
596
597 if (SYSCTL_USER_TO_KERN(dir)) {
598 if (proc_first_pos_non_zero_ignore(ppos, table))
599 goto out;
600
601 if (left > PAGE_SIZE - 1)
602 left = PAGE_SIZE - 1;
603 p = buffer;
604 }
605
606 for (; left && vleft--; i++, first=0) {
607 unsigned long lval;
608 bool neg;
609
610 if (SYSCTL_USER_TO_KERN(dir)) {
611 proc_skip_spaces(&p, &left);
612
613 if (!left)
614 break;
615 err = proc_get_long(&p, &left, &lval, &neg,
616 proc_wspace_sep,
617 sizeof(proc_wspace_sep), NULL);
618 if (err)
619 break;
620 if (conv(&neg, &lval, i, 1, table)) {
621 err = -EINVAL;
622 break;
623 }
624 } else {
625 if (conv(&neg, &lval, i, 0, table)) {
626 err = -EINVAL;
627 break;
628 }
629 if (!first)
630 proc_put_char(&buffer, &left, '\t');
631 proc_put_long(&buffer, &left, lval, neg);
632 }
633 }
634
635 if (SYSCTL_KERN_TO_USER(dir) && !first && left && !err)
636 proc_put_char(&buffer, &left, '\n');
637 if (SYSCTL_USER_TO_KERN(dir) && !err && left)
638 proc_skip_spaces(&p, &left);
639 if (SYSCTL_USER_TO_KERN(dir) && first)
640 return err ? : -EINVAL;
641 *lenp -= left;
642out:
643 *ppos += *lenp;
644 return err;
645}
646
647static int do_proc_douintvec_w(const struct ctl_table *table, void *buffer,
648 size_t *lenp, loff_t *ppos,
649 int (*conv)(unsigned long *u_ptr,
650 unsigned int *k_ptr, int dir,
651 const struct ctl_table *table))
652{
653 unsigned long lval;
654 int err = 0;
655 size_t left;
656 bool neg;
657 char *p = buffer;
658
659 left = *lenp;
660
661 if (proc_first_pos_non_zero_ignore(ppos, table))
662 goto bail_early;
663
664 if (left > PAGE_SIZE - 1)
665 left = PAGE_SIZE - 1;
666
667 proc_skip_spaces(&p, &left);
668 if (!left) {
669 err = -EINVAL;
670 goto out_free;
671 }
672
673 err = proc_get_long(&p, &left, &lval, &neg,
674 proc_wspace_sep,
675 sizeof(proc_wspace_sep), NULL);
676 if (err || neg) {
677 err = -EINVAL;
678 goto out_free;
679 }
680
681 if (conv(&lval, (unsigned int *) table->data, 1, table)) {
682 err = -EINVAL;
683 goto out_free;
684 }
685
686 if (!err && left)
687 proc_skip_spaces(&p, &left);
688
689out_free:
690 if (err)
691 return -EINVAL;
692
693 return 0;
694
695bail_early:
696 *ppos += *lenp;
697 return err;
698}
699
700static int do_proc_douintvec_r(const struct ctl_table *table, void *buffer,
701 size_t *lenp, loff_t *ppos,
702 int (*conv)(unsigned long *u_ptr,
703 unsigned int *k_ptr, int dir,
704 const struct ctl_table *table))
705{
706 unsigned long lval;
707 int err = 0;
708 size_t left;
709
710 left = *lenp;
711
712 if (conv(&lval, (unsigned int *) table->data, 0, table)) {
713 err = -EINVAL;
714 goto out;
715 }
716
717 proc_put_long(&buffer, &left, lval, false);
718 if (!left)
719 goto out;
720
721 proc_put_char(&buffer, &left, '\n');
722
723out:
724 *lenp -= left;
725 *ppos += *lenp;
726
727 return err;
728}
729
730static int do_proc_douintvec(const struct ctl_table *table, int dir,
731 void *buffer, size_t *lenp, loff_t *ppos,
732 int (*conv)(unsigned long *u_ptr,
733 unsigned int *k_ptr, int dir,
734 const struct ctl_table *table))
735{
736 unsigned int vleft;
737
738 if (!table->data || !table->maxlen || !*lenp ||
739 (*ppos && SYSCTL_KERN_TO_USER(dir))) {
740 *lenp = 0;
741 return 0;
742 }
743
744 vleft = table->maxlen / sizeof(unsigned int);
745
746 /*
747 * Arrays are not supported, keep this simple. *Do not* add
748 * support for them.
749 */
750 if (vleft != 1) {
751 *lenp = 0;
752 return -EINVAL;
753 }
754
755 if (!conv)
756 conv = do_proc_uint_conv;
757
758 if (SYSCTL_USER_TO_KERN(dir))
759 return do_proc_douintvec_w(table, buffer, lenp, ppos, conv);
760 return do_proc_douintvec_r(table, buffer, lenp, ppos, conv);
761}
762
763/**
764 * proc_douintvec_conv - read a vector of unsigned ints with a custom converter
765 *
766 * @table: the sysctl table
767 * @dir: %TRUE if this is a write to the sysctl file
768 * @buffer: the user buffer
769 * @lenp: the size of the user buffer
770 * @ppos: file position
771 * @conv: Custom converter call back
772 *
773 * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
774 * values from/to the user buffer, treated as an ASCII string. Negative
775 * strings are not allowed.
776 *
777 * Returns 0 on success
778 */
779int proc_douintvec_conv(const struct ctl_table *table, int dir, void *buffer,
780 size_t *lenp, loff_t *ppos,
781 int (*conv)(unsigned long *u_ptr, unsigned int *k_ptr,
782 int dir, const struct ctl_table *table))
783{
784 return do_proc_douintvec(table, dir, buffer, lenp, ppos, conv);
785}
786
787/**
788 * proc_dobool - read/write a bool
789 * @table: the sysctl table
790 * @dir: %TRUE if this is a write to the sysctl file
791 * @buffer: the user buffer
792 * @lenp: the size of the user buffer
793 * @ppos: file position
794 *
795 * Reads/writes one integer value from/to the user buffer,
796 * treated as an ASCII string.
797 *
798 * table->data must point to a bool variable and table->maxlen must
799 * be sizeof(bool).
800 *
801 * Returns 0 on success.
802 */
803int proc_dobool(const struct ctl_table *table, int dir, void *buffer,
804 size_t *lenp, loff_t *ppos)
805{
806 struct ctl_table tmp;
807 bool *data = table->data;
808 int res, val;
809
810 /* Do not support arrays yet. */
811 if (table->maxlen != sizeof(bool))
812 return -EINVAL;
813
814 tmp = *table;
815 tmp.maxlen = sizeof(val);
816 tmp.data = &val;
817
818 val = READ_ONCE(*data);
819 res = proc_dointvec(&tmp, dir, buffer, lenp, ppos);
820 if (res)
821 return res;
822 if (SYSCTL_USER_TO_KERN(dir))
823 WRITE_ONCE(*data, val);
824 return 0;
825}
826
827/**
828 * proc_dointvec - read a vector of integers
829 * @table: the sysctl table
830 * @dir: %TRUE if this is a write to the sysctl file
831 * @buffer: the user buffer
832 * @lenp: the size of the user buffer
833 * @ppos: file position
834 *
835 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
836 * values from/to the user buffer, treated as an ASCII string.
837 *
838 * Returns 0 on success.
839 */
840int proc_dointvec(const struct ctl_table *table, int dir, void *buffer,
841 size_t *lenp, loff_t *ppos)
842{
843 return do_proc_dointvec(table, dir, buffer, lenp, ppos, NULL);
844}
845
846/**
847 * proc_douintvec - read a vector of unsigned integers
848 * @table: the sysctl table
849 * @dir: %TRUE if this is a write to the sysctl file
850 * @buffer: the user buffer
851 * @lenp: the size of the user buffer
852 * @ppos: file position
853 *
854 * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
855 * values from/to the user buffer, treated as an ASCII string.
856 *
857 * Returns 0 on success.
858 */
859int proc_douintvec(const struct ctl_table *table, int dir, void *buffer,
860 size_t *lenp, loff_t *ppos)
861{
862 return do_proc_douintvec(table, dir, buffer, lenp, ppos,
863 do_proc_uint_conv);
864}
865
866/**
867 * proc_dointvec_minmax - read a vector of integers with min/max values
868 * @table: the sysctl table
869 * @dir: %TRUE if this is a write to the sysctl file
870 * @buffer: the user buffer
871 * @lenp: the size of the user buffer
872 * @ppos: file position
873 *
874 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
875 * values from/to the user buffer, treated as an ASCII string.
876 *
877 * This routine will ensure the values are within the range specified by
878 * table->extra1 (min) and table->extra2 (max).
879 *
880 * Returns 0 on success or -EINVAL when the range check fails and
881 * SYSCTL_USER_TO_KERN(dir) == true
882 */
883int proc_dointvec_minmax(const struct ctl_table *table, int dir,
884 void *buffer, size_t *lenp, loff_t *ppos)
885{
886 return do_proc_dointvec(table, dir, buffer, lenp, ppos,
887 do_proc_int_conv_minmax);
888}
889
890/**
891 * proc_douintvec_minmax - read a vector of unsigned ints with min/max values
892 * @table: the sysctl table
893 * @dir: %TRUE if this is a write to the sysctl file
894 * @buffer: the user buffer
895 * @lenp: the size of the user buffer
896 * @ppos: file position
897 *
898 * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
899 * values from/to the user buffer, treated as an ASCII string. Negative
900 * strings are not allowed.
901 *
902 * When changing the kernel variable, this routine will ensure the values
903 * are within the range specified by table->extra1 (min) and table->extra2
904 * (max). And Check that the values are less than UINT_MAX to avoid having to
905 * support wrap around uses from userspace.
906 *
907 * Returns 0 on success or -ERANGE when range check failes and
908 * SYSCTL_USER_TO_KERN(dir) == true
909 */
910int proc_douintvec_minmax(const struct ctl_table *table, int dir,
911 void *buffer, size_t *lenp, loff_t *ppos)
912{
913 return do_proc_douintvec(table, dir, buffer, lenp, ppos,
914 do_proc_uint_conv_minmax);
915}
916
917/**
918 * proc_dou8vec_minmax - read a vector of unsigned chars with min/max values
919 * @table: the sysctl table
920 * @dir: %TRUE if this is a write to the sysctl file
921 * @buffer: the user buffer
922 * @lenp: the size of the user buffer
923 * @ppos: file position
924 *
925 * Reads/writes up to table->maxlen/sizeof(u8) unsigned chars
926 * values from/to the user buffer, treated as an ASCII string. Negative
927 * strings are not allowed.
928 *
929 * This routine will ensure the values are within the range specified by
930 * table->extra1 (min) and table->extra2 (max).
931 *
932 * Returns 0 on success or an error on SYSCTL_USER_TO_KERN(dir) == true
933 * and the range check fails.
934 */
935int proc_dou8vec_minmax(const struct ctl_table *table, int dir,
936 void *buffer, size_t *lenp, loff_t *ppos)
937{
938 struct ctl_table tmp;
939 unsigned int min = 0, max = 255U, val;
940 u8 *data = table->data;
941 int res;
942
943 /* Do not support arrays yet. */
944 if (table->maxlen != sizeof(u8))
945 return -EINVAL;
946
947 tmp = *table;
948
949 tmp.maxlen = sizeof(val);
950 tmp.data = &val;
951 if (!tmp.extra1)
952 tmp.extra1 = (unsigned int *) &min;
953 if (!tmp.extra2)
954 tmp.extra2 = (unsigned int *) &max;
955
956 val = READ_ONCE(*data);
957 res = do_proc_douintvec(&tmp, dir, buffer, lenp, ppos,
958 do_proc_uint_conv_minmax);
959 if (res)
960 return res;
961 if (SYSCTL_USER_TO_KERN(dir))
962 WRITE_ONCE(*data, val);
963 return 0;
964}
965EXPORT_SYMBOL_GPL(proc_dou8vec_minmax);
966
967static int do_proc_doulongvec_minmax(const struct ctl_table *table, int dir,
968 void *buffer, size_t *lenp, loff_t *ppos,
969 unsigned long convmul,
970 unsigned long convdiv)
971{
972 unsigned long *i, *min, *max;
973 int vleft, first = 1, err = 0;
974 size_t left;
975 char *p;
976
977 if (!table->data || !table->maxlen || !*lenp ||
978 (*ppos && SYSCTL_KERN_TO_USER(dir))) {
979 *lenp = 0;
980 return 0;
981 }
982
983 i = table->data;
984 min = table->extra1;
985 max = table->extra2;
986 vleft = table->maxlen / sizeof(unsigned long);
987 left = *lenp;
988
989 if (SYSCTL_USER_TO_KERN(dir)) {
990 if (proc_first_pos_non_zero_ignore(ppos, table))
991 goto out;
992
993 if (left > PAGE_SIZE - 1)
994 left = PAGE_SIZE - 1;
995 p = buffer;
996 }
997
998 for (; left && vleft--; i++, first = 0) {
999 unsigned long val;
1000
1001 if (SYSCTL_USER_TO_KERN(dir)) {
1002 bool neg;
1003
1004 proc_skip_spaces(&p, &left);
1005 if (!left)
1006 break;
1007
1008 err = proc_get_long(&p, &left, &val, &neg,
1009 proc_wspace_sep,
1010 sizeof(proc_wspace_sep), NULL);
1011 if (err || neg) {
1012 err = -EINVAL;
1013 break;
1014 }
1015
1016 val = convmul * val / convdiv;
1017 if ((min && val < *min) || (max && val > *max)) {
1018 err = -EINVAL;
1019 break;
1020 }
1021 WRITE_ONCE(*i, val);
1022 } else {
1023 val = convdiv * READ_ONCE(*i) / convmul;
1024 if (!first)
1025 proc_put_char(&buffer, &left, '\t');
1026 proc_put_long(&buffer, &left, val, false);
1027 }
1028 }
1029
1030 if (SYSCTL_KERN_TO_USER(dir) && !first && left && !err)
1031 proc_put_char(&buffer, &left, '\n');
1032 if (SYSCTL_USER_TO_KERN(dir) && !err)
1033 proc_skip_spaces(&p, &left);
1034 if (SYSCTL_USER_TO_KERN(dir) && first)
1035 return err ? : -EINVAL;
1036 *lenp -= left;
1037out:
1038 *ppos += *lenp;
1039 return err;
1040}
1041
1042int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir,
1043 void *buffer, size_t *lenp, loff_t *ppos,
1044 unsigned long convmul, unsigned long convdiv)
1045{
1046 return do_proc_doulongvec_minmax(table, dir, buffer, lenp, ppos,
1047 convmul, convdiv);
1048}
1049
1050/**
1051 * proc_doulongvec_minmax - read a vector of long integers with min/max values
1052 * @table: the sysctl table
1053 * @dir: %TRUE if this is a write to the sysctl file
1054 * @buffer: the user buffer
1055 * @lenp: the size of the user buffer
1056 * @ppos: file position
1057 *
1058 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
1059 * values from/to the user buffer, treated as an ASCII string.
1060 *
1061 * This routine will ensure the values are within the range specified by
1062 * table->extra1 (min) and table->extra2 (max).
1063 *
1064 * Returns 0 on success.
1065 */
1066int proc_doulongvec_minmax(const struct ctl_table *table, int dir,
1067 void *buffer, size_t *lenp, loff_t *ppos)
1068{
1069 return proc_doulongvec_minmax_conv(table, dir, buffer, lenp, ppos, 1l, 1l);
1070}
1071
1072/**
1073 * proc_dointvec_conv - read a vector of ints with a custom converter
1074 * @table: the sysctl table
1075 * @dir: %TRUE if this is a write to the sysctl file
1076 * @buffer: the user buffer
1077 * @lenp: the size of the user buffer
1078 * @ppos: file position
1079 * @conv: Custom converter call back
1080 *
1081 * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
1082 * values from/to the user buffer, treated as an ASCII string. Negative
1083 * strings are not allowed.
1084 *
1085 * Returns: 0 on success
1086 */
1087
1088int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
1089 size_t *lenp, loff_t *ppos,
1090 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
1091 int dir, const struct ctl_table *table))
1092{
1093 return do_proc_dointvec(table, dir, buffer, lenp, ppos, conv);
1094}
1095
1096/**
1097 * proc_do_large_bitmap - read/write from/to a large bitmap
1098 * @table: the sysctl table
1099 * @dir: %TRUE if this is a write to the sysctl file
1100 * @buffer: the user buffer
1101 * @lenp: the size of the user buffer
1102 * @ppos: file position
1103 *
1104 * The bitmap is stored at table->data and the bitmap length (in bits)
1105 * in table->maxlen.
1106 *
1107 * We use a range comma separated format (e.g. 1,3-4,10-10) so that
1108 * large bitmaps may be represented in a compact manner. Writing into
1109 * the file will clear the bitmap then update it with the given input.
1110 *
1111 * Returns 0 on success.
1112 */
1113int proc_do_large_bitmap(const struct ctl_table *table, int dir,
1114 void *buffer, size_t *lenp, loff_t *ppos)
1115{
1116 int err = 0;
1117 size_t left = *lenp;
1118 unsigned long bitmap_len = table->maxlen;
1119 unsigned long *bitmap = *(unsigned long **) table->data;
1120 unsigned long *tmp_bitmap = NULL;
1121 char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c = 0;
1122
1123 if (!bitmap || !bitmap_len || !left || (*ppos && SYSCTL_KERN_TO_USER(dir))) {
1124 *lenp = 0;
1125 return 0;
1126 }
1127
1128 if (SYSCTL_USER_TO_KERN(dir)) {
1129 char *p = buffer;
1130 size_t skipped = 0;
1131
1132 if (left > PAGE_SIZE - 1) {
1133 left = PAGE_SIZE - 1;
1134 /* How much of the buffer we'll skip this pass */
1135 skipped = *lenp - left;
1136 }
1137
1138 tmp_bitmap = bitmap_zalloc(bitmap_len, GFP_KERNEL);
1139 if (!tmp_bitmap)
1140 return -ENOMEM;
1141 proc_skip_char(&p, &left, '\n');
1142 while (!err && left) {
1143 unsigned long val_a, val_b;
1144 bool neg;
1145 size_t saved_left;
1146
1147 /* In case we stop parsing mid-number, we can reset */
1148 saved_left = left;
1149 err = proc_get_long(&p, &left, &val_a, &neg, tr_a,
1150 sizeof(tr_a), &c);
1151 /*
1152 * If we consumed the entirety of a truncated buffer or
1153 * only one char is left (may be a "-"), then stop here,
1154 * reset, & come back for more.
1155 */
1156 if ((left <= 1) && skipped) {
1157 left = saved_left;
1158 break;
1159 }
1160
1161 if (err)
1162 break;
1163 if (val_a >= bitmap_len || neg) {
1164 err = -EINVAL;
1165 break;
1166 }
1167
1168 val_b = val_a;
1169 if (left) {
1170 p++;
1171 left--;
1172 }
1173
1174 if (c == '-') {
1175 err = proc_get_long(&p, &left, &val_b,
1176 &neg, tr_b, sizeof(tr_b),
1177 &c);
1178 /*
1179 * If we consumed all of a truncated buffer or
1180 * then stop here, reset, & come back for more.
1181 */
1182 if (!left && skipped) {
1183 left = saved_left;
1184 break;
1185 }
1186
1187 if (err)
1188 break;
1189 if (val_b >= bitmap_len || neg ||
1190 val_a > val_b) {
1191 err = -EINVAL;
1192 break;
1193 }
1194 if (left) {
1195 p++;
1196 left--;
1197 }
1198 }
1199
1200 bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1);
1201 proc_skip_char(&p, &left, '\n');
1202 }
1203 left += skipped;
1204 } else {
1205 unsigned long bit_a, bit_b = 0;
1206 bool first = 1;
1207
1208 while (left) {
1209 bit_a = find_next_bit(bitmap, bitmap_len, bit_b);
1210 if (bit_a >= bitmap_len)
1211 break;
1212 bit_b = find_next_zero_bit(bitmap, bitmap_len,
1213 bit_a + 1) - 1;
1214
1215 if (!first)
1216 proc_put_char(&buffer, &left, ',');
1217 proc_put_long(&buffer, &left, bit_a, false);
1218 if (bit_a != bit_b) {
1219 proc_put_char(&buffer, &left, '-');
1220 proc_put_long(&buffer, &left, bit_b, false);
1221 }
1222
1223 first = 0; bit_b++;
1224 }
1225 proc_put_char(&buffer, &left, '\n');
1226 }
1227
1228 if (!err) {
1229 if (SYSCTL_USER_TO_KERN(dir)) {
1230 if (*ppos)
1231 bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len);
1232 else
1233 bitmap_copy(bitmap, tmp_bitmap, bitmap_len);
1234 }
1235 *lenp -= left;
1236 *ppos += *lenp;
1237 }
1238
1239 bitmap_free(tmp_bitmap);
1240 return err;
1241}
1242
1243#else /* CONFIG_PROC_SYSCTL */
1244
1245int proc_dostring(const struct ctl_table *table, int dir,
1246 void *buffer, size_t *lenp, loff_t *ppos)
1247{
1248 return -ENOSYS;
1249}
1250
1251int proc_dobool(const struct ctl_table *table, int dir,
1252 void *buffer, size_t *lenp, loff_t *ppos)
1253{
1254 return -ENOSYS;
1255}
1256
1257int proc_dointvec(const struct ctl_table *table, int dir,
1258 void *buffer, size_t *lenp, loff_t *ppos)
1259{
1260 return -ENOSYS;
1261}
1262
1263int proc_douintvec(const struct ctl_table *table, int dir,
1264 void *buffer, size_t *lenp, loff_t *ppos)
1265{
1266 return -ENOSYS;
1267}
1268
1269int proc_dointvec_minmax(const struct ctl_table *table, int dir,
1270 void *buffer, size_t *lenp, loff_t *ppos)
1271{
1272 return -ENOSYS;
1273}
1274
1275int proc_douintvec_minmax(const struct ctl_table *table, int dir,
1276 void *buffer, size_t *lenp, loff_t *ppos)
1277{
1278 return -ENOSYS;
1279}
1280
1281int proc_douintvec_conv(const struct ctl_table *table, int write, void *buffer,
1282 size_t *lenp, loff_t *ppos,
1283 int (*conv)(unsigned long *lvalp, unsigned int *valp,
1284 int write, const struct ctl_table *table))
1285{
1286 return -ENOSYS;
1287}
1288
1289int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr)
1290{
1291 return -ENOSYS;
1292}
1293
1294int proc_uint_u2k_conv_uop(const ulong *u_ptr, uint *k_ptr,
1295 ulong (*u_ptr_op)(const ulong))
1296{
1297 return -ENOSYS;
1298}
1299
1300int proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir,
1301 const struct ctl_table *tbl, bool k_ptr_range_check,
1302 int (*user_to_kern)(const ulong *u_ptr, uint *k_ptr),
1303 int (*kern_to_user)(ulong *u_ptr, const uint *k_ptr))
1304{
1305 return -ENOSYS;
1306}
1307
1308int proc_dou8vec_minmax(const struct ctl_table *table, int dir,
1309 void *buffer, size_t *lenp, loff_t *ppos)
1310{
1311 return -ENOSYS;
1312}
1313
1314int proc_doulongvec_minmax(const struct ctl_table *table, int dir,
1315 void *buffer, size_t *lenp, loff_t *ppos)
1316{
1317 return -ENOSYS;
1318}
1319
1320int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir,
1321 void *buffer, size_t *lenp, loff_t *ppos,
1322 unsigned long convmul, unsigned long convdiv)
1323{
1324 return -ENOSYS;
1325}
1326
1327int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
1328 size_t *lenp, loff_t *ppos,
1329 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
1330 int dir, const struct ctl_table *table))
1331{
1332 return -ENOSYS;
1333}
1334
1335int proc_do_large_bitmap(const struct ctl_table *table, int dir,
1336 void *buffer, size_t *lenp, loff_t *ppos)
1337{
1338 return -ENOSYS;
1339}
1340
1341#endif /* CONFIG_PROC_SYSCTL */
1342
1343#if defined(CONFIG_SYSCTL)
1344int proc_do_static_key(const struct ctl_table *table, int dir,
1345 void *buffer, size_t *lenp, loff_t *ppos)
1346{
1347 struct static_key *key = (struct static_key *)table->data;
1348 static DEFINE_MUTEX(static_key_mutex);
1349 int val, ret;
1350 struct ctl_table tmp = {
1351 .data = &val,
1352 .maxlen = sizeof(val),
1353 .mode = table->mode,
1354 .extra1 = SYSCTL_ZERO,
1355 .extra2 = SYSCTL_ONE,
1356 };
1357
1358 if (SYSCTL_USER_TO_KERN(dir) && !capable(CAP_SYS_ADMIN))
1359 return -EPERM;
1360
1361 mutex_lock(&static_key_mutex);
1362 val = static_key_enabled(key);
1363 ret = proc_dointvec_minmax(&tmp, dir, buffer, lenp, ppos);
1364 if (SYSCTL_USER_TO_KERN(dir) && !ret) {
1365 if (val)
1366 static_key_enable(key);
1367 else
1368 static_key_disable(key);
1369 }
1370 mutex_unlock(&static_key_mutex);
1371 return ret;
1372}
1373
1374static const struct ctl_table sysctl_subsys_table[] = {
1375#ifdef CONFIG_PROC_SYSCTL
1376 {
1377 .procname = "sysctl_writes_strict",
1378 .data = &sysctl_writes_strict,
1379 .maxlen = sizeof(int),
1380 .mode = 0644,
1381 .proc_handler = proc_dointvec_minmax,
1382 .extra1 = SYSCTL_NEG_ONE,
1383 .extra2 = SYSCTL_ONE,
1384 },
1385#endif
1386 {
1387 .procname = "ngroups_max",
1388 .data = (void *)&ngroups_max,
1389 .maxlen = sizeof (int),
1390 .mode = 0444,
1391 .proc_handler = proc_dointvec,
1392 },
1393 {
1394 .procname = "cap_last_cap",
1395 .data = (void *)&cap_last_cap,
1396 .maxlen = sizeof(int),
1397 .mode = 0444,
1398 .proc_handler = proc_dointvec,
1399 },
1400#ifdef CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW
1401 {
1402 .procname = "unaligned-trap",
1403 .data = &unaligned_enabled,
1404 .maxlen = sizeof(int),
1405 .mode = 0644,
1406 .proc_handler = proc_dointvec,
1407 },
1408#endif
1409#ifdef CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN
1410 {
1411 .procname = "ignore-unaligned-usertrap",
1412 .data = &no_unaligned_warning,
1413 .maxlen = sizeof (int),
1414 .mode = 0644,
1415 .proc_handler = proc_dointvec,
1416 },
1417#endif
1418};
1419
1420int __init sysctl_init_bases(void)
1421{
1422 register_sysctl_init("kernel", sysctl_subsys_table);
1423
1424 return 0;
1425}
1426#endif /* CONFIG_SYSCTL */
1427/*
1428 * No sense putting this after each symbol definition, twice,
1429 * exception granted :-)
1430 */
1431EXPORT_SYMBOL(proc_dobool);
1432EXPORT_SYMBOL(proc_dointvec);
1433EXPORT_SYMBOL(proc_douintvec);
1434EXPORT_SYMBOL(proc_dointvec_minmax);
1435EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
1436EXPORT_SYMBOL(proc_dostring);
1437EXPORT_SYMBOL(proc_doulongvec_minmax);
1438EXPORT_SYMBOL(proc_do_large_bitmap);