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