xref: /linux/kernel/sysctl.c (revision 9d2ed026f031f764e9450ac9aada2f46bc977397)
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_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_SYSCTL */
68 #endif /* CONFIG_SYSCTL */
69 
70 /*
71  * /proc/sys support
72  */
73 
74 #ifdef CONFIG_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  * This function will fail the parse on overflow. If there wasn't an overflow
229  * the function will defer the decision what characters count as invalid to the
230  * caller.
231  *
232  * Returns:
233  * * %0 on success and @res will contain the parsed integer,
234  *   @endp will hold any trailing characters.
235  * * %-ERANGE on overflow.
236  */
strtoul_lenient(const char * cp,char ** endp,unsigned int base,unsigned long * res)237 static int strtoul_lenient(const char *cp, char **endp, unsigned int base,
238 			   unsigned long *res)
239 {
240 	unsigned long long result;
241 	unsigned int rv;
242 
243 	cp = _parse_integer_fixup_radix(cp, &base);
244 	rv = _parse_integer(cp, base, &result);
245 	if ((rv & KSTRTOX_OVERFLOW) || (result != (unsigned long)result))
246 		return -ERANGE;
247 
248 	cp += rv;
249 
250 	if (endp)
251 		*endp = (char *)cp;
252 
253 	*res = (unsigned long)result;
254 	return 0;
255 }
256 
257 #define TMPBUFLEN 22
258 /**
259  * proc_get_long - reads an ASCII formatted integer from a user buffer
260  *
261  * @buf: a kernel buffer
262  * @size: size of the kernel buffer
263  * @val: this is where the number will be stored
264  * @neg: set to %TRUE if number is negative
265  * @perm_tr: a vector which contains the allowed trailers
266  * @perm_tr_len: size of the perm_tr vector
267  * @tr: pointer to store the trailer character
268  *
269  * Returns:
270  * * %0 on success and @buf and @size are updated with
271  *   the amount of bytes read. If @tr is non-NULL and a trailing
272  *   character exists (size is non-zero after returning from this
273  *   function), @tr is updated with the trailing character.
274  * * %-EINVAL on failure.
275  */
proc_get_long(char ** buf,size_t * size,unsigned long * val,bool * neg,const char * perm_tr,unsigned perm_tr_len,char * tr)276 static int proc_get_long(char **buf, size_t *size,
277 			  unsigned long *val, bool *neg,
278 			  const char *perm_tr, unsigned perm_tr_len, char *tr)
279 {
280 	char *p, tmp[TMPBUFLEN];
281 	ssize_t len = *size;
282 
283 	if (len <= 0)
284 		return -EINVAL;
285 
286 	if (len > TMPBUFLEN - 1)
287 		len = TMPBUFLEN - 1;
288 
289 	memcpy(tmp, *buf, len);
290 
291 	tmp[len] = 0;
292 	p = tmp;
293 	if (*p == '-' && *size > 1) {
294 		*neg = true;
295 		p++;
296 	} else
297 		*neg = false;
298 	if (!isdigit(*p))
299 		return -EINVAL;
300 
301 	if (strtoul_lenient(p, &p, 0, val))
302 		return -EINVAL;
303 
304 	len = p - tmp;
305 
306 	/* We don't know if the next char is whitespace thus we may accept
307 	 * invalid integers (e.g. 1234...a) or two integers instead of one
308 	 * (e.g. 123...1). So lets not allow such large numbers. */
309 	if (len == TMPBUFLEN - 1)
310 		return -EINVAL;
311 
312 	if (len < *size && perm_tr_len && !memchr(perm_tr, *p, perm_tr_len))
313 		return -EINVAL;
314 
315 	if (tr && (len < *size))
316 		*tr = *p;
317 
318 	*buf += len;
319 	*size -= len;
320 
321 	return 0;
322 }
323 
324 /**
325  * proc_put_long - converts an integer to a decimal ASCII formatted string
326  *
327  * @buf: the user buffer
328  * @size: the size of the user buffer
329  * @val: the integer to be converted
330  * @neg: sign of the number, %TRUE for negative
331  *
332  * In case of success @buf and @size are updated with the amount of bytes
333  * written.
334  */
proc_put_long(void ** buf,size_t * size,unsigned long val,bool neg)335 static void proc_put_long(void **buf, size_t *size, unsigned long val, bool neg)
336 {
337 	int len;
338 	char tmp[TMPBUFLEN], *p = tmp;
339 
340 	sprintf(p, "%s%lu", neg ? "-" : "", val);
341 	len = strlen(tmp);
342 	if (len > *size)
343 		len = *size;
344 	memcpy(*buf, tmp, len);
345 	*size -= len;
346 	*buf += len;
347 }
348 #undef TMPBUFLEN
349 
proc_put_char(void ** buf,size_t * size,char c)350 static void proc_put_char(void **buf, size_t *size, char c)
351 {
352 	if (*size) {
353 		char **buffer = (char **)buf;
354 		**buffer = c;
355 
356 		(*size)--;
357 		(*buffer)++;
358 		*buf = *buffer;
359 	}
360 }
361 
362 /**
363  * proc_uint_u2k_conv_uop - Assign user value to a kernel pointer
364  *
365  * @u_ptr: pointer to user space variable
366  * @k_ptr: pointer to kernel variable
367  * @u_ptr_op: execute this function before assigning to k_ptr
368  *
369  * Uses WRITE_ONCE to assign value to k_ptr. Executes u_ptr_op if
370  * not NULL. Check that the values are less than UINT_MAX to avoid
371  * having to support wrap around from userspace.
372  *
373  * Returns: %0 on success.
374  */
proc_uint_u2k_conv_uop(const ulong * u_ptr,uint * k_ptr,ulong (* u_ptr_op)(const ulong))375 int proc_uint_u2k_conv_uop(const ulong *u_ptr, uint *k_ptr,
376 			   ulong (*u_ptr_op)(const ulong))
377 {
378 	ulong u = u_ptr_op ? u_ptr_op(*u_ptr) : *u_ptr;
379 
380 	if (u > UINT_MAX)
381 		return -EINVAL;
382 	WRITE_ONCE(*k_ptr, u);
383 	return 0;
384 }
385 
386 /**
387  * proc_uint_k2u_conv - Assign kernel value to a user space pointer
388  *
389  * @u_ptr: pointer to user space variable
390  * @k_ptr: pointer to kernel variable
391  *
392  * Uses READ_ONCE to assign value to u_ptr.
393  *
394  * Returns: %0 on success.
395  */
proc_uint_k2u_conv(ulong * u_ptr,const uint * k_ptr)396 int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr)
397 {
398 	uint val = READ_ONCE(*k_ptr);
399 	*u_ptr = (ulong)val;
400 	return 0;
401 }
402 
403 /**
404  * proc_uint_conv - Change user or kernel pointer based on direction
405  *
406  * @u_ptr: pointer to user variable
407  * @k_ptr: pointer to kernel variable
408  * @dir: %TRUE if this is a write to the sysctl file
409  * @tbl: the sysctl table
410  * @k_ptr_range_check: Check range for k_ptr when %TRUE
411  * @user_to_kern: Callback used to assign value from user to kernel var
412  * @kern_to_user: Callback used to assign value from kernel to user var
413  *
414  * When direction is kernel to user, then the u_ptr is modified.
415  * When direction is user to kernel, then the k_ptr is modified.
416  *
417  * Returns: %0 on success
418  */
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))419 int proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir,
420 		   const struct ctl_table *tbl, bool k_ptr_range_check,
421 		   int (*user_to_kern)(const ulong *u_ptr, uint *k_ptr),
422 		   int (*kern_to_user)(ulong *u_ptr, const uint *k_ptr))
423 {
424 	if (SYSCTL_KERN_TO_USER(dir))
425 		return kern_to_user(u_ptr, k_ptr);
426 
427 	if (k_ptr_range_check) {
428 		uint tmp_k;
429 		int ret;
430 
431 		if (!tbl)
432 			return -EINVAL;
433 		ret = user_to_kern(u_ptr, &tmp_k);
434 		if (ret)
435 			return ret;
436 		if ((tbl->extra1 &&
437 		     *(uint *)tbl->extra1 > tmp_k) ||
438 		    (tbl->extra2 &&
439 		     *(uint *)tbl->extra2 < tmp_k))
440 			return -ERANGE;
441 		WRITE_ONCE(*k_ptr, tmp_k);
442 	} else
443 		return user_to_kern(u_ptr, k_ptr);
444 	return 0;
445 }
446 
proc_uint_u2k_conv(const ulong * u_ptr,uint * k_ptr)447 static int proc_uint_u2k_conv(const ulong *u_ptr, uint *k_ptr)
448 {
449 	return proc_uint_u2k_conv_uop(u_ptr, k_ptr, NULL);
450 }
451 
do_proc_uint_conv(bool * negp,ulong * u_ptr,uint * k_ptr,int dir,const struct ctl_table * tbl)452 static int do_proc_uint_conv(bool *negp, ulong *u_ptr, uint *k_ptr, int dir,
453 			     const struct ctl_table *tbl)
454 {
455 	return proc_uint_conv(u_ptr, k_ptr, dir, tbl, false,
456 			      proc_uint_u2k_conv, proc_uint_k2u_conv);
457 }
458 
do_proc_uint_conv_minmax(bool * negp,ulong * u_ptr,uint * k_ptr,int dir,const struct ctl_table * tbl)459 static int do_proc_uint_conv_minmax(bool *negp, ulong *u_ptr, uint *k_ptr,
460 				    int dir, const struct ctl_table *tbl)
461 {
462 	return proc_uint_conv(u_ptr, k_ptr, dir, tbl, true,
463 			      proc_uint_u2k_conv, proc_uint_k2u_conv);
464 }
465 
466 /**
467  * proc_int_k2u_conv_kop - Assign kernel value to a user space pointer
468  * @u_ptr: pointer to user space variable
469  * @k_ptr: pointer to kernel variable
470  * @negp: assigned %TRUE if the converted kernel value is negative;
471  *        %FALSE otherweise
472  * @k_ptr_op: execute this function before assigning to u_ptr
473  *
474  * Uses READ_ONCE to get value from k_ptr. Executes k_ptr_op before assigning
475  * to u_ptr if not NULL. Does **not** check for overflow.
476  *
477  * Returns: 0 on success.
478  */
proc_int_k2u_conv_kop(ulong * u_ptr,const int * k_ptr,bool * negp,ulong (* k_ptr_op)(const ulong))479 int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp,
480 			  ulong (*k_ptr_op)(const ulong))
481 {
482 	int val = READ_ONCE(*k_ptr);
483 
484 	if (val < 0) {
485 		*negp = true;
486 		*u_ptr = k_ptr_op ? -k_ptr_op((ulong)val) : -(ulong)val;
487 	} else {
488 		*negp = false;
489 		*u_ptr = k_ptr_op ? k_ptr_op((ulong)val) : (ulong) val;
490 	}
491 	return 0;
492 }
493 
494 /**
495  * proc_int_u2k_conv_uop - Assign user value to a kernel pointer
496  * @u_ptr: pointer to user space variable
497  * @k_ptr: pointer to kernel variable
498  * @negp: If %TRUE, the converted user value is made negative.
499  * @u_ptr_op: execute this function before assigning to k_ptr
500  *
501  * Uses WRITE_ONCE to assign value to k_ptr. Executes u_ptr_op if
502  * not NULL. Check for overflow with UINT_MAX.
503  *
504  * Returns: 0 on success.
505  */
proc_int_u2k_conv_uop(const ulong * u_ptr,int * k_ptr,const bool * negp,ulong (* u_ptr_op)(const ulong))506 int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp,
507 			  ulong (*u_ptr_op)(const ulong))
508 {
509 	ulong u = u_ptr_op ? u_ptr_op(*u_ptr) : *u_ptr;
510 
511 	if (*negp) {
512 		if (u > (ulong) INT_MAX + 1)
513 			return -EINVAL;
514 		WRITE_ONCE(*k_ptr, -u);
515 	} else {
516 		if (u > (ulong) INT_MAX)
517 			return -EINVAL;
518 		WRITE_ONCE(*k_ptr, u);
519 	}
520 	return 0;
521 }
522 
523 /**
524  * proc_int_conv - Change user or kernel pointer based on direction
525  *
526  * @negp: will be passed to uni-directional converters
527  * @u_ptr: pointer to user variable
528  * @k_ptr: pointer to kernel variable
529  * @dir: %TRUE if this is a write to the sysctl file
530  * @tbl: the sysctl table
531  * @k_ptr_range_check: Check range for k_ptr when %TRUE
532  * @user_to_kern: Callback used to assign value from user to kernel var
533  * @kern_to_user: Callback used to assign value from kernel to user var
534  *
535  * When direction is kernel to user, then the u_ptr is modified.
536  * When direction is user to kernel, then the k_ptr is modified.
537  *
538  * Returns: 0 on success
539  */
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))540 int proc_int_conv(bool *negp, ulong *u_ptr, int *k_ptr, int dir,
541 		  const struct ctl_table *tbl, bool k_ptr_range_check,
542 		  int (*user_to_kern)(const bool *negp, const ulong *u_ptr, int *k_ptr),
543 		  int (*kern_to_user)(bool *negp, ulong *u_ptr, const int *k_ptr))
544 {
545 	if (SYSCTL_KERN_TO_USER(dir))
546 		return kern_to_user(negp, u_ptr, k_ptr);
547 
548 	if (k_ptr_range_check) {
549 		int tmp_k, ret;
550 
551 		if (!tbl)
552 			return -EINVAL;
553 		ret = user_to_kern(negp, u_ptr, &tmp_k);
554 		if (ret)
555 			return ret;
556 		if ((tbl->extra1 && *(int *)tbl->extra1 > tmp_k) ||
557 		    (tbl->extra2 && *(int *)tbl->extra2 < tmp_k))
558 			return -EINVAL;
559 		WRITE_ONCE(*k_ptr, tmp_k);
560 	} else
561 		return user_to_kern(negp, u_ptr, k_ptr);
562 	return 0;
563 }
564 
565 
566 
sysctl_user_to_kern_int_conv(const bool * negp,const ulong * u_ptr,int * k_ptr)567 static int sysctl_user_to_kern_int_conv(const bool *negp, const ulong *u_ptr,
568 					int *k_ptr)
569 {
570 	return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, NULL);
571 }
572 
sysctl_kern_to_user_int_conv(bool * negp,ulong * u_ptr,const int * k_ptr)573 static int sysctl_kern_to_user_int_conv(bool *negp, ulong *u_ptr, const int *k_ptr)
574 {
575 	return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, NULL);
576 }
577 
do_proc_int_conv(bool * negp,unsigned long * u_ptr,int * k_ptr,int dir,const struct ctl_table * tbl)578 static int do_proc_int_conv(bool *negp, unsigned long *u_ptr, int *k_ptr,
579 			    int dir, const struct ctl_table *tbl)
580 {
581 	return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false,
582 			     sysctl_user_to_kern_int_conv,
583 			     sysctl_kern_to_user_int_conv);
584 
585 }
586 
do_proc_int_conv_minmax(bool * negp,unsigned long * u_ptr,int * k_ptr,int dir,const struct ctl_table * tbl)587 static int do_proc_int_conv_minmax(bool *negp, unsigned long *u_ptr, int *k_ptr,
588 				   int dir, const struct ctl_table *tbl)
589 {
590 	return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, true,
591 			     sysctl_user_to_kern_int_conv,
592 			     sysctl_kern_to_user_int_conv);
593 }
594 
595 static const char proc_wspace_sep[] = { ' ', '\t', '\n' };
596 
597 /*
598  * Element type processed by do_proc_vec(). The tag selects the element size
599  * and signedness, and it selects which member of union proc_vec_conv is live.
600  */
601 enum proc_vec_type {
602 	PROC_VEC_INT,
603 	PROC_VEC_UINT,
604 	PROC_VEC_ULONG,
605 };
606 
607 /*
608  * Converter passed to do_proc_vec(). Only the member matching the
609  * enum proc_vec_type tag is ever read, so every dispatch stays fully typed and
610  * no void * converter pointer is needed.
611  */
612 union proc_vec_conv {
613 	int (*int_conv)(bool *negp, ulong *u_ptr, int *k_ptr,
614 			int dir, const struct ctl_table *table);
615 	int (*uint_conv)(bool *negp, ulong *u_ptr, uint *k_ptr,
616 			 int dir, const struct ctl_table *table);
617 	int (*ulong_conv)(bool *negp, ulong *u_ptr, ulong *k_ptr,
618 			  int dir, const struct ctl_table *table);
619 };
620 
621 /*
622  * Dispatch to the converter member selected by @type. @k_ptr walks
623  * table->data as raw bytes and is cast back to the element type here.
624  */
proc_vec_conv(enum proc_vec_type type,union proc_vec_conv conv,bool * negp,ulong * u_ptr,char * k_ptr,int dir,const struct ctl_table * table)625 static int proc_vec_conv(enum proc_vec_type type, union proc_vec_conv conv,
626 			 bool *negp, ulong *u_ptr, char *k_ptr, int dir,
627 			 const struct ctl_table *table)
628 {
629 	switch (type) {
630 	case PROC_VEC_INT:
631 		return conv.int_conv(negp, u_ptr, (int *)k_ptr, dir, table);
632 	case PROC_VEC_UINT:
633 		return conv.uint_conv(negp, u_ptr, (uint *)k_ptr, dir, table);
634 	case PROC_VEC_ULONG:
635 		return conv.ulong_conv(negp, u_ptr, (ulong *)k_ptr, dir, table);
636 	}
637 	return -EINVAL;
638 }
639 
640 /*
641  * Read/write a vector of @type elements. The element size and signedness are
642  * derived from @type, so a single runtime function replaces the per-type
643  * variants. table->data is walked as raw bytes (@i) advanced by @size; the
644  * converter performs the actual typed load/store.
645  */
do_proc_vec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,enum proc_vec_type type,union proc_vec_conv conv)646 static int do_proc_vec(const struct ctl_table *table, int dir,
647 		       void *buffer, size_t *lenp, loff_t *ppos,
648 		       enum proc_vec_type type, union proc_vec_conv conv)
649 {
650 	int vleft, first = 1, err = 0;
651 	size_t left, size;
652 	bool is_unsigned;
653 	char *i, *p;
654 
655 	switch (type) {
656 	case PROC_VEC_INT:
657 		size = sizeof(int);
658 		is_unsigned = false;
659 		break;
660 	case PROC_VEC_UINT:
661 		size = sizeof(uint);
662 		is_unsigned = true;
663 		break;
664 	case PROC_VEC_ULONG:
665 		size = sizeof(ulong);
666 		is_unsigned = true;
667 		break;
668 	default:
669 		return -EINVAL;
670 	}
671 
672 	if (!table->data || !table->maxlen || !*lenp ||
673 	    (*ppos && SYSCTL_KERN_TO_USER(dir))) {
674 		*lenp = 0;
675 		return 0;
676 	}
677 
678 	i = table->data;
679 	vleft = table->maxlen / size;
680 	left = *lenp;
681 
682 	/* uint arrays are not supported, *Do not* add support for them. */
683 	if (type == PROC_VEC_UINT && vleft != 1)
684 		return -EINVAL;
685 
686 	if (SYSCTL_USER_TO_KERN(dir)) {
687 		if (proc_first_pos_non_zero_ignore(ppos, table))
688 			goto out;
689 
690 		if (left > PAGE_SIZE - 1)
691 			left = PAGE_SIZE - 1;
692 		p = buffer;
693 	}
694 
695 	for (; left && vleft--; i += size, first = 0) {
696 		unsigned long lval;
697 		bool neg = false;
698 
699 		if (SYSCTL_USER_TO_KERN(dir)) {
700 			proc_skip_spaces(&p, &left);
701 
702 			if (!left)
703 				break;
704 			err = proc_get_long(&p, &left, &lval, &neg,
705 					    proc_wspace_sep,
706 					    sizeof(proc_wspace_sep), NULL);
707 			if (!err && neg && is_unsigned)
708 				err = -EINVAL;
709 			if (err)
710 				break;
711 			if (proc_vec_conv(type, conv, &neg, &lval, i, dir, table)) {
712 				err = -EINVAL;
713 				break;
714 			}
715 		} else {
716 			if (proc_vec_conv(type, conv, &neg, &lval, i, dir, table)) {
717 				err = -EINVAL;
718 				break;
719 			}
720 			if (!first)
721 				proc_put_char(&buffer, &left, '\t');
722 			proc_put_long(&buffer, &left, lval, neg);
723 		}
724 	}
725 
726 	if (SYSCTL_KERN_TO_USER(dir) && !first && left && !err)
727 		proc_put_char(&buffer, &left, '\n');
728 	if (SYSCTL_USER_TO_KERN(dir) && !err && left)
729 		proc_skip_spaces(&p, &left);
730 	if (SYSCTL_USER_TO_KERN(dir) && first)
731 		return err ? : -EINVAL;
732 	*lenp -= left;
733 out:
734 	*ppos += *lenp;
735 	return err;
736 }
737 
738 /**
739  * proc_douintvec_conv - read a vector of unsigned ints with a custom converter
740  *
741  * @table: the sysctl table
742  * @dir: %TRUE if this is a write to the sysctl file
743  * @buffer: the user buffer
744  * @lenp: the size of the user buffer
745  * @ppos: file position
746  * @conv: Custom converter call back
747  *
748  * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
749  * values from/to the user buffer, treated as an ASCII string. Negative
750  * strings are not allowed.
751  *
752  * Returns: %0 on success
753  */
proc_douintvec_conv(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(bool * negp,ulong * u_ptr,uint * k_ptr,int dir,const struct ctl_table * table))754 int proc_douintvec_conv(const struct ctl_table *table, int dir, void *buffer,
755 			size_t *lenp, loff_t *ppos,
756 			int (*conv)(bool *negp, ulong *u_ptr, uint *k_ptr,
757 				    int dir, const struct ctl_table *table))
758 {
759 
760 	if (!conv)
761 		conv = do_proc_uint_conv;
762 
763 	return do_proc_vec(table, dir, buffer, lenp, ppos, PROC_VEC_UINT,
764 			   (union proc_vec_conv){ .uint_conv = conv });
765 }
766 
767 /**
768  * proc_dobool - read/write a bool
769  * @table: the sysctl table
770  * @dir: %TRUE if this is a write to the sysctl file
771  * @buffer: the user buffer
772  * @lenp: the size of the user buffer
773  * @ppos: file position
774  *
775  * Reads/writes one integer value from/to the user buffer,
776  * treated as an ASCII string.
777  *
778  * table->data must point to a bool variable and table->maxlen must
779  * be sizeof(bool).
780  *
781  * Returns: %0 on success.
782  */
proc_dobool(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)783 int proc_dobool(const struct ctl_table *table, int dir, void *buffer,
784 		size_t *lenp, loff_t *ppos)
785 {
786 	struct ctl_table tmp;
787 	bool *data = table->data;
788 	int res, val;
789 
790 	/* Do not support arrays yet. */
791 	if (table->maxlen != sizeof(bool))
792 		return -EINVAL;
793 
794 	tmp = *table;
795 	tmp.maxlen = sizeof(val);
796 	tmp.data = &val;
797 
798 	val = READ_ONCE(*data);
799 	res = proc_dointvec(&tmp, dir, buffer, lenp, ppos);
800 	if (res)
801 		return res;
802 	if (SYSCTL_USER_TO_KERN(dir))
803 		WRITE_ONCE(*data, val);
804 	return 0;
805 }
806 
807 /**
808  * proc_dointvec - read a vector of integers
809  * @table: the sysctl table
810  * @dir: %TRUE if this is a write to the sysctl file
811  * @buffer: the user buffer
812  * @lenp: the size of the user buffer
813  * @ppos: file position
814  *
815  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
816  * values from/to the user buffer, treated as an ASCII string.
817  *
818  * Returns: %0 on success.
819  */
proc_dointvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)820 int proc_dointvec(const struct ctl_table *table, int dir, void *buffer,
821 		  size_t *lenp, loff_t *ppos)
822 {
823 	return do_proc_vec(table, dir, buffer, lenp, ppos, PROC_VEC_INT,
824 			   (union proc_vec_conv){ .int_conv = do_proc_int_conv });
825 }
826 
827 /**
828  * proc_douintvec - read a vector of unsigned 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) unsigned integer
836  * values from/to the user buffer, treated as an ASCII string.
837  *
838  * Returns: %0 on success.
839  */
proc_douintvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)840 int proc_douintvec(const struct ctl_table *table, int dir, void *buffer,
841 		size_t *lenp, loff_t *ppos)
842 {
843 	return do_proc_vec(table, dir, buffer, lenp, ppos, PROC_VEC_UINT,
844 			   (union proc_vec_conv){ .uint_conv = do_proc_uint_conv });
845 }
846 
847 /**
848  * proc_dointvec_minmax - read a vector of integers with min/max values
849  * @table: the sysctl table
850  * @dir: %TRUE if this is a write to the sysctl file
851  * @buffer: the user buffer
852  * @lenp: the size of the user buffer
853  * @ppos: file position
854  *
855  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
856  * values from/to the user buffer, treated as an ASCII string.
857  *
858  * This routine will ensure the values are within the range specified by
859  * table->extra1 (min) and table->extra2 (max).
860  *
861  * Returns: %0 on success or -EINVAL when the range check fails and
862  * SYSCTL_USER_TO_KERN(dir) == true
863  */
proc_dointvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)864 int proc_dointvec_minmax(const struct ctl_table *table, int dir,
865 		  void *buffer, size_t *lenp, loff_t *ppos)
866 {
867 	return do_proc_vec(table, dir, buffer, lenp, ppos, PROC_VEC_INT,
868 			   (union proc_vec_conv){ .int_conv = do_proc_int_conv_minmax });
869 }
870 
871 /**
872  * proc_douintvec_minmax - read a vector of unsigned ints with min/max values
873  * @table: the sysctl table
874  * @dir: %TRUE if this is a write to the sysctl file
875  * @buffer: the user buffer
876  * @lenp: the size of the user buffer
877  * @ppos: file position
878  *
879  * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer
880  * values from/to the user buffer, treated as an ASCII string. Negative
881  * strings are not allowed.
882  *
883  * When changing the kernel variable, this routine will ensure the values
884  * are within the range specified by table->extra1 (min) and table->extra2
885  * (max). And Check that the values are less than UINT_MAX to avoid having to
886  * support wrap around uses from userspace.
887  *
888  * Returns: %0 on success or -ERANGE when range check failes and
889  * SYSCTL_USER_TO_KERN(dir) == true
890  */
proc_douintvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)891 int proc_douintvec_minmax(const struct ctl_table *table, int dir,
892 			  void *buffer, size_t *lenp, loff_t *ppos)
893 {
894 	return do_proc_vec(table, dir, buffer, lenp, ppos, PROC_VEC_UINT,
895 			   (union proc_vec_conv){ .uint_conv = do_proc_uint_conv_minmax });
896 }
897 
898 /**
899  * proc_dou8vec_minmax - read a vector of unsigned chars with min/max values
900  * @table: the sysctl table
901  * @dir: %TRUE if this is a write to the sysctl file
902  * @buffer: the user buffer
903  * @lenp: the size of the user buffer
904  * @ppos: file position
905  *
906  * Reads/writes up to table->maxlen/sizeof(u8) unsigned chars
907  * values from/to the user buffer, treated as an ASCII string. Negative
908  * strings are not allowed.
909  *
910  * This routine will ensure the values are within the range specified by
911  * table->extra1 (min) and table->extra2 (max).
912  *
913  * Returns: %0 on success or an error on SYSCTL_USER_TO_KERN(dir) == true
914  * and the range check fails.
915  */
proc_dou8vec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)916 int proc_dou8vec_minmax(const struct ctl_table *table, int dir,
917 			void *buffer, size_t *lenp, loff_t *ppos)
918 {
919 	struct ctl_table tmp;
920 	unsigned int min = 0, max = 255U, val;
921 	u8 *data = table->data;
922 	int res;
923 
924 	/* Do not support arrays yet. */
925 	if (table->maxlen != sizeof(u8))
926 		return -EINVAL;
927 
928 	tmp = *table;
929 
930 	tmp.maxlen = sizeof(val);
931 	tmp.data = &val;
932 	if (!tmp.extra1)
933 		tmp.extra1 = (unsigned int *) &min;
934 	if (!tmp.extra2)
935 		tmp.extra2 = (unsigned int *) &max;
936 
937 	val = READ_ONCE(*data);
938 	res = do_proc_vec(&tmp, dir, buffer, lenp, ppos, PROC_VEC_UINT,
939 			  (union proc_vec_conv){ .uint_conv = do_proc_uint_conv_minmax });
940 	if (res)
941 		return res;
942 	if (SYSCTL_USER_TO_KERN(dir))
943 		WRITE_ONCE(*data, val);
944 	return 0;
945 }
946 EXPORT_SYMBOL_GPL(proc_dou8vec_minmax);
947 
948 /**
949  * proc_ulong_conv - Change user or kernel pointer based on direction
950  *
951  * @u_ptr: pointer to user variable
952  * @k_ptr: pointer to kernel variable
953  * @dir: %TRUE if this is a write to the sysctl file
954  * @tbl: the sysctl table
955  * @k_ptr_range_check: Check range for k_ptr when %TRUE
956  * @user_to_kern: Callback used to assign value from user to kernel var
957  * @kern_to_user: Callback used to assign value from kernel to user var
958  *
959  * When direction is kernel to user, then the u_ptr is modified.
960  * When direction is user to kernel, then the k_ptr is modified.
961  *
962  * Returns: 0 on success
963  */
proc_ulong_conv(ulong * u_ptr,ulong * k_ptr,int dir,const struct ctl_table * tbl,bool k_ptr_range_check,int (* user_to_kern)(const ulong * u_ptr,ulong * k_ptr),int (* kern_to_user)(ulong * u_ptr,const ulong * k_ptr))964 int proc_ulong_conv(ulong *u_ptr, ulong *k_ptr, int dir,
965 		    const struct ctl_table *tbl, bool k_ptr_range_check,
966 		    int (*user_to_kern)(const ulong *u_ptr, ulong *k_ptr),
967 		    int (*kern_to_user)(ulong *u_ptr, const ulong *k_ptr))
968 {
969 	if (SYSCTL_KERN_TO_USER(dir))
970 		return kern_to_user(u_ptr, k_ptr);
971 
972 	if (k_ptr_range_check) {
973 		ulong tmp_k;
974 		int ret;
975 
976 		if (!tbl)
977 			return -EINVAL;
978 		ret = user_to_kern(u_ptr, &tmp_k);
979 		if (ret)
980 			return ret;
981 		if ((tbl->extra1 && *(ulong *)tbl->extra1 > tmp_k) ||
982 		    (tbl->extra2 && *(ulong *)tbl->extra2 < tmp_k))
983 			return -ERANGE;
984 		WRITE_ONCE(*k_ptr, tmp_k);
985 	} else
986 		return user_to_kern(u_ptr, k_ptr);
987 	return 0;
988 }
989 
990 /**
991  * proc_ulong_u2k_conv_uop - Assign user value to a kernel pointer
992  *
993  * @u_ptr: pointer to user space variable
994  * @k_ptr: pointer to kernel variable
995  * @u_ptr_op: execute this function before assigning to k_ptr
996  *
997  * Uses WRITE_ONCE to assign value to k_ptr. Executes u_ptr_op if
998  * not NULL.
999  *
1000  * Returns: 0 on success.
1001  */
proc_ulong_u2k_conv_uop(const ulong * u_ptr,ulong * k_ptr,ulong (* u_ptr_op)(const ulong))1002 int proc_ulong_u2k_conv_uop(const ulong *u_ptr, ulong *k_ptr,
1003 			    ulong (*u_ptr_op)(const ulong))
1004 {
1005 	ulong u = u_ptr_op ? u_ptr_op(*u_ptr) : *u_ptr;
1006 
1007 	WRITE_ONCE(*k_ptr, u);
1008 	return 0;
1009 }
1010 
proc_ulong_u2k_conv(const ulong * u_ptr,ulong * k_ptr)1011 static int proc_ulong_u2k_conv(const ulong *u_ptr, ulong *k_ptr)
1012 {
1013 	return proc_ulong_u2k_conv_uop(u_ptr, k_ptr, NULL);
1014 }
1015 
1016 /**
1017  * proc_ulong_k2u_conv_kop - Assign kernel value to a user space pointer
1018  *
1019  * @u_ptr: pointer to user space variable
1020  * @k_ptr: pointer to kernel variable
1021  * @k_ptr_op: Operation applied to k_ptr before assignment
1022  *
1023  * Uses READ_ONCE to assign value to u_ptr. Executes k_ptr_op if
1024  * not NULL.
1025  *
1026  * Returns: 0 on success.
1027  */
proc_ulong_k2u_conv_kop(ulong * u_ptr,const ulong * k_ptr,ulong (* k_ptr_op)(const ulong))1028 int proc_ulong_k2u_conv_kop(ulong *u_ptr, const ulong *k_ptr,
1029 			    ulong (*k_ptr_op)(const ulong))
1030 {
1031 	ulong val = k_ptr_op ? k_ptr_op(READ_ONCE(*k_ptr)) : READ_ONCE(*k_ptr);
1032 	*u_ptr = (ulong)val;
1033 	return 0;
1034 }
1035 
proc_ulong_k2u_conv(ulong * u_ptr,const ulong * k_ptr)1036 static int proc_ulong_k2u_conv(ulong *u_ptr, const ulong *k_ptr)
1037 {
1038 	return proc_ulong_k2u_conv_kop(u_ptr, k_ptr, NULL);
1039 }
1040 
do_proc_ulong_conv(bool * negp,ulong * u_ptr,ulong * k_ptr,int dir,const struct ctl_table * tbl)1041 static int do_proc_ulong_conv(bool *negp, ulong *u_ptr, ulong *k_ptr, int dir,
1042 			      const struct ctl_table *tbl)
1043 {
1044 	return proc_ulong_conv(u_ptr, k_ptr, dir, tbl, true,
1045 			       proc_ulong_u2k_conv, proc_ulong_k2u_conv);
1046 }
1047 
1048 /**
1049  * proc_doulongvec_conv - read a vector of unsigned longs with a custom converter
1050  *
1051  * @table: the sysctl table
1052  * @dir: %TRUE if this is a write to the sysctl file
1053  * @buffer: the user buffer
1054  * @lenp: the size of the user buffer
1055  * @ppos: file position
1056  * @conv: Custom converter call back
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. Negative
1060  * strings are not allowed.
1061  *
1062  * Returns: 0 on success
1063  */
proc_doulongvec_conv(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(bool * negp,ulong * u_ptr,ulong * k_ptr,int dir,const struct ctl_table * table))1064 int proc_doulongvec_conv(const struct ctl_table *table, int dir,
1065 				void *buffer, size_t *lenp, loff_t *ppos,
1066 				int (*conv)(bool *negp, ulong *u_ptr, ulong *k_ptr,
1067 					    int dir, const struct ctl_table *table))
1068 {
1069 	return do_proc_vec(table, dir, buffer, lenp, ppos, PROC_VEC_ULONG,
1070 			   (union proc_vec_conv){ .ulong_conv = conv });
1071 }
1072 
1073 /**
1074  * proc_doulongvec_minmax - read a vector of long integers with min/max values
1075  * @table: the sysctl table
1076  * @dir: %TRUE if this is a write to the sysctl file
1077  * @buffer: the user buffer
1078  * @lenp: the size of the user buffer
1079  * @ppos: file position
1080  *
1081  * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long
1082  * values from/to the user buffer, treated as an ASCII string.
1083  *
1084  * This routine will ensure the values are within the range specified by
1085  * table->extra1 (min) and table->extra2 (max).
1086  *
1087  * Returns: %0 on success.
1088  */
proc_doulongvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1089 int proc_doulongvec_minmax(const struct ctl_table *table, int dir,
1090 			   void *buffer, size_t *lenp, loff_t *ppos)
1091 {
1092 	return do_proc_vec(table, dir, buffer, lenp, ppos, PROC_VEC_ULONG,
1093 			   (union proc_vec_conv){ .ulong_conv = do_proc_ulong_conv });
1094 }
1095 
1096 /**
1097  * proc_dointvec_conv - read a vector of ints with a custom converter
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  * @conv: Custom converter call back. Defaults to do_proc_int_conv
1104  *
1105  * Reads/writes up to table->maxlen/sizeof(int) integer values from/to the
1106  * user buffer, treated as an ASCII string.
1107  *
1108  * Returns: 0 on success
1109  */
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))1110 int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
1111 		       size_t *lenp, loff_t *ppos,
1112 		       int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
1113 				   int dir, const struct ctl_table *table))
1114 {
1115 	if (!conv)
1116 		conv = do_proc_int_conv;
1117 	return do_proc_vec(table, dir, buffer, lenp, ppos, PROC_VEC_INT,
1118 			   (union proc_vec_conv){ .int_conv = conv });
1119 }
1120 
1121 /**
1122  * proc_do_large_bitmap - read/write from/to a large bitmap
1123  * @table: the sysctl table
1124  * @dir: %TRUE if this is a write to the sysctl file
1125  * @buffer: the user buffer
1126  * @lenp: the size of the user buffer
1127  * @ppos: file position
1128  *
1129  * The bitmap is stored at table->data and the bitmap length (in bits)
1130  * in table->maxlen.
1131  *
1132  * We use a range comma separated format (e.g. 1,3-4,10-10) so that
1133  * large bitmaps may be represented in a compact manner. Writing into
1134  * the file will clear the bitmap then update it with the given input.
1135  *
1136  * Returns: %0 on success.
1137  */
proc_do_large_bitmap(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1138 int proc_do_large_bitmap(const struct ctl_table *table, int dir,
1139 			 void *buffer, size_t *lenp, loff_t *ppos)
1140 {
1141 	int err = 0;
1142 	size_t left = *lenp;
1143 	unsigned long bitmap_len = table->maxlen;
1144 	unsigned long *bitmap = *(unsigned long **) table->data;
1145 	unsigned long *tmp_bitmap = NULL;
1146 	char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c = 0;
1147 
1148 	if (!bitmap || !bitmap_len || !left || (*ppos && SYSCTL_KERN_TO_USER(dir))) {
1149 		*lenp = 0;
1150 		return 0;
1151 	}
1152 
1153 	if (SYSCTL_USER_TO_KERN(dir)) {
1154 		char *p = buffer;
1155 		size_t skipped = 0;
1156 
1157 		if (left > PAGE_SIZE - 1) {
1158 			left = PAGE_SIZE - 1;
1159 			/* How much of the buffer we'll skip this pass */
1160 			skipped = *lenp - left;
1161 		}
1162 
1163 		tmp_bitmap = bitmap_zalloc(bitmap_len, GFP_KERNEL);
1164 		if (!tmp_bitmap)
1165 			return -ENOMEM;
1166 		proc_skip_char(&p, &left, '\n');
1167 		while (!err && left) {
1168 			unsigned long val_a, val_b;
1169 			bool neg;
1170 			size_t saved_left;
1171 
1172 			/* In case we stop parsing mid-number, we can reset */
1173 			saved_left = left;
1174 			err = proc_get_long(&p, &left, &val_a, &neg, tr_a,
1175 					     sizeof(tr_a), &c);
1176 			/*
1177 			 * If we consumed the entirety of a truncated buffer or
1178 			 * only one char is left (may be a "-"), then stop here,
1179 			 * reset, & come back for more.
1180 			 */
1181 			if ((left <= 1) && skipped) {
1182 				left = saved_left;
1183 				break;
1184 			}
1185 
1186 			if (err)
1187 				break;
1188 			if (val_a >= bitmap_len || neg) {
1189 				err = -EINVAL;
1190 				break;
1191 			}
1192 
1193 			val_b = val_a;
1194 			if (left) {
1195 				p++;
1196 				left--;
1197 			}
1198 
1199 			if (c == '-') {
1200 				err = proc_get_long(&p, &left, &val_b,
1201 						     &neg, tr_b, sizeof(tr_b),
1202 						     &c);
1203 				/*
1204 				 * If we consumed all of a truncated buffer or
1205 				 * then stop here, reset, & come back for more.
1206 				 */
1207 				if (!left && skipped) {
1208 					left = saved_left;
1209 					break;
1210 				}
1211 
1212 				if (err)
1213 					break;
1214 				if (val_b >= bitmap_len || neg ||
1215 				    val_a > val_b) {
1216 					err = -EINVAL;
1217 					break;
1218 				}
1219 				if (left) {
1220 					p++;
1221 					left--;
1222 				}
1223 			}
1224 
1225 			bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1);
1226 			proc_skip_char(&p, &left, '\n');
1227 		}
1228 		left += skipped;
1229 	} else {
1230 		unsigned long bit_a, bit_b = 0;
1231 		bool first = 1;
1232 
1233 		while (left) {
1234 			bit_a = find_next_bit(bitmap, bitmap_len, bit_b);
1235 			if (bit_a >= bitmap_len)
1236 				break;
1237 			bit_b = find_next_zero_bit(bitmap, bitmap_len,
1238 						   bit_a + 1) - 1;
1239 
1240 			if (!first)
1241 				proc_put_char(&buffer, &left, ',');
1242 			proc_put_long(&buffer, &left, bit_a, false);
1243 			if (bit_a != bit_b) {
1244 				proc_put_char(&buffer, &left, '-');
1245 				proc_put_long(&buffer, &left, bit_b, false);
1246 			}
1247 
1248 			first = 0; bit_b++;
1249 		}
1250 		proc_put_char(&buffer, &left, '\n');
1251 	}
1252 
1253 	if (!err) {
1254 		if (SYSCTL_USER_TO_KERN(dir)) {
1255 			if (*ppos)
1256 				bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len);
1257 			else
1258 				bitmap_copy(bitmap, tmp_bitmap, bitmap_len);
1259 		}
1260 		*lenp -= left;
1261 		*ppos += *lenp;
1262 	}
1263 
1264 	bitmap_free(tmp_bitmap);
1265 	return err;
1266 }
1267 
1268 #else /* CONFIG_SYSCTL */
1269 
proc_dostring(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1270 int proc_dostring(const struct ctl_table *table, int dir,
1271 		  void *buffer, size_t *lenp, loff_t *ppos)
1272 {
1273 	return -ENOSYS;
1274 }
1275 
proc_dobool(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1276 int proc_dobool(const struct ctl_table *table, int dir,
1277 		void *buffer, size_t *lenp, loff_t *ppos)
1278 {
1279 	return -ENOSYS;
1280 }
1281 
proc_dointvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1282 int proc_dointvec(const struct ctl_table *table, int dir,
1283 		  void *buffer, size_t *lenp, loff_t *ppos)
1284 {
1285 	return -ENOSYS;
1286 }
1287 
proc_douintvec(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1288 int proc_douintvec(const struct ctl_table *table, int dir,
1289 		  void *buffer, size_t *lenp, loff_t *ppos)
1290 {
1291 	return -ENOSYS;
1292 }
1293 
proc_dointvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1294 int proc_dointvec_minmax(const struct ctl_table *table, int dir,
1295 		    void *buffer, size_t *lenp, loff_t *ppos)
1296 {
1297 	return -ENOSYS;
1298 }
1299 
proc_douintvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1300 int proc_douintvec_minmax(const struct ctl_table *table, int dir,
1301 			  void *buffer, size_t *lenp, loff_t *ppos)
1302 {
1303 	return -ENOSYS;
1304 }
1305 
proc_douintvec_conv(const struct ctl_table * table,int write,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(bool * negp,ulong * lvalp,uint * valp,int write,const struct ctl_table * table))1306 int proc_douintvec_conv(const struct ctl_table *table, int write, void *buffer,
1307 			size_t *lenp, loff_t *ppos,
1308 			int (*conv)(bool *negp, ulong *lvalp, uint *valp,
1309 				    int write, const struct ctl_table *table))
1310 {
1311 	return -ENOSYS;
1312 }
1313 
proc_uint_k2u_conv(ulong * u_ptr,const uint * k_ptr)1314 int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr)
1315 {
1316 	return -ENOSYS;
1317 }
1318 
proc_uint_u2k_conv_uop(const ulong * u_ptr,uint * k_ptr,ulong (* u_ptr_op)(const ulong))1319 int proc_uint_u2k_conv_uop(const ulong *u_ptr, uint *k_ptr,
1320 			   ulong (*u_ptr_op)(const ulong))
1321 {
1322 	return -ENOSYS;
1323 }
1324 
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))1325 int proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir,
1326 		   const struct ctl_table *tbl, bool k_ptr_range_check,
1327 		   int (*user_to_kern)(const ulong *u_ptr, uint *k_ptr),
1328 		   int (*kern_to_user)(ulong *u_ptr, const uint *k_ptr))
1329 {
1330 	return -ENOSYS;
1331 }
1332 
proc_dou8vec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1333 int proc_dou8vec_minmax(const struct ctl_table *table, int dir,
1334 			void *buffer, size_t *lenp, loff_t *ppos)
1335 {
1336 	return -ENOSYS;
1337 }
1338 
proc_doulongvec_minmax(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1339 int proc_doulongvec_minmax(const struct ctl_table *table, int dir,
1340 		    void *buffer, size_t *lenp, loff_t *ppos)
1341 {
1342 	return -ENOSYS;
1343 }
1344 
proc_doulongvec_conv(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos,int (* conv)(bool * negp,ulong * u_ptr,ulong * k_ptr,int dir,const struct ctl_table * table))1345 int proc_doulongvec_conv(const struct ctl_table *table, int dir,
1346 				void *buffer, size_t *lenp, loff_t *ppos,
1347 				int (*conv)(bool *negp, ulong *u_ptr, ulong *k_ptr,
1348 					    int dir, const struct ctl_table *table))
1349 {
1350 	return -ENOSYS;
1351 }
1352 
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))1353 int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer,
1354 		       size_t *lenp, loff_t *ppos,
1355 		       int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr,
1356 				   int dir, const struct ctl_table *table))
1357 {
1358 	return -ENOSYS;
1359 }
1360 
proc_do_large_bitmap(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1361 int proc_do_large_bitmap(const struct ctl_table *table, int dir,
1362 			 void *buffer, size_t *lenp, loff_t *ppos)
1363 {
1364 	return -ENOSYS;
1365 }
1366 
1367 #endif /* CONFIG_SYSCTL */
1368 
1369 #if defined(CONFIG_SYSCTL)
proc_do_static_key(const struct ctl_table * table,int dir,void * buffer,size_t * lenp,loff_t * ppos)1370 int proc_do_static_key(const struct ctl_table *table, int dir,
1371 		       void *buffer, size_t *lenp, loff_t *ppos)
1372 {
1373 	struct static_key *key = (struct static_key *)table->data;
1374 	static DEFINE_MUTEX(static_key_mutex);
1375 	int val, ret;
1376 	struct ctl_table tmp = {
1377 		.data   = &val,
1378 		.maxlen = sizeof(val),
1379 		.mode   = table->mode,
1380 		.extra1 = SYSCTL_ZERO,
1381 		.extra2 = SYSCTL_ONE,
1382 	};
1383 
1384 	if (SYSCTL_USER_TO_KERN(dir) && !capable(CAP_SYS_ADMIN))
1385 		return -EPERM;
1386 
1387 	mutex_lock(&static_key_mutex);
1388 	val = static_key_enabled(key);
1389 	ret = proc_dointvec_minmax(&tmp, dir, buffer, lenp, ppos);
1390 	if (SYSCTL_USER_TO_KERN(dir) && !ret) {
1391 		if (val)
1392 			static_key_enable(key);
1393 		else
1394 			static_key_disable(key);
1395 	}
1396 	mutex_unlock(&static_key_mutex);
1397 	return ret;
1398 }
1399 
1400 static const struct ctl_table sysctl_subsys_table[] = {
1401 #ifdef CONFIG_SYSCTL
1402 	{
1403 		.procname	= "sysctl_writes_strict",
1404 		.data		= &sysctl_writes_strict,
1405 		.maxlen		= sizeof(int),
1406 		.mode		= 0644,
1407 		.proc_handler	= proc_dointvec_minmax,
1408 		.extra1		= SYSCTL_NEG_ONE,
1409 		.extra2		= SYSCTL_ONE,
1410 	},
1411 #endif
1412 	{
1413 		.procname	= "ngroups_max",
1414 		.data		= (void *)&ngroups_max,
1415 		.maxlen		= sizeof (int),
1416 		.mode		= 0444,
1417 		.proc_handler	= proc_dointvec,
1418 	},
1419 	{
1420 		.procname	= "cap_last_cap",
1421 		.data		= (void *)&cap_last_cap,
1422 		.maxlen		= sizeof(int),
1423 		.mode		= 0444,
1424 		.proc_handler	= proc_dointvec,
1425 	},
1426 #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW
1427 	{
1428 		.procname	= "unaligned-trap",
1429 		.data		= &unaligned_enabled,
1430 		.maxlen		= sizeof(int),
1431 		.mode		= 0644,
1432 		.proc_handler	= proc_dointvec,
1433 	},
1434 #endif
1435 #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN
1436 	{
1437 		.procname	= "ignore-unaligned-usertrap",
1438 		.data		= &no_unaligned_warning,
1439 		.maxlen		= sizeof (int),
1440 		.mode		= 0644,
1441 		.proc_handler	= proc_dointvec,
1442 	},
1443 #endif
1444 };
1445 
sysctl_init_bases(void)1446 int __init sysctl_init_bases(void)
1447 {
1448 	register_sysctl_init("kernel", sysctl_subsys_table);
1449 
1450 	return 0;
1451 }
1452 #endif /* CONFIG_SYSCTL */
1453 /*
1454  * No sense putting this after each symbol definition, twice,
1455  * exception granted :-)
1456  */
1457 EXPORT_SYMBOL(proc_dobool);
1458 EXPORT_SYMBOL(proc_dointvec);
1459 EXPORT_SYMBOL(proc_douintvec);
1460 EXPORT_SYMBOL(proc_dointvec_minmax);
1461 EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
1462 EXPORT_SYMBOL(proc_dostring);
1463 EXPORT_SYMBOL(proc_doulongvec_minmax);
1464 EXPORT_SYMBOL(proc_do_large_bitmap);
1465