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 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 * 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 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 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 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 */ 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 */ 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 */ 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 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 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 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 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 */ 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 */ 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 */ 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 */ 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 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 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 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 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 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 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 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 1314 int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr) 1315 { 1316 return -ENOSYS; 1317 } 1318 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 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 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 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 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 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 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) 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 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