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 */
26 const int sysctl_vals[] = { 0, 1, 2, 3, 4, 100, 200, 1000, 3000, INT_MAX, 65535, -1 };
27 EXPORT_SYMBOL(sysctl_vals);
28
29 const unsigned long sysctl_long_vals[] = { 0, 1, LONG_MAX };
30 EXPORT_SYMBOL_GPL(sysctl_long_vals);
31
32 #if defined(CONFIG_SYSCTL)
33
34 /* Constants used for minimum and maximum */
35 static const int ngroups_max = NGROUPS_MAX;
36 static 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 */
60 enum sysctl_writes_mode {
61 SYSCTL_WRITES_LEGACY = -1,
62 SYSCTL_WRITES_WARN = 0,
63 SYSCTL_WRITES_STRICT = 1,
64 };
65
66 static 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
_proc_do_string(char * data,int maxlen,int dir,char * buffer,size_t * lenp,loff_t * ppos)76 static 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
warn_sysctl_write(const struct ctl_table * table)138 static 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 */
proc_first_pos_non_zero_ignore(loff_t * ppos,const struct ctl_table * table)155 static 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 */
proc_dostring(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)189 int 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
proc_skip_spaces(char ** buf,size_t * size)199 static 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
proc_skip_char(char ** buf,size_t * size,const char v)209 static 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 */
strtoul_lenient(const char * cp,char ** endp,unsigned int base,unsigned long * res)234 static 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 */
proc_get_long(char ** buf,size_t * size,unsigned long * val,bool * neg,const char * perm_tr,unsigned perm_tr_len,char * tr)271 static 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 */
proc_put_long(void ** buf,size_t * size,unsigned long val,bool neg)330 static 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
proc_put_char(void ** buf,size_t * size,char c)345 static 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 static SYSCTL_USER_TO_KERN_INT_CONV(, SYSCTL_CONV_IDENTITY)
358 static SYSCTL_KERN_TO_USER_INT_CONV(, SYSCTL_CONV_IDENTITY)
359
360 static SYSCTL_INT_CONV_CUSTOM(, sysctl_user_to_kern_int_conv,
361 sysctl_kern_to_user_int_conv, false)
SYSCTL_INT_CONV_CUSTOM(_minmax,sysctl_user_to_kern_int_conv,sysctl_kern_to_user_int_conv,true)362 static SYSCTL_INT_CONV_CUSTOM(_minmax, sysctl_user_to_kern_int_conv,
363 sysctl_kern_to_user_int_conv, true)
364
365
366 static SYSCTL_USER_TO_KERN_UINT_CONV(, SYSCTL_CONV_IDENTITY)
367
368 int sysctl_kern_to_user_uint_conv(unsigned long *u_ptr,
369 const unsigned int *k_ptr)
370 {
371 unsigned int val = READ_ONCE(*k_ptr);
372 *u_ptr = (unsigned long)val;
373 return 0;
374 }
375
376 static SYSCTL_UINT_CONV_CUSTOM(, sysctl_user_to_kern_uint_conv,
377 sysctl_kern_to_user_uint_conv, false)
378 static SYSCTL_UINT_CONV_CUSTOM(_minmax, sysctl_user_to_kern_uint_conv,
379 sysctl_kern_to_user_uint_conv, true)
380
381 static const char proc_wspace_sep[] = { ' ', '\t', '\n' };
382
do_proc_dointvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(bool * negp,unsigned long * u_ptr,int * k_ptr,int dir,const struct ctl_table * table))383 static int do_proc_dointvec(const struct ctl_table *table, int dir,
384 void *buffer, size_t *lenp, loff_t *ppos,
385 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
386 int dir, const struct ctl_table *table))
387 {
388 int *i, vleft, first = 1, err = 0;
389 size_t left;
390 char *p;
391
392 if (!table->data || !table->maxlen || !*lenp ||
393 (*ppos && SYSCTL_KERN_TO_USER(dir))) {
394 *lenp = 0;
395 return 0;
396 }
397
398 i = (int *) table->data;
399 vleft = table->maxlen / sizeof(*i);
400 left = *lenp;
401
402 if (!conv)
403 conv = do_proc_int_conv;
404
405 if (SYSCTL_USER_TO_KERN(dir)) {
406 if (proc_first_pos_non_zero_ignore(ppos, table))
407 goto out;
408
409 if (left > PAGE_SIZE - 1)
410 left = PAGE_SIZE - 1;
411 p = buffer;
412 }
413
414 for (; left && vleft--; i++, first=0) {
415 unsigned long lval;
416 bool neg;
417
418 if (SYSCTL_USER_TO_KERN(dir)) {
419 proc_skip_spaces(&p, &left);
420
421 if (!left)
422 break;
423 err = proc_get_long(&p, &left, &lval, &neg,
424 proc_wspace_sep,
425 sizeof(proc_wspace_sep), NULL);
426 if (err)
427 break;
428 if (conv(&neg, &lval, i, 1, table)) {
429 err = -EINVAL;
430 break;
431 }
432 } else {
433 if (conv(&neg, &lval, i, 0, table)) {
434 err = -EINVAL;
435 break;
436 }
437 if (!first)
438 proc_put_char(&buffer, &left, '\t');
439 proc_put_long(&buffer, &left, lval, neg);
440 }
441 }
442
443 if (SYSCTL_KERN_TO_USER(dir) && !first && left && !err)
444 proc_put_char(&buffer, &left, '\n');
445 if (SYSCTL_USER_TO_KERN(dir) && !err && left)
446 proc_skip_spaces(&p, &left);
447 if (SYSCTL_USER_TO_KERN(dir) && first)
448 return err ? : -EINVAL;
449 *lenp -= left;
450 out:
451 *ppos += *lenp;
452 return err;
453 }
454
do_proc_douintvec_w(const struct ctl_table * table,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(unsigned long * u_ptr,unsigned int * k_ptr,int dir,const struct ctl_table * table))455 static int do_proc_douintvec_w(const struct ctl_table *table, void *buffer,
456 size_t *lenp, loff_t *ppos,
457 int (*conv)(unsigned long *u_ptr,
458 unsigned int *k_ptr, int dir,
459 const struct ctl_table *table))
460 {
461 unsigned long lval;
462 int err = 0;
463 size_t left;
464 bool neg;
465 char *p = buffer;
466
467 left = *lenp;
468
469 if (proc_first_pos_non_zero_ignore(ppos, table))
470 goto bail_early;
471
472 if (left > PAGE_SIZE - 1)
473 left = PAGE_SIZE - 1;
474
475 proc_skip_spaces(&p, &left);
476 if (!left) {
477 err = -EINVAL;
478 goto out_free;
479 }
480
481 err = proc_get_long(&p, &left, &lval, &neg,
482 proc_wspace_sep,
483 sizeof(proc_wspace_sep), NULL);
484 if (err || neg) {
485 err = -EINVAL;
486 goto out_free;
487 }
488
489 if (conv(&lval, (unsigned int *) table->data, 1, table)) {
490 err = -EINVAL;
491 goto out_free;
492 }
493
494 if (!err && left)
495 proc_skip_spaces(&p, &left);
496
497 out_free:
498 if (err)
499 return -EINVAL;
500
501 return 0;
502
503 bail_early:
504 *ppos += *lenp;
505 return err;
506 }
507
do_proc_douintvec_r(const struct ctl_table * table,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(unsigned long * u_ptr,unsigned int * k_ptr,int dir,const struct ctl_table * table))508 static int do_proc_douintvec_r(const struct ctl_table *table, void *buffer,
509 size_t *lenp, loff_t *ppos,
510 int (*conv)(unsigned long *u_ptr,
511 unsigned int *k_ptr, int dir,
512 const struct ctl_table *table))
513 {
514 unsigned long lval;
515 int err = 0;
516 size_t left;
517
518 left = *lenp;
519
520 if (conv(&lval, (unsigned int *) table->data, 0, table)) {
521 err = -EINVAL;
522 goto out;
523 }
524
525 proc_put_long(&buffer, &left, lval, false);
526 if (!left)
527 goto out;
528
529 proc_put_char(&buffer, &left, '\n');
530
531 out:
532 *lenp -= left;
533 *ppos += *lenp;
534
535 return err;
536 }
537
do_proc_douintvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(unsigned long * u_ptr,unsigned int * k_ptr,int dir,const struct ctl_table * table))538 static int do_proc_douintvec(const struct ctl_table *table, int dir,
539 void *buffer, size_t *lenp, loff_t *ppos,
540 int (*conv)(unsigned long *u_ptr,
541 unsigned int *k_ptr, int dir,
542 const struct ctl_table *table))
543 {
544 unsigned int vleft;
545
546 if (!table->data || !table->maxlen || !*lenp ||
547 (*ppos && SYSCTL_KERN_TO_USER(dir))) {
548 *lenp = 0;
549 return 0;
550 }
551
552 vleft = table->maxlen / sizeof(unsigned int);
553
554 /*
555 * Arrays are not supported, keep this simple. *Do not* add
556 * support for them.
557 */
558 if (vleft != 1) {
559 *lenp = 0;
560 return -EINVAL;
561 }
562
563 if (!conv)
564 conv = do_proc_uint_conv;
565
566 if (SYSCTL_USER_TO_KERN(dir))
567 return do_proc_douintvec_w(table, buffer, lenp, ppos, conv);
568 return do_proc_douintvec_r(table, buffer, lenp, ppos, conv);
569 }
570
proc_douintvec_conv(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(unsigned long * u_ptr,unsigned int * k_ptr,int dir,const struct ctl_table * table))571 int proc_douintvec_conv(const struct ctl_table *table, int dir, void *buffer,
572 size_t *lenp, loff_t *ppos,
573 int (*conv)(unsigned long *u_ptr, unsigned int *k_ptr,
574 int dir, const struct ctl_table *table))
575 {
576 return do_proc_douintvec(table, dir, buffer, lenp, ppos, conv);
577 }
578
579
580 /**
581 * proc_dobool - read/write a bool
582 * @table: the sysctl table
583 * @dir: %TRUE if this is a write to the sysctl file
584 * @buffer: the user buffer
585 * @lenp: the size of the user buffer
586 * @ppos: file position
587 *
588 * Reads/writes one integer value from/to the user buffer,
589 * treated as an ASCII string.
590 *
591 * table->data must point to a bool variable and table->maxlen must
592 * be sizeof(bool).
593 *
594 * Returns 0 on success.
595 */
proc_dobool(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)596 int proc_dobool(const struct ctl_table *table, int dir, void *buffer,
597 size_t *lenp, loff_t *ppos)
598 {
599 struct ctl_table tmp;
600 bool *data = table->data;
601 int res, val;
602
603 /* Do not support arrays yet. */
604 if (table->maxlen != sizeof(bool))
605 return -EINVAL;
606
607 tmp = *table;
608 tmp.maxlen = sizeof(val);
609 tmp.data = &val;
610
611 val = READ_ONCE(*data);
612 res = proc_dointvec(&tmp, dir, buffer, lenp, ppos);
613 if (res)
614 return res;
615 if (SYSCTL_USER_TO_KERN(dir))
616 WRITE_ONCE(*data, val);
617 return 0;
618 }
619
620 /**
621 * proc_dointvec - read a vector of integers
622 * @table: the sysctl table
623 * @dir: %TRUE if this is a write to the sysctl file
624 * @buffer: the user buffer
625 * @lenp: the size of the user buffer
626 * @ppos: file position
627 *
628 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
629 * values from/to the user buffer, treated as an ASCII string.
630 *
631 * Returns 0 on success.
632 */
proc_dointvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)633 int proc_dointvec(const struct ctl_table *table, int dir, void *buffer,
634 size_t *lenp, loff_t *ppos)
635 {
636 return do_proc_dointvec(table, dir, buffer, lenp, ppos, NULL);
637 }
638
639 /**
640 * proc_douintvec - read a vector of unsigned integers
641 * @table: the sysctl table
642 * @dir: %TRUE if this is a write to the sysctl file
643 * @buffer: the user buffer
644 * @lenp: the size of the user buffer
645 * @ppos: file position
646 *
647 * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
648 * values from/to the user buffer, treated as an ASCII string.
649 *
650 * Returns 0 on success.
651 */
proc_douintvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)652 int proc_douintvec(const struct ctl_table *table, int dir, void *buffer,
653 size_t *lenp, loff_t *ppos)
654 {
655 return do_proc_douintvec(table, dir, buffer, lenp, ppos,
656 do_proc_uint_conv);
657 }
658
659 /**
660 * proc_dointvec_minmax - read a vector of integers with min/max values
661 * @table: the sysctl table
662 * @dir: %TRUE if this is a write to the sysctl file
663 * @buffer: the user buffer
664 * @lenp: the size of the user buffer
665 * @ppos: file position
666 *
667 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
668 * values from/to the user buffer, treated as an ASCII string.
669 *
670 * This routine will ensure the values are within the range specified by
671 * table->extra1 (min) and table->extra2 (max).
672 *
673 * Returns 0 on success or -EINVAL when the range check fails and
674 * SYSCTL_USER_TO_KERN(dir) == true
675 */
proc_dointvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)676 int proc_dointvec_minmax(const struct ctl_table *table, int dir,
677 void *buffer, size_t *lenp, loff_t *ppos)
678 {
679 return do_proc_dointvec(table, dir, buffer, lenp, ppos,
680 do_proc_int_conv_minmax);
681 }
682
683 /**
684 * proc_douintvec_minmax - read a vector of unsigned ints with min/max values
685 * @table: the sysctl table
686 * @dir: %TRUE if this is a write to the sysctl file
687 * @buffer: the user buffer
688 * @lenp: the size of the user buffer
689 * @ppos: file position
690 *
691 * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
692 * values from/to the user buffer, treated as an ASCII string. Negative
693 * strings are not allowed.
694 *
695 * This routine will ensure the values are within the range specified by
696 * table->extra1 (min) and table->extra2 (max). There is a final sanity
697 * check for UINT_MAX to avoid having to support wrap around uses from
698 * userspace.
699 *
700 * Returns 0 on success or -ERANGE when range check failes and
701 * SYSCTL_USER_TO_KERN(dir) == true
702 */
proc_douintvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)703 int proc_douintvec_minmax(const struct ctl_table *table, int dir,
704 void *buffer, size_t *lenp, loff_t *ppos)
705 {
706 return do_proc_douintvec(table, dir, buffer, lenp, ppos,
707 do_proc_uint_conv_minmax);
708 }
709
710 /**
711 * proc_dou8vec_minmax - read a vector of unsigned chars with min/max values
712 * @table: the sysctl table
713 * @dir: %TRUE if this is a write to the sysctl file
714 * @buffer: the user buffer
715 * @lenp: the size of the user buffer
716 * @ppos: file position
717 *
718 * Reads/writes up to table->maxlen/sizeof(u8) unsigned chars
719 * values from/to the user buffer, treated as an ASCII string. Negative
720 * strings are not allowed.
721 *
722 * This routine will ensure the values are within the range specified by
723 * table->extra1 (min) and table->extra2 (max).
724 *
725 * Returns 0 on success or an error on SYSCTL_USER_TO_KERN(dir) == true
726 * and the range check fails.
727 */
proc_dou8vec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)728 int proc_dou8vec_minmax(const struct ctl_table *table, int dir,
729 void *buffer, size_t *lenp, loff_t *ppos)
730 {
731 struct ctl_table tmp;
732 unsigned int min = 0, max = 255U, val;
733 u8 *data = table->data;
734 int res;
735
736 /* Do not support arrays yet. */
737 if (table->maxlen != sizeof(u8))
738 return -EINVAL;
739
740 tmp = *table;
741
742 tmp.maxlen = sizeof(val);
743 tmp.data = &val;
744 if (!tmp.extra1)
745 tmp.extra1 = (unsigned int *) &min;
746 if (!tmp.extra2)
747 tmp.extra2 = (unsigned int *) &max;
748
749 val = READ_ONCE(*data);
750 res = do_proc_douintvec(&tmp, dir, buffer, lenp, ppos,
751 do_proc_uint_conv_minmax);
752 if (res)
753 return res;
754 if (SYSCTL_USER_TO_KERN(dir))
755 WRITE_ONCE(*data, val);
756 return 0;
757 }
758 EXPORT_SYMBOL_GPL(proc_dou8vec_minmax);
759
do_proc_doulongvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,unsigned long convmul,unsigned long convdiv)760 static int do_proc_doulongvec_minmax(const struct ctl_table *table, int dir,
761 void *buffer, size_t *lenp, loff_t *ppos,
762 unsigned long convmul,
763 unsigned long convdiv)
764 {
765 unsigned long *i, *min, *max;
766 int vleft, first = 1, err = 0;
767 size_t left;
768 char *p;
769
770 if (!table->data || !table->maxlen || !*lenp ||
771 (*ppos && SYSCTL_KERN_TO_USER(dir))) {
772 *lenp = 0;
773 return 0;
774 }
775
776 i = table->data;
777 min = table->extra1;
778 max = table->extra2;
779 vleft = table->maxlen / sizeof(unsigned long);
780 left = *lenp;
781
782 if (SYSCTL_USER_TO_KERN(dir)) {
783 if (proc_first_pos_non_zero_ignore(ppos, table))
784 goto out;
785
786 if (left > PAGE_SIZE - 1)
787 left = PAGE_SIZE - 1;
788 p = buffer;
789 }
790
791 for (; left && vleft--; i++, first = 0) {
792 unsigned long val;
793
794 if (SYSCTL_USER_TO_KERN(dir)) {
795 bool neg;
796
797 proc_skip_spaces(&p, &left);
798 if (!left)
799 break;
800
801 err = proc_get_long(&p, &left, &val, &neg,
802 proc_wspace_sep,
803 sizeof(proc_wspace_sep), NULL);
804 if (err || neg) {
805 err = -EINVAL;
806 break;
807 }
808
809 val = convmul * val / convdiv;
810 if ((min && val < *min) || (max && val > *max)) {
811 err = -EINVAL;
812 break;
813 }
814 WRITE_ONCE(*i, val);
815 } else {
816 val = convdiv * READ_ONCE(*i) / convmul;
817 if (!first)
818 proc_put_char(&buffer, &left, '\t');
819 proc_put_long(&buffer, &left, val, false);
820 }
821 }
822
823 if (SYSCTL_KERN_TO_USER(dir) && !first && left && !err)
824 proc_put_char(&buffer, &left, '\n');
825 if (SYSCTL_USER_TO_KERN(dir) && !err)
826 proc_skip_spaces(&p, &left);
827 if (SYSCTL_USER_TO_KERN(dir) && first)
828 return err ? : -EINVAL;
829 *lenp -= left;
830 out:
831 *ppos += *lenp;
832 return err;
833 }
834
proc_doulongvec_minmax_conv(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,unsigned long convmul,unsigned long convdiv)835 int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir,
836 void *buffer, size_t *lenp, loff_t *ppos,
837 unsigned long convmul, unsigned long convdiv)
838 {
839 return do_proc_doulongvec_minmax(table, dir, buffer, lenp, ppos,
840 convmul, convdiv);
841 }
842
843 /**
844 * proc_doulongvec_minmax - read a vector of long integers with min/max values
845 * @table: the sysctl table
846 * @dir: %TRUE if this is a write to the sysctl file
847 * @buffer: the user buffer
848 * @lenp: the size of the user buffer
849 * @ppos: file position
850 *
851 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
852 * values from/to the user buffer, treated as an ASCII string.
853 *
854 * This routine will ensure the values are within the range specified by
855 * table->extra1 (min) and table->extra2 (max).
856 *
857 * Returns 0 on success.
858 */
proc_doulongvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)859 int proc_doulongvec_minmax(const struct ctl_table *table, int dir,
860 void *buffer, size_t *lenp, loff_t *ppos)
861 {
862 return proc_doulongvec_minmax_conv(table, dir, buffer, lenp, ppos, 1l, 1l);
863 }
864
proc_dointvec_conv(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(bool * negp,unsigned long * u_ptr,int * k_ptr,int dir,const struct ctl_table * table))865 int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
866 size_t *lenp, loff_t *ppos,
867 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
868 int dir, const struct ctl_table *table))
869 {
870 return do_proc_dointvec(table, dir, buffer, lenp, ppos, conv);
871 }
872
873 /**
874 * proc_do_large_bitmap - read/write from/to a large bitmap
875 * @table: the sysctl table
876 * @dir: %TRUE if this is a write to the sysctl file
877 * @buffer: the user buffer
878 * @lenp: the size of the user buffer
879 * @ppos: file position
880 *
881 * The bitmap is stored at table->data and the bitmap length (in bits)
882 * in table->maxlen.
883 *
884 * We use a range comma separated format (e.g. 1,3-4,10-10) so that
885 * large bitmaps may be represented in a compact manner. Writing into
886 * the file will clear the bitmap then update it with the given input.
887 *
888 * Returns 0 on success.
889 */
proc_do_large_bitmap(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)890 int proc_do_large_bitmap(const struct ctl_table *table, int dir,
891 void *buffer, size_t *lenp, loff_t *ppos)
892 {
893 int err = 0;
894 size_t left = *lenp;
895 unsigned long bitmap_len = table->maxlen;
896 unsigned long *bitmap = *(unsigned long **) table->data;
897 unsigned long *tmp_bitmap = NULL;
898 char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c;
899
900 if (!bitmap || !bitmap_len || !left || (*ppos && SYSCTL_KERN_TO_USER(dir))) {
901 *lenp = 0;
902 return 0;
903 }
904
905 if (SYSCTL_USER_TO_KERN(dir)) {
906 char *p = buffer;
907 size_t skipped = 0;
908
909 if (left > PAGE_SIZE - 1) {
910 left = PAGE_SIZE - 1;
911 /* How much of the buffer we'll skip this pass */
912 skipped = *lenp - left;
913 }
914
915 tmp_bitmap = bitmap_zalloc(bitmap_len, GFP_KERNEL);
916 if (!tmp_bitmap)
917 return -ENOMEM;
918 proc_skip_char(&p, &left, '\n');
919 while (!err && left) {
920 unsigned long val_a, val_b;
921 bool neg;
922 size_t saved_left;
923
924 /* In case we stop parsing mid-number, we can reset */
925 saved_left = left;
926 err = proc_get_long(&p, &left, &val_a, &neg, tr_a,
927 sizeof(tr_a), &c);
928 /*
929 * If we consumed the entirety of a truncated buffer or
930 * only one char is left (may be a "-"), then stop here,
931 * reset, & come back for more.
932 */
933 if ((left <= 1) && skipped) {
934 left = saved_left;
935 break;
936 }
937
938 if (err)
939 break;
940 if (val_a >= bitmap_len || neg) {
941 err = -EINVAL;
942 break;
943 }
944
945 val_b = val_a;
946 if (left) {
947 p++;
948 left--;
949 }
950
951 if (c == '-') {
952 err = proc_get_long(&p, &left, &val_b,
953 &neg, tr_b, sizeof(tr_b),
954 &c);
955 /*
956 * If we consumed all of a truncated buffer or
957 * then stop here, reset, & come back for more.
958 */
959 if (!left && skipped) {
960 left = saved_left;
961 break;
962 }
963
964 if (err)
965 break;
966 if (val_b >= bitmap_len || neg ||
967 val_a > val_b) {
968 err = -EINVAL;
969 break;
970 }
971 if (left) {
972 p++;
973 left--;
974 }
975 }
976
977 bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1);
978 proc_skip_char(&p, &left, '\n');
979 }
980 left += skipped;
981 } else {
982 unsigned long bit_a, bit_b = 0;
983 bool first = 1;
984
985 while (left) {
986 bit_a = find_next_bit(bitmap, bitmap_len, bit_b);
987 if (bit_a >= bitmap_len)
988 break;
989 bit_b = find_next_zero_bit(bitmap, bitmap_len,
990 bit_a + 1) - 1;
991
992 if (!first)
993 proc_put_char(&buffer, &left, ',');
994 proc_put_long(&buffer, &left, bit_a, false);
995 if (bit_a != bit_b) {
996 proc_put_char(&buffer, &left, '-');
997 proc_put_long(&buffer, &left, bit_b, false);
998 }
999
1000 first = 0; bit_b++;
1001 }
1002 proc_put_char(&buffer, &left, '\n');
1003 }
1004
1005 if (!err) {
1006 if (SYSCTL_USER_TO_KERN(dir)) {
1007 if (*ppos)
1008 bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len);
1009 else
1010 bitmap_copy(bitmap, tmp_bitmap, bitmap_len);
1011 }
1012 *lenp -= left;
1013 *ppos += *lenp;
1014 }
1015
1016 bitmap_free(tmp_bitmap);
1017 return err;
1018 }
1019
1020 #else /* CONFIG_PROC_SYSCTL */
1021
proc_dostring(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1022 int proc_dostring(const struct ctl_table *table, int dir,
1023 void *buffer, size_t *lenp, loff_t *ppos)
1024 {
1025 return -ENOSYS;
1026 }
1027
proc_dobool(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1028 int proc_dobool(const struct ctl_table *table, int dir,
1029 void *buffer, size_t *lenp, loff_t *ppos)
1030 {
1031 return -ENOSYS;
1032 }
1033
proc_dointvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1034 int proc_dointvec(const struct ctl_table *table, int dir,
1035 void *buffer, size_t *lenp, loff_t *ppos)
1036 {
1037 return -ENOSYS;
1038 }
1039
proc_douintvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1040 int proc_douintvec(const struct ctl_table *table, int dir,
1041 void *buffer, size_t *lenp, loff_t *ppos)
1042 {
1043 return -ENOSYS;
1044 }
1045
proc_dointvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1046 int proc_dointvec_minmax(const struct ctl_table *table, int dir,
1047 void *buffer, size_t *lenp, loff_t *ppos)
1048 {
1049 return -ENOSYS;
1050 }
1051
proc_douintvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1052 int proc_douintvec_minmax(const struct ctl_table *table, int dir,
1053 void *buffer, size_t *lenp, loff_t *ppos)
1054 {
1055 return -ENOSYS;
1056 }
1057
proc_dou8vec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1058 int proc_dou8vec_minmax(const struct ctl_table *table, int dir,
1059 void *buffer, size_t *lenp, loff_t *ppos)
1060 {
1061 return -ENOSYS;
1062 }
1063
proc_doulongvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1064 int proc_doulongvec_minmax(const struct ctl_table *table, int dir,
1065 void *buffer, size_t *lenp, loff_t *ppos)
1066 {
1067 return -ENOSYS;
1068 }
1069
proc_doulongvec_minmax_conv(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,unsigned long convmul,unsigned long convdiv)1070 int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir,
1071 void *buffer, size_t *lenp, loff_t *ppos,
1072 unsigned long convmul, unsigned long convdiv)
1073 {
1074 return -ENOSYS;
1075 }
1076
proc_dointvec_conv(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(bool * negp,unsigned long * u_ptr,int * k_ptr,int dir,const struct ctl_table * table))1077 int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
1078 size_t *lenp, loff_t *ppos,
1079 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
1080 int dir, const struct ctl_table *table))
1081 {
1082 return -ENOSYS;
1083 }
1084
proc_do_large_bitmap(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1085 int proc_do_large_bitmap(const struct ctl_table *table, int dir,
1086 void *buffer, size_t *lenp, loff_t *ppos)
1087 {
1088 return -ENOSYS;
1089 }
1090
1091 #endif /* CONFIG_PROC_SYSCTL */
1092
1093 #if defined(CONFIG_SYSCTL)
proc_do_static_key(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1094 int proc_do_static_key(const struct ctl_table *table, int dir,
1095 void *buffer, size_t *lenp, loff_t *ppos)
1096 {
1097 struct static_key *key = (struct static_key *)table->data;
1098 static DEFINE_MUTEX(static_key_mutex);
1099 int val, ret;
1100 struct ctl_table tmp = {
1101 .data = &val,
1102 .maxlen = sizeof(val),
1103 .mode = table->mode,
1104 .extra1 = SYSCTL_ZERO,
1105 .extra2 = SYSCTL_ONE,
1106 };
1107
1108 if (SYSCTL_USER_TO_KERN(dir) && !capable(CAP_SYS_ADMIN))
1109 return -EPERM;
1110
1111 mutex_lock(&static_key_mutex);
1112 val = static_key_enabled(key);
1113 ret = proc_dointvec_minmax(&tmp, dir, buffer, lenp, ppos);
1114 if (SYSCTL_USER_TO_KERN(dir) && !ret) {
1115 if (val)
1116 static_key_enable(key);
1117 else
1118 static_key_disable(key);
1119 }
1120 mutex_unlock(&static_key_mutex);
1121 return ret;
1122 }
1123
1124 static const struct ctl_table sysctl_subsys_table[] = {
1125 #ifdef CONFIG_PROC_SYSCTL
1126 {
1127 .procname = "sysctl_writes_strict",
1128 .data = &sysctl_writes_strict,
1129 .maxlen = sizeof(int),
1130 .mode = 0644,
1131 .proc_handler = proc_dointvec_minmax,
1132 .extra1 = SYSCTL_NEG_ONE,
1133 .extra2 = SYSCTL_ONE,
1134 },
1135 #endif
1136 {
1137 .procname = "ngroups_max",
1138 .data = (void *)&ngroups_max,
1139 .maxlen = sizeof (int),
1140 .mode = 0444,
1141 .proc_handler = proc_dointvec,
1142 },
1143 {
1144 .procname = "cap_last_cap",
1145 .data = (void *)&cap_last_cap,
1146 .maxlen = sizeof(int),
1147 .mode = 0444,
1148 .proc_handler = proc_dointvec,
1149 },
1150 #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW
1151 {
1152 .procname = "unaligned-trap",
1153 .data = &unaligned_enabled,
1154 .maxlen = sizeof(int),
1155 .mode = 0644,
1156 .proc_handler = proc_dointvec,
1157 },
1158 #endif
1159 #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN
1160 {
1161 .procname = "ignore-unaligned-usertrap",
1162 .data = &no_unaligned_warning,
1163 .maxlen = sizeof (int),
1164 .mode = 0644,
1165 .proc_handler = proc_dointvec,
1166 },
1167 #endif
1168 };
1169
sysctl_init_bases(void)1170 int __init sysctl_init_bases(void)
1171 {
1172 register_sysctl_init("kernel", sysctl_subsys_table);
1173
1174 return 0;
1175 }
1176 #endif /* CONFIG_SYSCTL */
1177 /*
1178 * No sense putting this after each symbol definition, twice,
1179 * exception granted :-)
1180 */
1181 EXPORT_SYMBOL(proc_dobool);
1182 EXPORT_SYMBOL(proc_dointvec);
1183 EXPORT_SYMBOL(proc_douintvec);
1184 EXPORT_SYMBOL(proc_dointvec_minmax);
1185 EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
1186 EXPORT_SYMBOL(proc_dostring);
1187 EXPORT_SYMBOL(proc_doulongvec_minmax);
1188 EXPORT_SYMBOL(proc_do_large_bitmap);
1189