xref: /linux/kernel/sysctl.c (revision 23b0f90ba871f096474e1c27c3d14f455189d2d9)
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 /**
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  */
proc_uint_u2k_conv_uop(const ulong * u_ptr,uint * k_ptr,ulong (* u_ptr_op)(const ulong))370 int 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  */
proc_uint_k2u_conv(ulong * u_ptr,const uint * k_ptr)391 int 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  */
proc_uint_conv(ulong * u_ptr,uint * k_ptr,int dir,const struct ctl_table * tbl,bool k_ptr_range_check,int (* user_to_kern)(const ulong * u_ptr,uint * k_ptr),int (* kern_to_user)(ulong * u_ptr,const uint * k_ptr))414 int 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 
proc_uint_u2k_conv(const ulong * u_ptr,uint * k_ptr)442 static 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 
do_proc_uint_conv(ulong * u_ptr,uint * k_ptr,int dir,const struct ctl_table * tbl)447 static 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 
do_proc_uint_conv_minmax(ulong * u_ptr,uint * k_ptr,int dir,const struct ctl_table * tbl)454 static 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  */
proc_int_k2u_conv_kop(ulong * u_ptr,const int * k_ptr,bool * negp,ulong (* k_ptr_op)(const ulong))474 int 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  */
proc_int_u2k_conv_uop(const ulong * u_ptr,int * k_ptr,const bool * negp,ulong (* u_ptr_op)(const ulong))501 int 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 
proc_int_conv(bool * negp,ulong * u_ptr,int * k_ptr,int dir,const struct ctl_table * tbl,bool k_ptr_range_check,int (* user_to_kern)(const bool * negp,const ulong * u_ptr,int * k_ptr),int (* kern_to_user)(bool * negp,ulong * u_ptr,const int * k_ptr))518 int 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 
sysctl_user_to_kern_int_conv(const bool * negp,const ulong * u_ptr,int * k_ptr)545 static 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 
sysctl_kern_to_user_int_conv(bool * negp,ulong * u_ptr,const int * k_ptr)551 static 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 
do_proc_int_conv(bool * negp,unsigned long * u_ptr,int * k_ptr,int dir,const struct ctl_table * tbl)556 static 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 
do_proc_int_conv_minmax(bool * negp,unsigned long * u_ptr,int * k_ptr,int dir,const struct ctl_table * tbl)565 static 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 
573 static const char proc_wspace_sep[] = { ' ', '\t', '\n' };
574 
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))575 static 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;
642 out:
643 	*ppos += *lenp;
644 	return err;
645 }
646 
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))647 static 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 
689 out_free:
690 	if (err)
691 		return -EINVAL;
692 
693 	return 0;
694 
695 bail_early:
696 	*ppos += *lenp;
697 	return err;
698 }
699 
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))700 static 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 
723 out:
724 	*lenp -= left;
725 	*ppos += *lenp;
726 
727 	return err;
728 }
729 
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))730 static 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  */
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))779 int 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  */
proc_dobool(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)803 int 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  */
proc_dointvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)840 int 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  */
proc_douintvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)859 int 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  */
proc_dointvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)883 int 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  */
proc_douintvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)910 int 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  */
proc_dou8vec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)935 int 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 }
965 EXPORT_SYMBOL_GPL(proc_dou8vec_minmax);
966 
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)967 static 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;
1037 out:
1038 	*ppos += *lenp;
1039 	return err;
1040 }
1041 
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)1042 int 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  */
proc_doulongvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1066 int 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 
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))1088 int 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  */
proc_do_large_bitmap(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1113 int 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;
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 
proc_dostring(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1245 int proc_dostring(const struct ctl_table *table, int dir,
1246 		  void *buffer, size_t *lenp, loff_t *ppos)
1247 {
1248 	return -ENOSYS;
1249 }
1250 
proc_dobool(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1251 int proc_dobool(const struct ctl_table *table, int dir,
1252 		void *buffer, size_t *lenp, loff_t *ppos)
1253 {
1254 	return -ENOSYS;
1255 }
1256 
proc_dointvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1257 int proc_dointvec(const struct ctl_table *table, int dir,
1258 		  void *buffer, size_t *lenp, loff_t *ppos)
1259 {
1260 	return -ENOSYS;
1261 }
1262 
proc_douintvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1263 int proc_douintvec(const struct ctl_table *table, int dir,
1264 		  void *buffer, size_t *lenp, loff_t *ppos)
1265 {
1266 	return -ENOSYS;
1267 }
1268 
proc_dointvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1269 int 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 
proc_douintvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1275 int 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 
proc_douintvec_conv(const struct ctl_table * table,int write,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(unsigned long * lvalp,unsigned int * valp,int write,const struct ctl_table * table))1281 int 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 
proc_uint_k2u_conv(ulong * u_ptr,const uint * k_ptr)1289 int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr)
1290 {
1291 	return -ENOSYS;
1292 }
1293 
proc_uint_u2k_conv_uop(const ulong * u_ptr,uint * k_ptr,ulong (* u_ptr_op)(const ulong))1294 int 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 
proc_uint_conv(ulong * u_ptr,uint * k_ptr,int dir,const struct ctl_table * tbl,bool k_ptr_range_check,int (* user_to_kern)(const ulong * u_ptr,uint * k_ptr),int (* kern_to_user)(ulong * u_ptr,const uint * k_ptr))1300 int 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 
proc_dou8vec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1308 int 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 
proc_doulongvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1314 int 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 
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)1320 int 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 
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))1327 int 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 
proc_do_large_bitmap(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1335 int 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)
proc_do_static_key(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1344 int 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 
1374 static 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 
sysctl_init_bases(void)1420 int __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  */
1431 EXPORT_SYMBOL(proc_dobool);
1432 EXPORT_SYMBOL(proc_dointvec);
1433 EXPORT_SYMBOL(proc_douintvec);
1434 EXPORT_SYMBOL(proc_dointvec_minmax);
1435 EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
1436 EXPORT_SYMBOL(proc_dostring);
1437 EXPORT_SYMBOL(proc_doulongvec_minmax);
1438 EXPORT_SYMBOL(proc_do_large_bitmap);
1439