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