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 int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer, 866 size_t *lenp, loff_t *ppos, 867 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr, 868 int dir, const struct ctl_table *table)) 869 { 870 return do_proc_dointvec(table, dir, buffer, lenp, ppos, conv); 871 } 872 873 /** 874 * proc_do_large_bitmap - read/write from/to a large bitmap 875 * @table: the sysctl table 876 * @dir: %TRUE if this is a write to the sysctl file 877 * @buffer: the user buffer 878 * @lenp: the size of the user buffer 879 * @ppos: file position 880 * 881 * The bitmap is stored at table->data and the bitmap length (in bits) 882 * in table->maxlen. 883 * 884 * We use a range comma separated format (e.g. 1,3-4,10-10) so that 885 * large bitmaps may be represented in a compact manner. Writing into 886 * the file will clear the bitmap then update it with the given input. 887 * 888 * Returns 0 on success. 889 */ 890 int proc_do_large_bitmap(const struct ctl_table *table, int dir, 891 void *buffer, size_t *lenp, loff_t *ppos) 892 { 893 int err = 0; 894 size_t left = *lenp; 895 unsigned long bitmap_len = table->maxlen; 896 unsigned long *bitmap = *(unsigned long **) table->data; 897 unsigned long *tmp_bitmap = NULL; 898 char tr_a[] = { '-', ',', '\n' }, tr_b[] = { ',', '\n', 0 }, c; 899 900 if (!bitmap || !bitmap_len || !left || (*ppos && SYSCTL_KERN_TO_USER(dir))) { 901 *lenp = 0; 902 return 0; 903 } 904 905 if (SYSCTL_USER_TO_KERN(dir)) { 906 char *p = buffer; 907 size_t skipped = 0; 908 909 if (left > PAGE_SIZE - 1) { 910 left = PAGE_SIZE - 1; 911 /* How much of the buffer we'll skip this pass */ 912 skipped = *lenp - left; 913 } 914 915 tmp_bitmap = bitmap_zalloc(bitmap_len, GFP_KERNEL); 916 if (!tmp_bitmap) 917 return -ENOMEM; 918 proc_skip_char(&p, &left, '\n'); 919 while (!err && left) { 920 unsigned long val_a, val_b; 921 bool neg; 922 size_t saved_left; 923 924 /* In case we stop parsing mid-number, we can reset */ 925 saved_left = left; 926 err = proc_get_long(&p, &left, &val_a, &neg, tr_a, 927 sizeof(tr_a), &c); 928 /* 929 * If we consumed the entirety of a truncated buffer or 930 * only one char is left (may be a "-"), then stop here, 931 * reset, & come back for more. 932 */ 933 if ((left <= 1) && skipped) { 934 left = saved_left; 935 break; 936 } 937 938 if (err) 939 break; 940 if (val_a >= bitmap_len || neg) { 941 err = -EINVAL; 942 break; 943 } 944 945 val_b = val_a; 946 if (left) { 947 p++; 948 left--; 949 } 950 951 if (c == '-') { 952 err = proc_get_long(&p, &left, &val_b, 953 &neg, tr_b, sizeof(tr_b), 954 &c); 955 /* 956 * If we consumed all of a truncated buffer or 957 * then stop here, reset, & come back for more. 958 */ 959 if (!left && skipped) { 960 left = saved_left; 961 break; 962 } 963 964 if (err) 965 break; 966 if (val_b >= bitmap_len || neg || 967 val_a > val_b) { 968 err = -EINVAL; 969 break; 970 } 971 if (left) { 972 p++; 973 left--; 974 } 975 } 976 977 bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1); 978 proc_skip_char(&p, &left, '\n'); 979 } 980 left += skipped; 981 } else { 982 unsigned long bit_a, bit_b = 0; 983 bool first = 1; 984 985 while (left) { 986 bit_a = find_next_bit(bitmap, bitmap_len, bit_b); 987 if (bit_a >= bitmap_len) 988 break; 989 bit_b = find_next_zero_bit(bitmap, bitmap_len, 990 bit_a + 1) - 1; 991 992 if (!first) 993 proc_put_char(&buffer, &left, ','); 994 proc_put_long(&buffer, &left, bit_a, false); 995 if (bit_a != bit_b) { 996 proc_put_char(&buffer, &left, '-'); 997 proc_put_long(&buffer, &left, bit_b, false); 998 } 999 1000 first = 0; bit_b++; 1001 } 1002 proc_put_char(&buffer, &left, '\n'); 1003 } 1004 1005 if (!err) { 1006 if (SYSCTL_USER_TO_KERN(dir)) { 1007 if (*ppos) 1008 bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len); 1009 else 1010 bitmap_copy(bitmap, tmp_bitmap, bitmap_len); 1011 } 1012 *lenp -= left; 1013 *ppos += *lenp; 1014 } 1015 1016 bitmap_free(tmp_bitmap); 1017 return err; 1018 } 1019 1020 #else /* CONFIG_PROC_SYSCTL */ 1021 1022 int proc_dostring(const struct ctl_table *table, int dir, 1023 void *buffer, size_t *lenp, loff_t *ppos) 1024 { 1025 return -ENOSYS; 1026 } 1027 1028 int proc_dobool(const struct ctl_table *table, int dir, 1029 void *buffer, size_t *lenp, loff_t *ppos) 1030 { 1031 return -ENOSYS; 1032 } 1033 1034 int proc_dointvec(const struct ctl_table *table, int dir, 1035 void *buffer, size_t *lenp, loff_t *ppos) 1036 { 1037 return -ENOSYS; 1038 } 1039 1040 int proc_douintvec(const struct ctl_table *table, int dir, 1041 void *buffer, size_t *lenp, loff_t *ppos) 1042 { 1043 return -ENOSYS; 1044 } 1045 1046 int proc_dointvec_minmax(const struct ctl_table *table, int dir, 1047 void *buffer, size_t *lenp, loff_t *ppos) 1048 { 1049 return -ENOSYS; 1050 } 1051 1052 int proc_douintvec_minmax(const struct ctl_table *table, int dir, 1053 void *buffer, size_t *lenp, loff_t *ppos) 1054 { 1055 return -ENOSYS; 1056 } 1057 1058 int proc_dou8vec_minmax(const struct ctl_table *table, int dir, 1059 void *buffer, size_t *lenp, loff_t *ppos) 1060 { 1061 return -ENOSYS; 1062 } 1063 1064 int proc_doulongvec_minmax(const struct ctl_table *table, int dir, 1065 void *buffer, size_t *lenp, loff_t *ppos) 1066 { 1067 return -ENOSYS; 1068 } 1069 1070 int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir, 1071 void *buffer, size_t *lenp, loff_t *ppos, 1072 unsigned long convmul, unsigned long convdiv) 1073 { 1074 return -ENOSYS; 1075 } 1076 1077 int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer, 1078 size_t *lenp, loff_t *ppos, 1079 int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr, 1080 int dir, const struct ctl_table *table)) 1081 { 1082 return -ENOSYS; 1083 } 1084 1085 int proc_do_large_bitmap(const struct ctl_table *table, int dir, 1086 void *buffer, size_t *lenp, loff_t *ppos) 1087 { 1088 return -ENOSYS; 1089 } 1090 1091 #endif /* CONFIG_PROC_SYSCTL */ 1092 1093 #if defined(CONFIG_SYSCTL) 1094 int proc_do_static_key(const struct ctl_table *table, int dir, 1095 void *buffer, size_t *lenp, loff_t *ppos) 1096 { 1097 struct static_key *key = (struct static_key *)table->data; 1098 static DEFINE_MUTEX(static_key_mutex); 1099 int val, ret; 1100 struct ctl_table tmp = { 1101 .data = &val, 1102 .maxlen = sizeof(val), 1103 .mode = table->mode, 1104 .extra1 = SYSCTL_ZERO, 1105 .extra2 = SYSCTL_ONE, 1106 }; 1107 1108 if (SYSCTL_USER_TO_KERN(dir) && !capable(CAP_SYS_ADMIN)) 1109 return -EPERM; 1110 1111 mutex_lock(&static_key_mutex); 1112 val = static_key_enabled(key); 1113 ret = proc_dointvec_minmax(&tmp, dir, buffer, lenp, ppos); 1114 if (SYSCTL_USER_TO_KERN(dir) && !ret) { 1115 if (val) 1116 static_key_enable(key); 1117 else 1118 static_key_disable(key); 1119 } 1120 mutex_unlock(&static_key_mutex); 1121 return ret; 1122 } 1123 1124 static const struct ctl_table sysctl_subsys_table[] = { 1125 #ifdef CONFIG_PROC_SYSCTL 1126 { 1127 .procname = "sysctl_writes_strict", 1128 .data = &sysctl_writes_strict, 1129 .maxlen = sizeof(int), 1130 .mode = 0644, 1131 .proc_handler = proc_dointvec_minmax, 1132 .extra1 = SYSCTL_NEG_ONE, 1133 .extra2 = SYSCTL_ONE, 1134 }, 1135 #endif 1136 { 1137 .procname = "ngroups_max", 1138 .data = (void *)&ngroups_max, 1139 .maxlen = sizeof (int), 1140 .mode = 0444, 1141 .proc_handler = proc_dointvec, 1142 }, 1143 { 1144 .procname = "cap_last_cap", 1145 .data = (void *)&cap_last_cap, 1146 .maxlen = sizeof(int), 1147 .mode = 0444, 1148 .proc_handler = proc_dointvec, 1149 }, 1150 #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW 1151 { 1152 .procname = "unaligned-trap", 1153 .data = &unaligned_enabled, 1154 .maxlen = sizeof(int), 1155 .mode = 0644, 1156 .proc_handler = proc_dointvec, 1157 }, 1158 #endif 1159 #ifdef CONFIG_SYSCTL_ARCH_UNALIGN_NO_WARN 1160 { 1161 .procname = "ignore-unaligned-usertrap", 1162 .data = &no_unaligned_warning, 1163 .maxlen = sizeof (int), 1164 .mode = 0644, 1165 .proc_handler = proc_dointvec, 1166 }, 1167 #endif 1168 }; 1169 1170 int __init sysctl_init_bases(void) 1171 { 1172 register_sysctl_init("kernel", sysctl_subsys_table); 1173 1174 return 0; 1175 } 1176 #endif /* CONFIG_SYSCTL */ 1177 /* 1178 * No sense putting this after each symbol definition, twice, 1179 * exception granted :-) 1180 */ 1181 EXPORT_SYMBOL(proc_dobool); 1182 EXPORT_SYMBOL(proc_dointvec); 1183 EXPORT_SYMBOL(proc_douintvec); 1184 EXPORT_SYMBOL(proc_dointvec_minmax); 1185 EXPORT_SYMBOL_GPL(proc_douintvec_minmax); 1186 EXPORT_SYMBOL(proc_dostring); 1187 EXPORT_SYMBOL(proc_doulongvec_minmax); 1188 EXPORT_SYMBOL(proc_do_large_bitmap); 1189