xref: /linux/kernel/sysctl.c (revision ac20755937e037e586b1ca18a6717d31b1cbce93)
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