1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * sysctl.c: General linux system control interface 4 */ 5 6 #include <linux/sysctl.h> 7 #include <linux/bitmap.h> 8 #include <linux/proc_fs.h> 9 #include <linux/ctype.h> 10 #include <linux/init.h> 11 #include <linux/kernel.h> 12 #include <linux/kobject.h> 13 #include <linux/highuid.h> 14 #include <linux/writeback.h> 15 #include <linux/initrd.h> 16 #include <linux/limits.h> 17 #include <linux/syscalls.h> 18 #include <linux/capability.h> 19 20 #include "../lib/kstrtox.h" 21 22 #include <linux/uaccess.h> 23 #include <asm/processor.h> 24 25 /* shared constants to be used in various sysctls */ 26 const int sysctl_vals[] = { 0, 1, 2, 3, 4, 100, 200, 1000, 3000, INT_MAX, 65535, -1 }; 27 EXPORT_SYMBOL(sysctl_vals); 28 29 const unsigned long sysctl_long_vals[] = { 0, 1, LONG_MAX }; 30 EXPORT_SYMBOL_GPL(sysctl_long_vals); 31 32 #if defined(CONFIG_SYSCTL) 33 34 /* Constants used for minimum and maximum */ 35 static const int ngroups_max = NGROUPS_MAX; 36 static const int cap_last_cap = CAP_LAST_CAP; 37 38 #ifdef CONFIG_PROC_SYSCTL 39 40 /** 41 * enum sysctl_writes_mode - supported sysctl write modes 42 * 43 * @SYSCTL_WRITES_LEGACY: each write syscall must fully contain the sysctl value 44 * to be written, and multiple writes on the same sysctl file descriptor 45 * will rewrite the sysctl value, regardless of file position. No warning 46 * is issued when the initial position is not 0. 47 * @SYSCTL_WRITES_WARN: same as above but warn when the initial file position is 48 * not 0. 49 * @SYSCTL_WRITES_STRICT: writes to numeric sysctl entries must always be at 50 * file position 0 and the value must be fully contained in the buffer 51 * sent to the write syscall. If dealing with strings respect the file 52 * position, but restrict this to the max length of the buffer, anything 53 * passed the max length will be ignored. Multiple writes will append 54 * to the buffer. 55 * 56 * These write modes control how current file position affects the behavior of 57 * updating internal kernel (SYSCTL_USER_TO_KERN) sysctl values through the proc 58 * interface on each write. 59 */ 60 enum sysctl_writes_mode { 61 SYSCTL_WRITES_LEGACY = -1, 62 SYSCTL_WRITES_WARN = 0, 63 SYSCTL_WRITES_STRICT = 1, 64 }; 65 66 static enum sysctl_writes_mode sysctl_writes_strict = SYSCTL_WRITES_STRICT; 67 #endif /* CONFIG_PROC_SYSCTL */ 68 #endif /* CONFIG_SYSCTL */ 69 70 /* 71 * /proc/sys support 72 */ 73 74 #ifdef CONFIG_PROC_SYSCTL 75 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 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 */ 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 */ 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 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 209 static void proc_skip_char(char **buf, size_t *size, const char v) 210 { 211 while (*size) { 212 if (**buf != v) 213 break; 214 (*size)--; 215 (*buf)++; 216 } 217 } 218 219 /** 220 * strtoul_lenient - parse an ASCII formatted integer from a buffer and only 221 * fail on overflow 222 * 223 * @cp: kernel buffer containing the string to parse 224 * @endp: pointer to store the trailing characters 225 * @base: the base to use 226 * @res: where the parsed integer will be stored 227 * 228 * In case of success 0 is returned and @res will contain the parsed integer, 229 * @endp will hold any trailing characters. 230 * This function will fail the parse on overflow. If there wasn't an overflow 231 * the function will defer the decision what characters count as invalid to the 232 * caller. 233 */ 234 static int strtoul_lenient(const char *cp, char **endp, unsigned int base, 235 unsigned long *res) 236 { 237 unsigned long long result; 238 unsigned int rv; 239 240 cp = _parse_integer_fixup_radix(cp, &base); 241 rv = _parse_integer(cp, base, &result); 242 if ((rv & KSTRTOX_OVERFLOW) || (result != (unsigned long)result)) 243 return -ERANGE; 244 245 cp += rv; 246 247 if (endp) 248 *endp = (char *)cp; 249 250 *res = (unsigned long)result; 251 return 0; 252 } 253 254 #define TMPBUFLEN 22 255 /** 256 * proc_get_long - reads an ASCII formatted integer from a user buffer 257 * 258 * @buf: a kernel buffer 259 * @size: size of the kernel buffer 260 * @val: this is where the number will be stored 261 * @neg: set to %TRUE if number is negative 262 * @perm_tr: a vector which contains the allowed trailers 263 * @perm_tr_len: size of the perm_tr vector 264 * @tr: pointer to store the trailer character 265 * 266 * In case of success %0 is returned and @buf and @size are updated with 267 * the amount of bytes read. If @tr is non-NULL and a trailing 268 * character exists (size is non-zero after returning from this 269 * function), @tr is updated with the trailing character. 270 */ 271 static int proc_get_long(char **buf, size_t *size, 272 unsigned long *val, bool *neg, 273 const char *perm_tr, unsigned perm_tr_len, char *tr) 274 { 275 char *p, tmp[TMPBUFLEN]; 276 ssize_t len = *size; 277 278 if (len <= 0) 279 return -EINVAL; 280 281 if (len > TMPBUFLEN - 1) 282 len = TMPBUFLEN - 1; 283 284 memcpy(tmp, *buf, len); 285 286 tmp[len] = 0; 287 p = tmp; 288 if (*p == '-' && *size > 1) { 289 *neg = true; 290 p++; 291 } else 292 *neg = false; 293 if (!isdigit(*p)) 294 return -EINVAL; 295 296 if (strtoul_lenient(p, &p, 0, val)) 297 return -EINVAL; 298 299 len = p - tmp; 300 301 /* We don't know if the next char is whitespace thus we may accept 302 * invalid integers (e.g. 1234...a) or two integers instead of one 303 * (e.g. 123...1). So lets not allow such large numbers. */ 304 if (len == TMPBUFLEN - 1) 305 return -EINVAL; 306 307 if (len < *size && perm_tr_len && !memchr(perm_tr, *p, perm_tr_len)) 308 return -EINVAL; 309 310 if (tr && (len < *size)) 311 *tr = *p; 312 313 *buf += len; 314 *size -= len; 315 316 return 0; 317 } 318 319 /** 320 * proc_put_long - converts an integer to a decimal ASCII formatted string 321 * 322 * @buf: the user buffer 323 * @size: the size of the user buffer 324 * @val: the integer to be converted 325 * @neg: sign of the number, %TRUE for negative 326 * 327 * In case of success @buf and @size are updated with the amount of bytes 328 * written. 329 */ 330 static void proc_put_long(void **buf, size_t *size, unsigned long val, bool neg) 331 { 332 int len; 333 char tmp[TMPBUFLEN], *p = tmp; 334 335 sprintf(p, "%s%lu", neg ? "-" : "", val); 336 len = strlen(tmp); 337 if (len > *size) 338 len = *size; 339 memcpy(*buf, tmp, len); 340 *size -= len; 341 *buf += len; 342 } 343 #undef TMPBUFLEN 344 345 static void proc_put_char(void **buf, size_t *size, char c) 346 { 347 if (*size) { 348 char **buffer = (char **)buf; 349 **buffer = c; 350 351 (*size)--; 352 (*buffer)++; 353 *buf = *buffer; 354 } 355 } 356 357 static SYSCTL_USER_TO_KERN_INT_CONV(, SYSCTL_CONV_IDENTITY) 358 static SYSCTL_KERN_TO_USER_INT_CONV(, SYSCTL_CONV_IDENTITY) 359 360 static SYSCTL_INT_CONV_CUSTOM(, sysctl_user_to_kern_int_conv, 361 sysctl_kern_to_user_int_conv, false) 362 static SYSCTL_INT_CONV_CUSTOM(_minmax, sysctl_user_to_kern_int_conv, 363 sysctl_kern_to_user_int_conv, true) 364 365 366 static SYSCTL_USER_TO_KERN_UINT_CONV(, SYSCTL_CONV_IDENTITY) 367 368 int sysctl_kern_to_user_uint_conv(unsigned long *u_ptr, 369 const unsigned int *k_ptr) 370 { 371 unsigned int val = READ_ONCE(*k_ptr); 372 *u_ptr = (unsigned long)val; 373 return 0; 374 } 375 376 static SYSCTL_UINT_CONV_CUSTOM(, sysctl_user_to_kern_uint_conv, 377 sysctl_kern_to_user_uint_conv, false) 378 static SYSCTL_UINT_CONV_CUSTOM(_minmax, sysctl_user_to_kern_uint_conv, 379 sysctl_kern_to_user_uint_conv, true) 380 381 static const char proc_wspace_sep[] = { ' ', '\t', '\n' }; 382 383 static int do_proc_dointvec(const struct ctl_table *table, int dir, 384 void *buffer, size_t *lenp, loff_t *ppos, 385 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr, 386 int dir, const struct ctl_table *table)) 387 { 388 int *i, vleft, first = 1, err = 0; 389 size_t left; 390 char *p; 391 392 if (!table->data || !table->maxlen || !*lenp || 393 (*ppos && SYSCTL_KERN_TO_USER(dir))) { 394 *lenp = 0; 395 return 0; 396 } 397 398 i = (int *) table->data; 399 vleft = table->maxlen / sizeof(*i); 400 left = *lenp; 401 402 if (!conv) 403 conv = do_proc_int_conv; 404 405 if (SYSCTL_USER_TO_KERN(dir)) { 406 if (proc_first_pos_non_zero_ignore(ppos, table)) 407 goto out; 408 409 if (left > PAGE_SIZE - 1) 410 left = PAGE_SIZE - 1; 411 p = buffer; 412 } 413 414 for (; left && vleft--; i++, first=0) { 415 unsigned long lval; 416 bool neg; 417 418 if (SYSCTL_USER_TO_KERN(dir)) { 419 proc_skip_spaces(&p, &left); 420 421 if (!left) 422 break; 423 err = proc_get_long(&p, &left, &lval, &neg, 424 proc_wspace_sep, 425 sizeof(proc_wspace_sep), NULL); 426 if (err) 427 break; 428 if (conv(&neg, &lval, i, 1, table)) { 429 err = -EINVAL; 430 break; 431 } 432 } else { 433 if (conv(&neg, &lval, i, 0, table)) { 434 err = -EINVAL; 435 break; 436 } 437 if (!first) 438 proc_put_char(&buffer, &left, '\t'); 439 proc_put_long(&buffer, &left, lval, neg); 440 } 441 } 442 443 if (SYSCTL_KERN_TO_USER(dir) && !first && left && !err) 444 proc_put_char(&buffer, &left, '\n'); 445 if (SYSCTL_USER_TO_KERN(dir) && !err && left) 446 proc_skip_spaces(&p, &left); 447 if (SYSCTL_USER_TO_KERN(dir) && first) 448 return err ? : -EINVAL; 449 *lenp -= left; 450 out: 451 *ppos += *lenp; 452 return err; 453 } 454 455 static int do_proc_douintvec_w(const struct ctl_table *table, void *buffer, 456 size_t *lenp, loff_t *ppos, 457 int (*conv)(unsigned long *u_ptr, 458 unsigned int *k_ptr, int dir, 459 const struct ctl_table *table)) 460 { 461 unsigned long lval; 462 int err = 0; 463 size_t left; 464 bool neg; 465 char *p = buffer; 466 467 left = *lenp; 468 469 if (proc_first_pos_non_zero_ignore(ppos, table)) 470 goto bail_early; 471 472 if (left > PAGE_SIZE - 1) 473 left = PAGE_SIZE - 1; 474 475 proc_skip_spaces(&p, &left); 476 if (!left) { 477 err = -EINVAL; 478 goto out_free; 479 } 480 481 err = proc_get_long(&p, &left, &lval, &neg, 482 proc_wspace_sep, 483 sizeof(proc_wspace_sep), NULL); 484 if (err || neg) { 485 err = -EINVAL; 486 goto out_free; 487 } 488 489 if (conv(&lval, (unsigned int *) table->data, 1, table)) { 490 err = -EINVAL; 491 goto out_free; 492 } 493 494 if (!err && left) 495 proc_skip_spaces(&p, &left); 496 497 out_free: 498 if (err) 499 return -EINVAL; 500 501 return 0; 502 503 bail_early: 504 *ppos += *lenp; 505 return err; 506 } 507 508 static int do_proc_douintvec_r(const struct ctl_table *table, void *buffer, 509 size_t *lenp, loff_t *ppos, 510 int (*conv)(unsigned long *u_ptr, 511 unsigned int *k_ptr, int dir, 512 const struct ctl_table *table)) 513 { 514 unsigned long lval; 515 int err = 0; 516 size_t left; 517 518 left = *lenp; 519 520 if (conv(&lval, (unsigned int *) table->data, 0, table)) { 521 err = -EINVAL; 522 goto out; 523 } 524 525 proc_put_long(&buffer, &left, lval, false); 526 if (!left) 527 goto out; 528 529 proc_put_char(&buffer, &left, '\n'); 530 531 out: 532 *lenp -= left; 533 *ppos += *lenp; 534 535 return err; 536 } 537 538 static int do_proc_douintvec(const struct ctl_table *table, int dir, 539 void *buffer, size_t *lenp, loff_t *ppos, 540 int (*conv)(unsigned long *u_ptr, 541 unsigned int *k_ptr, int dir, 542 const struct ctl_table *table)) 543 { 544 unsigned int vleft; 545 546 if (!table->data || !table->maxlen || !*lenp || 547 (*ppos && SYSCTL_KERN_TO_USER(dir))) { 548 *lenp = 0; 549 return 0; 550 } 551 552 vleft = table->maxlen / sizeof(unsigned int); 553 554 /* 555 * Arrays are not supported, keep this simple. *Do not* add 556 * support for them. 557 */ 558 if (vleft != 1) { 559 *lenp = 0; 560 return -EINVAL; 561 } 562 563 if (!conv) 564 conv = do_proc_uint_conv; 565 566 if (SYSCTL_USER_TO_KERN(dir)) 567 return do_proc_douintvec_w(table, buffer, lenp, ppos, conv); 568 return do_proc_douintvec_r(table, buffer, lenp, ppos, conv); 569 } 570 571 int proc_douintvec_conv(const struct ctl_table *table, int dir, void *buffer, 572 size_t *lenp, loff_t *ppos, 573 int (*conv)(unsigned long *u_ptr, unsigned int *k_ptr, 574 int dir, const struct ctl_table *table)) 575 { 576 return do_proc_douintvec(table, dir, buffer, lenp, ppos, conv); 577 } 578 579 580 /** 581 * proc_dobool - read/write a bool 582 * @table: the sysctl table 583 * @dir: %TRUE if this is a write to the sysctl file 584 * @buffer: the user buffer 585 * @lenp: the size of the user buffer 586 * @ppos: file position 587 * 588 * Reads/writes one integer value from/to the user buffer, 589 * treated as an ASCII string. 590 * 591 * table->data must point to a bool variable and table->maxlen must 592 * be sizeof(bool). 593 * 594 * Returns 0 on success. 595 */ 596 int proc_dobool(const struct ctl_table *table, int dir, void *buffer, 597 size_t *lenp, loff_t *ppos) 598 { 599 struct ctl_table tmp; 600 bool *data = table->data; 601 int res, val; 602 603 /* Do not support arrays yet. */ 604 if (table->maxlen != sizeof(bool)) 605 return -EINVAL; 606 607 tmp = *table; 608 tmp.maxlen = sizeof(val); 609 tmp.data = &val; 610 611 val = READ_ONCE(*data); 612 res = proc_dointvec(&tmp, dir, buffer, lenp, ppos); 613 if (res) 614 return res; 615 if (SYSCTL_USER_TO_KERN(dir)) 616 WRITE_ONCE(*data, val); 617 return 0; 618 } 619 620 /** 621 * proc_dointvec - read a vector of integers 622 * @table: the sysctl table 623 * @dir: %TRUE if this is a write to the sysctl file 624 * @buffer: the user buffer 625 * @lenp: the size of the user buffer 626 * @ppos: file position 627 * 628 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 629 * values from/to the user buffer, treated as an ASCII string. 630 * 631 * Returns 0 on success. 632 */ 633 int proc_dointvec(const struct ctl_table *table, int dir, void *buffer, 634 size_t *lenp, loff_t *ppos) 635 { 636 return do_proc_dointvec(table, dir, buffer, lenp, ppos, NULL); 637 } 638 639 /** 640 * proc_douintvec - read a vector of unsigned integers 641 * @table: the sysctl table 642 * @dir: %TRUE if this is a write to the sysctl file 643 * @buffer: the user buffer 644 * @lenp: the size of the user buffer 645 * @ppos: file position 646 * 647 * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer 648 * values from/to the user buffer, treated as an ASCII string. 649 * 650 * Returns 0 on success. 651 */ 652 int proc_douintvec(const struct ctl_table *table, int dir, void *buffer, 653 size_t *lenp, loff_t *ppos) 654 { 655 return do_proc_douintvec(table, dir, buffer, lenp, ppos, 656 do_proc_uint_conv); 657 } 658 659 /** 660 * proc_dointvec_minmax - read a vector of integers with min/max values 661 * @table: the sysctl table 662 * @dir: %TRUE if this is a write to the sysctl file 663 * @buffer: the user buffer 664 * @lenp: the size of the user buffer 665 * @ppos: file position 666 * 667 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 668 * values from/to the user buffer, treated as an ASCII string. 669 * 670 * This routine will ensure the values are within the range specified by 671 * table->extra1 (min) and table->extra2 (max). 672 * 673 * Returns 0 on success or -EINVAL when the range check fails and 674 * SYSCTL_USER_TO_KERN(dir) == true 675 */ 676 int proc_dointvec_minmax(const struct ctl_table *table, int dir, 677 void *buffer, size_t *lenp, loff_t *ppos) 678 { 679 return do_proc_dointvec(table, dir, buffer, lenp, ppos, 680 do_proc_int_conv_minmax); 681 } 682 683 /** 684 * proc_douintvec_minmax - read a vector of unsigned ints with min/max values 685 * @table: the sysctl table 686 * @dir: %TRUE if this is a write to the sysctl file 687 * @buffer: the user buffer 688 * @lenp: the size of the user buffer 689 * @ppos: file position 690 * 691 * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer 692 * values from/to the user buffer, treated as an ASCII string. Negative 693 * strings are not allowed. 694 * 695 * This routine will ensure the values are within the range specified by 696 * table->extra1 (min) and table->extra2 (max). There is a final sanity 697 * check for UINT_MAX to avoid having to support wrap around uses from 698 * userspace. 699 * 700 * Returns 0 on success or -ERANGE when range check failes and 701 * SYSCTL_USER_TO_KERN(dir) == true 702 */ 703 int proc_douintvec_minmax(const struct ctl_table *table, int dir, 704 void *buffer, size_t *lenp, loff_t *ppos) 705 { 706 return do_proc_douintvec(table, dir, buffer, lenp, ppos, 707 do_proc_uint_conv_minmax); 708 } 709 710 /** 711 * proc_dou8vec_minmax - read a vector of unsigned chars with min/max values 712 * @table: the sysctl table 713 * @dir: %TRUE if this is a write to the sysctl file 714 * @buffer: the user buffer 715 * @lenp: the size of the user buffer 716 * @ppos: file position 717 * 718 * Reads/writes up to table->maxlen/sizeof(u8) unsigned chars 719 * values from/to the user buffer, treated as an ASCII string. Negative 720 * strings are not allowed. 721 * 722 * This routine will ensure the values are within the range specified by 723 * table->extra1 (min) and table->extra2 (max). 724 * 725 * Returns 0 on success or an error on SYSCTL_USER_TO_KERN(dir) == true 726 * and the range check fails. 727 */ 728 int proc_dou8vec_minmax(const struct ctl_table *table, int dir, 729 void *buffer, size_t *lenp, loff_t *ppos) 730 { 731 struct ctl_table tmp; 732 unsigned int min = 0, max = 255U, val; 733 u8 *data = table->data; 734 int res; 735 736 /* Do not support arrays yet. */ 737 if (table->maxlen != sizeof(u8)) 738 return -EINVAL; 739 740 tmp = *table; 741 742 tmp.maxlen = sizeof(val); 743 tmp.data = &val; 744 if (!tmp.extra1) 745 tmp.extra1 = (unsigned int *) &min; 746 if (!tmp.extra2) 747 tmp.extra2 = (unsigned int *) &max; 748 749 val = READ_ONCE(*data); 750 res = do_proc_douintvec(&tmp, dir, buffer, lenp, ppos, 751 do_proc_uint_conv_minmax); 752 if (res) 753 return res; 754 if (SYSCTL_USER_TO_KERN(dir)) 755 WRITE_ONCE(*data, val); 756 return 0; 757 } 758 EXPORT_SYMBOL_GPL(proc_dou8vec_minmax); 759 760 static int do_proc_doulongvec_minmax(const struct ctl_table *table, int dir, 761 void *buffer, size_t *lenp, loff_t *ppos, 762 unsigned long convmul, 763 unsigned long convdiv) 764 { 765 unsigned long *i, *min, *max; 766 int vleft, first = 1, err = 0; 767 size_t left; 768 char *p; 769 770 if (!table->data || !table->maxlen || !*lenp || 771 (*ppos && SYSCTL_KERN_TO_USER(dir))) { 772 *lenp = 0; 773 return 0; 774 } 775 776 i = table->data; 777 min = table->extra1; 778 max = table->extra2; 779 vleft = table->maxlen / sizeof(unsigned long); 780 left = *lenp; 781 782 if (SYSCTL_USER_TO_KERN(dir)) { 783 if (proc_first_pos_non_zero_ignore(ppos, table)) 784 goto out; 785 786 if (left > PAGE_SIZE - 1) 787 left = PAGE_SIZE - 1; 788 p = buffer; 789 } 790 791 for (; left && vleft--; i++, first = 0) { 792 unsigned long val; 793 794 if (SYSCTL_USER_TO_KERN(dir)) { 795 bool neg; 796 797 proc_skip_spaces(&p, &left); 798 if (!left) 799 break; 800 801 err = proc_get_long(&p, &left, &val, &neg, 802 proc_wspace_sep, 803 sizeof(proc_wspace_sep), NULL); 804 if (err || neg) { 805 err = -EINVAL; 806 break; 807 } 808 809 val = convmul * val / convdiv; 810 if ((min && val < *min) || (max && val > *max)) { 811 err = -EINVAL; 812 break; 813 } 814 WRITE_ONCE(*i, val); 815 } else { 816 val = convdiv * READ_ONCE(*i) / convmul; 817 if (!first) 818 proc_put_char(&buffer, &left, '\t'); 819 proc_put_long(&buffer, &left, val, false); 820 } 821 } 822 823 if (SYSCTL_KERN_TO_USER(dir) && !first && left && !err) 824 proc_put_char(&buffer, &left, '\n'); 825 if (SYSCTL_USER_TO_KERN(dir) && !err) 826 proc_skip_spaces(&p, &left); 827 if (SYSCTL_USER_TO_KERN(dir) && first) 828 return err ? : -EINVAL; 829 *lenp -= left; 830 out: 831 *ppos += *lenp; 832 return err; 833 } 834 835 int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir, 836 void *buffer, size_t *lenp, loff_t *ppos, 837 unsigned long convmul, unsigned long convdiv) 838 { 839 return do_proc_doulongvec_minmax(table, dir, buffer, lenp, ppos, 840 convmul, convdiv); 841 } 842 843 /** 844 * proc_doulongvec_minmax - read a vector of long integers with min/max values 845 * @table: the sysctl table 846 * @dir: %TRUE if this is a write to the sysctl file 847 * @buffer: the user buffer 848 * @lenp: the size of the user buffer 849 * @ppos: file position 850 * 851 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long 852 * values from/to the user buffer, treated as an ASCII string. 853 * 854 * This routine will ensure the values are within the range specified by 855 * table->extra1 (min) and table->extra2 (max). 856 * 857 * Returns 0 on success. 858 */ 859 int proc_doulongvec_minmax(const struct ctl_table *table, int dir, 860 void *buffer, size_t *lenp, loff_t *ppos) 861 { 862 return proc_doulongvec_minmax_conv(table, dir, buffer, lenp, ppos, 1l, 1l); 863 } 864 865 /** 866 * proc_dointvec_conv - read a vector of ints with a custom converter 867 * @table: the sysctl table 868 * @dir: %TRUE if this is a write to the sysctl file 869 * @buffer: the user buffer 870 * @lenp: the size of the user buffer 871 * @ppos: file position 872 * @conv: Custom converter call back 873 * 874 * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer 875 * values from/to the user buffer, treated as an ASCII string. Negative 876 * strings are not allowed. 877 * 878 * Returns: 0 on success 879 */ 880 881 int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer, 882 size_t *lenp, loff_t *ppos, 883 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr, 884 int dir, const struct ctl_table *table)) 885 { 886 return do_proc_dointvec(table, dir, buffer, lenp, ppos, conv); 887 } 888 889 /** 890 * proc_do_large_bitmap - read/write from/to a large bitmap 891 * @table: the sysctl table 892 * @dir: %TRUE if this is a write to the sysctl file 893 * @buffer: the user buffer 894 * @lenp: the size of the user buffer 895 * @ppos: file position 896 * 897 * The bitmap is stored at table->data and the bitmap length (in bits) 898 * in table->maxlen. 899 * 900 * We use a range comma separated format (e.g. 1,3-4,10-10) so that 901 * large bitmaps may be represented in a compact manner. Writing into 902 * the file will clear the bitmap then update it with the given input. 903 * 904 * Returns 0 on success. 905 */ 906 int proc_do_large_bitmap(const struct ctl_table *table, int dir, 907 void *buffer, size_t *lenp, loff_t *ppos) 908 { 909 int err = 0; 910 size_t left = *lenp; 911 unsigned long bitmap_len = table->maxlen; 912 unsigned long *bitmap = *(unsigned long **) table->data; 913 unsigned long *tmp_bitmap = NULL; 914 char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c; 915 916 if (!bitmap || !bitmap_len || !left || (*ppos && SYSCTL_KERN_TO_USER(dir))) { 917 *lenp = 0; 918 return 0; 919 } 920 921 if (SYSCTL_USER_TO_KERN(dir)) { 922 char *p = buffer; 923 size_t skipped = 0; 924 925 if (left > PAGE_SIZE - 1) { 926 left = PAGE_SIZE - 1; 927 /* How much of the buffer we'll skip this pass */ 928 skipped = *lenp - left; 929 } 930 931 tmp_bitmap = bitmap_zalloc(bitmap_len, GFP_KERNEL); 932 if (!tmp_bitmap) 933 return -ENOMEM; 934 proc_skip_char(&p, &left, '\n'); 935 while (!err && left) { 936 unsigned long val_a, val_b; 937 bool neg; 938 size_t saved_left; 939 940 /* In case we stop parsing mid-number, we can reset */ 941 saved_left = left; 942 err = proc_get_long(&p, &left, &val_a, &neg, tr_a, 943 sizeof(tr_a), &c); 944 /* 945 * If we consumed the entirety of a truncated buffer or 946 * only one char is left (may be a "-"), then stop here, 947 * reset, & come back for more. 948 */ 949 if ((left <= 1) && skipped) { 950 left = saved_left; 951 break; 952 } 953 954 if (err) 955 break; 956 if (val_a >= bitmap_len || neg) { 957 err = -EINVAL; 958 break; 959 } 960 961 val_b = val_a; 962 if (left) { 963 p++; 964 left--; 965 } 966 967 if (c == '-') { 968 err = proc_get_long(&p, &left, &val_b, 969 &neg, tr_b, sizeof(tr_b), 970 &c); 971 /* 972 * If we consumed all of a truncated buffer or 973 * then stop here, reset, & come back for more. 974 */ 975 if (!left && skipped) { 976 left = saved_left; 977 break; 978 } 979 980 if (err) 981 break; 982 if (val_b >= bitmap_len || neg || 983 val_a > val_b) { 984 err = -EINVAL; 985 break; 986 } 987 if (left) { 988 p++; 989 left--; 990 } 991 } 992 993 bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1); 994 proc_skip_char(&p, &left, '\n'); 995 } 996 left += skipped; 997 } else { 998 unsigned long bit_a, bit_b = 0; 999 bool first = 1; 1000 1001 while (left) { 1002 bit_a = find_next_bit(bitmap, bitmap_len, bit_b); 1003 if (bit_a >= bitmap_len) 1004 break; 1005 bit_b = find_next_zero_bit(bitmap, bitmap_len, 1006 bit_a + 1) - 1; 1007 1008 if (!first) 1009 proc_put_char(&buffer, &left, ','); 1010 proc_put_long(&buffer, &left, bit_a, false); 1011 if (bit_a != bit_b) { 1012 proc_put_char(&buffer, &left, '-'); 1013 proc_put_long(&buffer, &left, bit_b, false); 1014 } 1015 1016 first = 0; bit_b++; 1017 } 1018 proc_put_char(&buffer, &left, '\n'); 1019 } 1020 1021 if (!err) { 1022 if (SYSCTL_USER_TO_KERN(dir)) { 1023 if (*ppos) 1024 bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len); 1025 else 1026 bitmap_copy(bitmap, tmp_bitmap, bitmap_len); 1027 } 1028 *lenp -= left; 1029 *ppos += *lenp; 1030 } 1031 1032 bitmap_free(tmp_bitmap); 1033 return err; 1034 } 1035 1036 #else /* CONFIG_PROC_SYSCTL */ 1037 1038 int proc_dostring(const struct ctl_table *table, int dir, 1039 void *buffer, size_t *lenp, loff_t *ppos) 1040 { 1041 return -ENOSYS; 1042 } 1043 1044 int proc_dobool(const struct ctl_table *table, int dir, 1045 void *buffer, size_t *lenp, loff_t *ppos) 1046 { 1047 return -ENOSYS; 1048 } 1049 1050 int proc_dointvec(const struct ctl_table *table, int dir, 1051 void *buffer, size_t *lenp, loff_t *ppos) 1052 { 1053 return -ENOSYS; 1054 } 1055 1056 int proc_douintvec(const struct ctl_table *table, int dir, 1057 void *buffer, size_t *lenp, loff_t *ppos) 1058 { 1059 return -ENOSYS; 1060 } 1061 1062 int proc_dointvec_minmax(const struct ctl_table *table, int dir, 1063 void *buffer, size_t *lenp, loff_t *ppos) 1064 { 1065 return -ENOSYS; 1066 } 1067 1068 int proc_douintvec_minmax(const struct ctl_table *table, int dir, 1069 void *buffer, size_t *lenp, loff_t *ppos) 1070 { 1071 return -ENOSYS; 1072 } 1073 1074 int proc_dou8vec_minmax(const struct ctl_table *table, int dir, 1075 void *buffer, size_t *lenp, loff_t *ppos) 1076 { 1077 return -ENOSYS; 1078 } 1079 1080 int proc_doulongvec_minmax(const struct ctl_table *table, int dir, 1081 void *buffer, size_t *lenp, loff_t *ppos) 1082 { 1083 return -ENOSYS; 1084 } 1085 1086 int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir, 1087 void *buffer, size_t *lenp, loff_t *ppos, 1088 unsigned long convmul, unsigned long convdiv) 1089 { 1090 return -ENOSYS; 1091 } 1092 1093 int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer, 1094 size_t *lenp, loff_t *ppos, 1095 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr, 1096 int dir, const struct ctl_table *table)) 1097 { 1098 return -ENOSYS; 1099 } 1100 1101 int proc_do_large_bitmap(const struct ctl_table *table, int dir, 1102 void *buffer, size_t *lenp, loff_t *ppos) 1103 { 1104 return -ENOSYS; 1105 } 1106 1107 #endif /* CONFIG_PROC_SYSCTL */ 1108 1109 #if defined(CONFIG_SYSCTL) 1110 int proc_do_static_key(const struct ctl_table *table, int dir, 1111 void *buffer, size_t *lenp, loff_t *ppos) 1112 { 1113 struct static_key *key = (struct static_key *)table->data; 1114 static DEFINE_MUTEX(static_key_mutex); 1115 int val, ret; 1116 struct ctl_table tmp = { 1117 .data = &val, 1118 .maxlen = sizeof(val), 1119 .mode = table->mode, 1120 .extra1 = SYSCTL_ZERO, 1121 .extra2 = SYSCTL_ONE, 1122 }; 1123 1124 if (SYSCTL_USER_TO_KERN(dir) && !capable(CAP_SYS_ADMIN)) 1125 return -EPERM; 1126 1127 mutex_lock(&static_key_mutex); 1128 val = static_key_enabled(key); 1129 ret = proc_dointvec_minmax(&tmp, dir, buffer, lenp, ppos); 1130 if (SYSCTL_USER_TO_KERN(dir) && !ret) { 1131 if (val) 1132 static_key_enable(key); 1133 else 1134 static_key_disable(key); 1135 } 1136 mutex_unlock(&static_key_mutex); 1137 return ret; 1138 } 1139 1140 static const struct ctl_table sysctl_subsys_table[] = { 1141 #ifdef CONFIG_PROC_SYSCTL 1142 { 1143 .procname = "sysctl_writes_strict", 1144 .data = &sysctl_writes_strict, 1145 .maxlen = sizeof(int), 1146 .mode = 0644, 1147 .proc_handler = proc_dointvec_minmax, 1148 .extra1 = SYSCTL_NEG_ONE, 1149 .extra2 = SYSCTL_ONE, 1150 }, 1151 #endif 1152 { 1153 .procname = "ngroups_max", 1154 .data = (void *)&ngroups_max, 1155 .maxlen = sizeof (int), 1156 .mode = 0444, 1157 .proc_handler = proc_dointvec, 1158 }, 1159 { 1160 .procname = "cap_last_cap", 1161 .data = (void *)&cap_last_cap, 1162 .maxlen = sizeof(int), 1163 .mode = 0444, 1164 .proc_handler = proc_dointvec, 1165 }, 1166 #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW 1167 { 1168 .procname = "unaligned-trap", 1169 .data = &unaligned_enabled, 1170 .maxlen = sizeof(int), 1171 .mode = 0644, 1172 .proc_handler = proc_dointvec, 1173 }, 1174 #endif 1175 #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN 1176 { 1177 .procname = "ignore-unaligned-usertrap", 1178 .data = &no_unaligned_warning, 1179 .maxlen = sizeof (int), 1180 .mode = 0644, 1181 .proc_handler = proc_dointvec, 1182 }, 1183 #endif 1184 }; 1185 1186 int __init sysctl_init_bases(void) 1187 { 1188 register_sysctl_init("kernel", sysctl_subsys_table); 1189 1190 return 0; 1191 } 1192 #endif /* CONFIG_SYSCTL */ 1193 /* 1194 * No sense putting this after each symbol definition, twice, 1195 * exception granted :-) 1196 */ 1197 EXPORT_SYMBOL(proc_dobool); 1198 EXPORT_SYMBOL(proc_dointvec); 1199 EXPORT_SYMBOL(proc_douintvec); 1200 EXPORT_SYMBOL(proc_dointvec_minmax); 1201 EXPORT_SYMBOL_GPL(proc_douintvec_minmax); 1202 EXPORT_SYMBOL(proc_dostring); 1203 EXPORT_SYMBOL(proc_doulongvec_minmax); 1204 EXPORT_SYMBOL(proc_do_large_bitmap); 1205