1 /* 2 * sysctl.c: General linux system control interface 3 * 4 * Begun 24 March 1995, Stephen Tweedie 5 * Added /proc support, Dec 1995 6 * Added bdflush entry and intvec min/max checking, 2/23/96, Tom Dyas. 7 * Added hooks for /proc/sys/net (minor, minor patch), 96/4/1, Mike Shaver. 8 * Added kernel/java-{interpreter,appletviewer}, 96/5/10, Mike Shaver. 9 * Dynamic registration fixes, Stephen Tweedie. 10 * Added kswapd-interval, ctrl-alt-del, printk stuff, 1/8/97, Chris Horn. 11 * Made sysctl support optional via CONFIG_SYSCTL, 1/10/97, Chris 12 * Horn. 13 * Added proc_doulongvec_ms_jiffies_minmax, 09/08/99, Carlos H. Bauer. 14 * Added proc_doulongvec_minmax, 09/08/99, Carlos H. Bauer. 15 * Changed linked lists to use list.h instead of lists.h, 02/24/00, Bill 16 * Wendling. 17 * The list_for_each() macro wasn't appropriate for the sysctl loop. 18 * Removed it and replaced it with older style, 03/23/00, Bill Wendling 19 */ 20 21 #include <linux/module.h> 22 #include <linux/mm.h> 23 #include <linux/swap.h> 24 #include <linux/slab.h> 25 #include <linux/sysctl.h> 26 #include <linux/proc_fs.h> 27 #include <linux/capability.h> 28 #include <linux/ctype.h> 29 #include <linux/utsname.h> 30 #include <linux/capability.h> 31 #include <linux/smp_lock.h> 32 #include <linux/init.h> 33 #include <linux/kernel.h> 34 #include <linux/kobject.h> 35 #include <linux/net.h> 36 #include <linux/sysrq.h> 37 #include <linux/highuid.h> 38 #include <linux/writeback.h> 39 #include <linux/hugetlb.h> 40 #include <linux/security.h> 41 #include <linux/initrd.h> 42 #include <linux/times.h> 43 #include <linux/limits.h> 44 #include <linux/dcache.h> 45 #include <linux/syscalls.h> 46 #include <linux/nfs_fs.h> 47 #include <linux/acpi.h> 48 49 #include <asm/uaccess.h> 50 #include <asm/processor.h> 51 52 extern int proc_nr_files(ctl_table *table, int write, struct file *filp, 53 void __user *buffer, size_t *lenp, loff_t *ppos); 54 55 #ifdef CONFIG_X86 56 #include <asm/nmi.h> 57 #include <asm/stacktrace.h> 58 #endif 59 60 #if defined(CONFIG_SYSCTL) 61 62 /* External variables not in a header file. */ 63 extern int C_A_D; 64 extern int sysctl_overcommit_memory; 65 extern int sysctl_overcommit_ratio; 66 extern int sysctl_panic_on_oom; 67 extern int max_threads; 68 extern int core_uses_pid; 69 extern int suid_dumpable; 70 extern char core_pattern[]; 71 extern int pid_max; 72 extern int min_free_kbytes; 73 extern int printk_ratelimit_jiffies; 74 extern int printk_ratelimit_burst; 75 extern int pid_max_min, pid_max_max; 76 extern int sysctl_drop_caches; 77 extern int percpu_pagelist_fraction; 78 extern int compat_log; 79 80 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ 81 static int maxolduid = 65535; 82 static int minolduid; 83 static int min_percpu_pagelist_fract = 8; 84 85 static int ngroups_max = NGROUPS_MAX; 86 87 #ifdef CONFIG_KMOD 88 extern char modprobe_path[]; 89 #endif 90 #ifdef CONFIG_CHR_DEV_SG 91 extern int sg_big_buff; 92 #endif 93 94 #ifdef __sparc__ 95 extern char reboot_command []; 96 extern int stop_a_enabled; 97 extern int scons_pwroff; 98 #endif 99 100 #ifdef __hppa__ 101 extern int pwrsw_enabled; 102 extern int unaligned_enabled; 103 #endif 104 105 #ifdef CONFIG_S390 106 #ifdef CONFIG_MATHEMU 107 extern int sysctl_ieee_emulation_warnings; 108 #endif 109 extern int sysctl_userprocess_debug; 110 extern int spin_retry; 111 #endif 112 113 extern int sysctl_hz_timer; 114 115 #ifdef CONFIG_BSD_PROCESS_ACCT 116 extern int acct_parm[]; 117 #endif 118 119 #ifdef CONFIG_IA64 120 extern int no_unaligned_warning; 121 #endif 122 123 #ifdef CONFIG_RT_MUTEXES 124 extern int max_lock_depth; 125 #endif 126 127 #ifdef CONFIG_SYSCTL_SYSCALL 128 static int parse_table(int __user *, int, void __user *, size_t __user *, 129 void __user *, size_t, ctl_table *); 130 #endif 131 132 133 #ifdef CONFIG_PROC_SYSCTL 134 static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, 135 void __user *buffer, size_t *lenp, loff_t *ppos); 136 static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp, 137 void __user *buffer, size_t *lenp, loff_t *ppos); 138 #endif 139 140 static ctl_table root_table[]; 141 static struct ctl_table_header root_table_header = 142 { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; 143 144 static ctl_table kern_table[]; 145 static ctl_table vm_table[]; 146 static ctl_table fs_table[]; 147 static ctl_table debug_table[]; 148 static ctl_table dev_table[]; 149 extern ctl_table random_table[]; 150 #ifdef CONFIG_UNIX98_PTYS 151 extern ctl_table pty_table[]; 152 #endif 153 #ifdef CONFIG_INOTIFY_USER 154 extern ctl_table inotify_table[]; 155 #endif 156 157 #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT 158 int sysctl_legacy_va_layout; 159 #endif 160 161 162 /* The default sysctl tables: */ 163 164 static ctl_table root_table[] = { 165 { 166 .ctl_name = CTL_KERN, 167 .procname = "kernel", 168 .mode = 0555, 169 .child = kern_table, 170 }, 171 { 172 .ctl_name = CTL_VM, 173 .procname = "vm", 174 .mode = 0555, 175 .child = vm_table, 176 }, 177 #ifdef CONFIG_NET 178 { 179 .ctl_name = CTL_NET, 180 .procname = "net", 181 .mode = 0555, 182 .child = net_table, 183 }, 184 #endif 185 { 186 .ctl_name = CTL_FS, 187 .procname = "fs", 188 .mode = 0555, 189 .child = fs_table, 190 }, 191 { 192 .ctl_name = CTL_DEBUG, 193 .procname = "debug", 194 .mode = 0555, 195 .child = debug_table, 196 }, 197 { 198 .ctl_name = CTL_DEV, 199 .procname = "dev", 200 .mode = 0555, 201 .child = dev_table, 202 }, 203 204 { .ctl_name = 0 } 205 }; 206 207 static ctl_table kern_table[] = { 208 { 209 .ctl_name = KERN_PANIC, 210 .procname = "panic", 211 .data = &panic_timeout, 212 .maxlen = sizeof(int), 213 .mode = 0644, 214 .proc_handler = &proc_dointvec, 215 }, 216 { 217 .ctl_name = KERN_CORE_USES_PID, 218 .procname = "core_uses_pid", 219 .data = &core_uses_pid, 220 .maxlen = sizeof(int), 221 .mode = 0644, 222 .proc_handler = &proc_dointvec, 223 }, 224 { 225 .ctl_name = KERN_CORE_PATTERN, 226 .procname = "core_pattern", 227 .data = core_pattern, 228 .maxlen = 128, 229 .mode = 0644, 230 .proc_handler = &proc_dostring, 231 .strategy = &sysctl_string, 232 }, 233 #ifdef CONFIG_PROC_SYSCTL 234 { 235 .ctl_name = KERN_TAINTED, 236 .procname = "tainted", 237 .data = &tainted, 238 .maxlen = sizeof(int), 239 .mode = 0644, 240 .proc_handler = &proc_dointvec_taint, 241 }, 242 #endif 243 { 244 .ctl_name = KERN_CAP_BSET, 245 .procname = "cap-bound", 246 .data = &cap_bset, 247 .maxlen = sizeof(kernel_cap_t), 248 .mode = 0600, 249 .proc_handler = &proc_dointvec_bset, 250 }, 251 #ifdef CONFIG_BLK_DEV_INITRD 252 { 253 .ctl_name = KERN_REALROOTDEV, 254 .procname = "real-root-dev", 255 .data = &real_root_dev, 256 .maxlen = sizeof(int), 257 .mode = 0644, 258 .proc_handler = &proc_dointvec, 259 }, 260 #endif 261 #ifdef __sparc__ 262 { 263 .ctl_name = KERN_SPARC_REBOOT, 264 .procname = "reboot-cmd", 265 .data = reboot_command, 266 .maxlen = 256, 267 .mode = 0644, 268 .proc_handler = &proc_dostring, 269 .strategy = &sysctl_string, 270 }, 271 { 272 .ctl_name = KERN_SPARC_STOP_A, 273 .procname = "stop-a", 274 .data = &stop_a_enabled, 275 .maxlen = sizeof (int), 276 .mode = 0644, 277 .proc_handler = &proc_dointvec, 278 }, 279 { 280 .ctl_name = KERN_SPARC_SCONS_PWROFF, 281 .procname = "scons-poweroff", 282 .data = &scons_pwroff, 283 .maxlen = sizeof (int), 284 .mode = 0644, 285 .proc_handler = &proc_dointvec, 286 }, 287 #endif 288 #ifdef __hppa__ 289 { 290 .ctl_name = KERN_HPPA_PWRSW, 291 .procname = "soft-power", 292 .data = &pwrsw_enabled, 293 .maxlen = sizeof (int), 294 .mode = 0644, 295 .proc_handler = &proc_dointvec, 296 }, 297 { 298 .ctl_name = KERN_HPPA_UNALIGNED, 299 .procname = "unaligned-trap", 300 .data = &unaligned_enabled, 301 .maxlen = sizeof (int), 302 .mode = 0644, 303 .proc_handler = &proc_dointvec, 304 }, 305 #endif 306 { 307 .ctl_name = KERN_CTLALTDEL, 308 .procname = "ctrl-alt-del", 309 .data = &C_A_D, 310 .maxlen = sizeof(int), 311 .mode = 0644, 312 .proc_handler = &proc_dointvec, 313 }, 314 { 315 .ctl_name = KERN_PRINTK, 316 .procname = "printk", 317 .data = &console_loglevel, 318 .maxlen = 4*sizeof(int), 319 .mode = 0644, 320 .proc_handler = &proc_dointvec, 321 }, 322 #ifdef CONFIG_KMOD 323 { 324 .ctl_name = KERN_MODPROBE, 325 .procname = "modprobe", 326 .data = &modprobe_path, 327 .maxlen = KMOD_PATH_LEN, 328 .mode = 0644, 329 .proc_handler = &proc_dostring, 330 .strategy = &sysctl_string, 331 }, 332 #endif 333 #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) 334 { 335 .ctl_name = KERN_HOTPLUG, 336 .procname = "hotplug", 337 .data = &uevent_helper, 338 .maxlen = UEVENT_HELPER_PATH_LEN, 339 .mode = 0644, 340 .proc_handler = &proc_dostring, 341 .strategy = &sysctl_string, 342 }, 343 #endif 344 #ifdef CONFIG_CHR_DEV_SG 345 { 346 .ctl_name = KERN_SG_BIG_BUFF, 347 .procname = "sg-big-buff", 348 .data = &sg_big_buff, 349 .maxlen = sizeof (int), 350 .mode = 0444, 351 .proc_handler = &proc_dointvec, 352 }, 353 #endif 354 #ifdef CONFIG_BSD_PROCESS_ACCT 355 { 356 .ctl_name = KERN_ACCT, 357 .procname = "acct", 358 .data = &acct_parm, 359 .maxlen = 3*sizeof(int), 360 .mode = 0644, 361 .proc_handler = &proc_dointvec, 362 }, 363 #endif 364 #ifdef CONFIG_MAGIC_SYSRQ 365 { 366 .ctl_name = KERN_SYSRQ, 367 .procname = "sysrq", 368 .data = &__sysrq_enabled, 369 .maxlen = sizeof (int), 370 .mode = 0644, 371 .proc_handler = &proc_dointvec, 372 }, 373 #endif 374 #ifdef CONFIG_PROC_SYSCTL 375 { 376 .ctl_name = KERN_CADPID, 377 .procname = "cad_pid", 378 .data = NULL, 379 .maxlen = sizeof (int), 380 .mode = 0600, 381 .proc_handler = &proc_do_cad_pid, 382 }, 383 #endif 384 { 385 .ctl_name = KERN_MAX_THREADS, 386 .procname = "threads-max", 387 .data = &max_threads, 388 .maxlen = sizeof(int), 389 .mode = 0644, 390 .proc_handler = &proc_dointvec, 391 }, 392 { 393 .ctl_name = KERN_RANDOM, 394 .procname = "random", 395 .mode = 0555, 396 .child = random_table, 397 }, 398 #ifdef CONFIG_UNIX98_PTYS 399 { 400 .ctl_name = KERN_PTY, 401 .procname = "pty", 402 .mode = 0555, 403 .child = pty_table, 404 }, 405 #endif 406 { 407 .ctl_name = KERN_OVERFLOWUID, 408 .procname = "overflowuid", 409 .data = &overflowuid, 410 .maxlen = sizeof(int), 411 .mode = 0644, 412 .proc_handler = &proc_dointvec_minmax, 413 .strategy = &sysctl_intvec, 414 .extra1 = &minolduid, 415 .extra2 = &maxolduid, 416 }, 417 { 418 .ctl_name = KERN_OVERFLOWGID, 419 .procname = "overflowgid", 420 .data = &overflowgid, 421 .maxlen = sizeof(int), 422 .mode = 0644, 423 .proc_handler = &proc_dointvec_minmax, 424 .strategy = &sysctl_intvec, 425 .extra1 = &minolduid, 426 .extra2 = &maxolduid, 427 }, 428 #ifdef CONFIG_S390 429 #ifdef CONFIG_MATHEMU 430 { 431 .ctl_name = KERN_IEEE_EMULATION_WARNINGS, 432 .procname = "ieee_emulation_warnings", 433 .data = &sysctl_ieee_emulation_warnings, 434 .maxlen = sizeof(int), 435 .mode = 0644, 436 .proc_handler = &proc_dointvec, 437 }, 438 #endif 439 #ifdef CONFIG_NO_IDLE_HZ 440 { 441 .ctl_name = KERN_HZ_TIMER, 442 .procname = "hz_timer", 443 .data = &sysctl_hz_timer, 444 .maxlen = sizeof(int), 445 .mode = 0644, 446 .proc_handler = &proc_dointvec, 447 }, 448 #endif 449 { 450 .ctl_name = KERN_S390_USER_DEBUG_LOGGING, 451 .procname = "userprocess_debug", 452 .data = &sysctl_userprocess_debug, 453 .maxlen = sizeof(int), 454 .mode = 0644, 455 .proc_handler = &proc_dointvec, 456 }, 457 #endif 458 { 459 .ctl_name = KERN_PIDMAX, 460 .procname = "pid_max", 461 .data = &pid_max, 462 .maxlen = sizeof (int), 463 .mode = 0644, 464 .proc_handler = &proc_dointvec_minmax, 465 .strategy = sysctl_intvec, 466 .extra1 = &pid_max_min, 467 .extra2 = &pid_max_max, 468 }, 469 { 470 .ctl_name = KERN_PANIC_ON_OOPS, 471 .procname = "panic_on_oops", 472 .data = &panic_on_oops, 473 .maxlen = sizeof(int), 474 .mode = 0644, 475 .proc_handler = &proc_dointvec, 476 }, 477 { 478 .ctl_name = KERN_PRINTK_RATELIMIT, 479 .procname = "printk_ratelimit", 480 .data = &printk_ratelimit_jiffies, 481 .maxlen = sizeof(int), 482 .mode = 0644, 483 .proc_handler = &proc_dointvec_jiffies, 484 .strategy = &sysctl_jiffies, 485 }, 486 { 487 .ctl_name = KERN_PRINTK_RATELIMIT_BURST, 488 .procname = "printk_ratelimit_burst", 489 .data = &printk_ratelimit_burst, 490 .maxlen = sizeof(int), 491 .mode = 0644, 492 .proc_handler = &proc_dointvec, 493 }, 494 { 495 .ctl_name = KERN_NGROUPS_MAX, 496 .procname = "ngroups_max", 497 .data = &ngroups_max, 498 .maxlen = sizeof (int), 499 .mode = 0444, 500 .proc_handler = &proc_dointvec, 501 }, 502 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86) 503 { 504 .ctl_name = KERN_UNKNOWN_NMI_PANIC, 505 .procname = "unknown_nmi_panic", 506 .data = &unknown_nmi_panic, 507 .maxlen = sizeof (int), 508 .mode = 0644, 509 .proc_handler = &proc_dointvec, 510 }, 511 { 512 .ctl_name = KERN_NMI_WATCHDOG, 513 .procname = "nmi_watchdog", 514 .data = &nmi_watchdog_enabled, 515 .maxlen = sizeof (int), 516 .mode = 0644, 517 .proc_handler = &proc_nmi_enabled, 518 }, 519 #endif 520 #if defined(CONFIG_X86) 521 { 522 .ctl_name = KERN_PANIC_ON_NMI, 523 .procname = "panic_on_unrecovered_nmi", 524 .data = &panic_on_unrecovered_nmi, 525 .maxlen = sizeof(int), 526 .mode = 0644, 527 .proc_handler = &proc_dointvec, 528 }, 529 { 530 .ctl_name = KERN_BOOTLOADER_TYPE, 531 .procname = "bootloader_type", 532 .data = &bootloader_type, 533 .maxlen = sizeof (int), 534 .mode = 0444, 535 .proc_handler = &proc_dointvec, 536 }, 537 { 538 .ctl_name = CTL_UNNUMBERED, 539 .procname = "kstack_depth_to_print", 540 .data = &kstack_depth_to_print, 541 .maxlen = sizeof(int), 542 .mode = 0644, 543 .proc_handler = &proc_dointvec, 544 }, 545 #endif 546 #if defined(CONFIG_MMU) 547 { 548 .ctl_name = KERN_RANDOMIZE, 549 .procname = "randomize_va_space", 550 .data = &randomize_va_space, 551 .maxlen = sizeof(int), 552 .mode = 0644, 553 .proc_handler = &proc_dointvec, 554 }, 555 #endif 556 #if defined(CONFIG_S390) && defined(CONFIG_SMP) 557 { 558 .ctl_name = KERN_SPIN_RETRY, 559 .procname = "spin_retry", 560 .data = &spin_retry, 561 .maxlen = sizeof (int), 562 .mode = 0644, 563 .proc_handler = &proc_dointvec, 564 }, 565 #endif 566 #ifdef CONFIG_ACPI_SLEEP 567 { 568 .ctl_name = KERN_ACPI_VIDEO_FLAGS, 569 .procname = "acpi_video_flags", 570 .data = &acpi_video_flags, 571 .maxlen = sizeof (unsigned long), 572 .mode = 0644, 573 .proc_handler = &proc_doulongvec_minmax, 574 }, 575 #endif 576 #ifdef CONFIG_IA64 577 { 578 .ctl_name = KERN_IA64_UNALIGNED, 579 .procname = "ignore-unaligned-usertrap", 580 .data = &no_unaligned_warning, 581 .maxlen = sizeof (int), 582 .mode = 0644, 583 .proc_handler = &proc_dointvec, 584 }, 585 #endif 586 #ifdef CONFIG_COMPAT 587 { 588 .ctl_name = KERN_COMPAT_LOG, 589 .procname = "compat-log", 590 .data = &compat_log, 591 .maxlen = sizeof (int), 592 .mode = 0644, 593 .proc_handler = &proc_dointvec, 594 }, 595 #endif 596 #ifdef CONFIG_RT_MUTEXES 597 { 598 .ctl_name = KERN_MAX_LOCK_DEPTH, 599 .procname = "max_lock_depth", 600 .data = &max_lock_depth, 601 .maxlen = sizeof(int), 602 .mode = 0644, 603 .proc_handler = &proc_dointvec, 604 }, 605 #endif 606 607 { .ctl_name = 0 } 608 }; 609 610 /* Constants for minimum and maximum testing in vm_table. 611 We use these as one-element integer vectors. */ 612 static int zero; 613 static int one_hundred = 100; 614 615 616 static ctl_table vm_table[] = { 617 { 618 .ctl_name = VM_OVERCOMMIT_MEMORY, 619 .procname = "overcommit_memory", 620 .data = &sysctl_overcommit_memory, 621 .maxlen = sizeof(sysctl_overcommit_memory), 622 .mode = 0644, 623 .proc_handler = &proc_dointvec, 624 }, 625 { 626 .ctl_name = VM_PANIC_ON_OOM, 627 .procname = "panic_on_oom", 628 .data = &sysctl_panic_on_oom, 629 .maxlen = sizeof(sysctl_panic_on_oom), 630 .mode = 0644, 631 .proc_handler = &proc_dointvec, 632 }, 633 { 634 .ctl_name = VM_OVERCOMMIT_RATIO, 635 .procname = "overcommit_ratio", 636 .data = &sysctl_overcommit_ratio, 637 .maxlen = sizeof(sysctl_overcommit_ratio), 638 .mode = 0644, 639 .proc_handler = &proc_dointvec, 640 }, 641 { 642 .ctl_name = VM_PAGE_CLUSTER, 643 .procname = "page-cluster", 644 .data = &page_cluster, 645 .maxlen = sizeof(int), 646 .mode = 0644, 647 .proc_handler = &proc_dointvec, 648 }, 649 { 650 .ctl_name = VM_DIRTY_BACKGROUND, 651 .procname = "dirty_background_ratio", 652 .data = &dirty_background_ratio, 653 .maxlen = sizeof(dirty_background_ratio), 654 .mode = 0644, 655 .proc_handler = &proc_dointvec_minmax, 656 .strategy = &sysctl_intvec, 657 .extra1 = &zero, 658 .extra2 = &one_hundred, 659 }, 660 { 661 .ctl_name = VM_DIRTY_RATIO, 662 .procname = "dirty_ratio", 663 .data = &vm_dirty_ratio, 664 .maxlen = sizeof(vm_dirty_ratio), 665 .mode = 0644, 666 .proc_handler = &proc_dointvec_minmax, 667 .strategy = &sysctl_intvec, 668 .extra1 = &zero, 669 .extra2 = &one_hundred, 670 }, 671 { 672 .ctl_name = VM_DIRTY_WB_CS, 673 .procname = "dirty_writeback_centisecs", 674 .data = &dirty_writeback_interval, 675 .maxlen = sizeof(dirty_writeback_interval), 676 .mode = 0644, 677 .proc_handler = &dirty_writeback_centisecs_handler, 678 }, 679 { 680 .ctl_name = VM_DIRTY_EXPIRE_CS, 681 .procname = "dirty_expire_centisecs", 682 .data = &dirty_expire_interval, 683 .maxlen = sizeof(dirty_expire_interval), 684 .mode = 0644, 685 .proc_handler = &proc_dointvec_userhz_jiffies, 686 }, 687 { 688 .ctl_name = VM_NR_PDFLUSH_THREADS, 689 .procname = "nr_pdflush_threads", 690 .data = &nr_pdflush_threads, 691 .maxlen = sizeof nr_pdflush_threads, 692 .mode = 0444 /* read-only*/, 693 .proc_handler = &proc_dointvec, 694 }, 695 { 696 .ctl_name = VM_SWAPPINESS, 697 .procname = "swappiness", 698 .data = &vm_swappiness, 699 .maxlen = sizeof(vm_swappiness), 700 .mode = 0644, 701 .proc_handler = &proc_dointvec_minmax, 702 .strategy = &sysctl_intvec, 703 .extra1 = &zero, 704 .extra2 = &one_hundred, 705 }, 706 #ifdef CONFIG_HUGETLB_PAGE 707 { 708 .ctl_name = VM_HUGETLB_PAGES, 709 .procname = "nr_hugepages", 710 .data = &max_huge_pages, 711 .maxlen = sizeof(unsigned long), 712 .mode = 0644, 713 .proc_handler = &hugetlb_sysctl_handler, 714 .extra1 = (void *)&hugetlb_zero, 715 .extra2 = (void *)&hugetlb_infinity, 716 }, 717 { 718 .ctl_name = VM_HUGETLB_GROUP, 719 .procname = "hugetlb_shm_group", 720 .data = &sysctl_hugetlb_shm_group, 721 .maxlen = sizeof(gid_t), 722 .mode = 0644, 723 .proc_handler = &proc_dointvec, 724 }, 725 #endif 726 { 727 .ctl_name = VM_LOWMEM_RESERVE_RATIO, 728 .procname = "lowmem_reserve_ratio", 729 .data = &sysctl_lowmem_reserve_ratio, 730 .maxlen = sizeof(sysctl_lowmem_reserve_ratio), 731 .mode = 0644, 732 .proc_handler = &lowmem_reserve_ratio_sysctl_handler, 733 .strategy = &sysctl_intvec, 734 }, 735 { 736 .ctl_name = VM_DROP_PAGECACHE, 737 .procname = "drop_caches", 738 .data = &sysctl_drop_caches, 739 .maxlen = sizeof(int), 740 .mode = 0644, 741 .proc_handler = drop_caches_sysctl_handler, 742 .strategy = &sysctl_intvec, 743 }, 744 { 745 .ctl_name = VM_MIN_FREE_KBYTES, 746 .procname = "min_free_kbytes", 747 .data = &min_free_kbytes, 748 .maxlen = sizeof(min_free_kbytes), 749 .mode = 0644, 750 .proc_handler = &min_free_kbytes_sysctl_handler, 751 .strategy = &sysctl_intvec, 752 .extra1 = &zero, 753 }, 754 { 755 .ctl_name = VM_PERCPU_PAGELIST_FRACTION, 756 .procname = "percpu_pagelist_fraction", 757 .data = &percpu_pagelist_fraction, 758 .maxlen = sizeof(percpu_pagelist_fraction), 759 .mode = 0644, 760 .proc_handler = &percpu_pagelist_fraction_sysctl_handler, 761 .strategy = &sysctl_intvec, 762 .extra1 = &min_percpu_pagelist_fract, 763 }, 764 #ifdef CONFIG_MMU 765 { 766 .ctl_name = VM_MAX_MAP_COUNT, 767 .procname = "max_map_count", 768 .data = &sysctl_max_map_count, 769 .maxlen = sizeof(sysctl_max_map_count), 770 .mode = 0644, 771 .proc_handler = &proc_dointvec 772 }, 773 #endif 774 { 775 .ctl_name = VM_LAPTOP_MODE, 776 .procname = "laptop_mode", 777 .data = &laptop_mode, 778 .maxlen = sizeof(laptop_mode), 779 .mode = 0644, 780 .proc_handler = &proc_dointvec_jiffies, 781 .strategy = &sysctl_jiffies, 782 }, 783 { 784 .ctl_name = VM_BLOCK_DUMP, 785 .procname = "block_dump", 786 .data = &block_dump, 787 .maxlen = sizeof(block_dump), 788 .mode = 0644, 789 .proc_handler = &proc_dointvec, 790 .strategy = &sysctl_intvec, 791 .extra1 = &zero, 792 }, 793 { 794 .ctl_name = VM_VFS_CACHE_PRESSURE, 795 .procname = "vfs_cache_pressure", 796 .data = &sysctl_vfs_cache_pressure, 797 .maxlen = sizeof(sysctl_vfs_cache_pressure), 798 .mode = 0644, 799 .proc_handler = &proc_dointvec, 800 .strategy = &sysctl_intvec, 801 .extra1 = &zero, 802 }, 803 #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT 804 { 805 .ctl_name = VM_LEGACY_VA_LAYOUT, 806 .procname = "legacy_va_layout", 807 .data = &sysctl_legacy_va_layout, 808 .maxlen = sizeof(sysctl_legacy_va_layout), 809 .mode = 0644, 810 .proc_handler = &proc_dointvec, 811 .strategy = &sysctl_intvec, 812 .extra1 = &zero, 813 }, 814 #endif 815 #ifdef CONFIG_NUMA 816 { 817 .ctl_name = VM_ZONE_RECLAIM_MODE, 818 .procname = "zone_reclaim_mode", 819 .data = &zone_reclaim_mode, 820 .maxlen = sizeof(zone_reclaim_mode), 821 .mode = 0644, 822 .proc_handler = &proc_dointvec, 823 .strategy = &sysctl_intvec, 824 .extra1 = &zero, 825 }, 826 { 827 .ctl_name = VM_MIN_UNMAPPED, 828 .procname = "min_unmapped_ratio", 829 .data = &sysctl_min_unmapped_ratio, 830 .maxlen = sizeof(sysctl_min_unmapped_ratio), 831 .mode = 0644, 832 .proc_handler = &sysctl_min_unmapped_ratio_sysctl_handler, 833 .strategy = &sysctl_intvec, 834 .extra1 = &zero, 835 .extra2 = &one_hundred, 836 }, 837 { 838 .ctl_name = VM_MIN_SLAB, 839 .procname = "min_slab_ratio", 840 .data = &sysctl_min_slab_ratio, 841 .maxlen = sizeof(sysctl_min_slab_ratio), 842 .mode = 0644, 843 .proc_handler = &sysctl_min_slab_ratio_sysctl_handler, 844 .strategy = &sysctl_intvec, 845 .extra1 = &zero, 846 .extra2 = &one_hundred, 847 }, 848 #endif 849 #if defined(CONFIG_X86_32) || \ 850 (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL)) 851 { 852 .ctl_name = VM_VDSO_ENABLED, 853 .procname = "vdso_enabled", 854 .data = &vdso_enabled, 855 .maxlen = sizeof(vdso_enabled), 856 .mode = 0644, 857 .proc_handler = &proc_dointvec, 858 .strategy = &sysctl_intvec, 859 .extra1 = &zero, 860 }, 861 #endif 862 { .ctl_name = 0 } 863 }; 864 865 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) 866 static ctl_table binfmt_misc_table[] = { 867 { .ctl_name = 0 } 868 }; 869 #endif 870 871 static ctl_table fs_table[] = { 872 { 873 .ctl_name = FS_NRINODE, 874 .procname = "inode-nr", 875 .data = &inodes_stat, 876 .maxlen = 2*sizeof(int), 877 .mode = 0444, 878 .proc_handler = &proc_dointvec, 879 }, 880 { 881 .ctl_name = FS_STATINODE, 882 .procname = "inode-state", 883 .data = &inodes_stat, 884 .maxlen = 7*sizeof(int), 885 .mode = 0444, 886 .proc_handler = &proc_dointvec, 887 }, 888 { 889 .ctl_name = FS_NRFILE, 890 .procname = "file-nr", 891 .data = &files_stat, 892 .maxlen = 3*sizeof(int), 893 .mode = 0444, 894 .proc_handler = &proc_nr_files, 895 }, 896 { 897 .ctl_name = FS_MAXFILE, 898 .procname = "file-max", 899 .data = &files_stat.max_files, 900 .maxlen = sizeof(int), 901 .mode = 0644, 902 .proc_handler = &proc_dointvec, 903 }, 904 { 905 .ctl_name = FS_DENTRY, 906 .procname = "dentry-state", 907 .data = &dentry_stat, 908 .maxlen = 6*sizeof(int), 909 .mode = 0444, 910 .proc_handler = &proc_dointvec, 911 }, 912 { 913 .ctl_name = FS_OVERFLOWUID, 914 .procname = "overflowuid", 915 .data = &fs_overflowuid, 916 .maxlen = sizeof(int), 917 .mode = 0644, 918 .proc_handler = &proc_dointvec_minmax, 919 .strategy = &sysctl_intvec, 920 .extra1 = &minolduid, 921 .extra2 = &maxolduid, 922 }, 923 { 924 .ctl_name = FS_OVERFLOWGID, 925 .procname = "overflowgid", 926 .data = &fs_overflowgid, 927 .maxlen = sizeof(int), 928 .mode = 0644, 929 .proc_handler = &proc_dointvec_minmax, 930 .strategy = &sysctl_intvec, 931 .extra1 = &minolduid, 932 .extra2 = &maxolduid, 933 }, 934 { 935 .ctl_name = FS_LEASES, 936 .procname = "leases-enable", 937 .data = &leases_enable, 938 .maxlen = sizeof(int), 939 .mode = 0644, 940 .proc_handler = &proc_dointvec, 941 }, 942 #ifdef CONFIG_DNOTIFY 943 { 944 .ctl_name = FS_DIR_NOTIFY, 945 .procname = "dir-notify-enable", 946 .data = &dir_notify_enable, 947 .maxlen = sizeof(int), 948 .mode = 0644, 949 .proc_handler = &proc_dointvec, 950 }, 951 #endif 952 #ifdef CONFIG_MMU 953 { 954 .ctl_name = FS_LEASE_TIME, 955 .procname = "lease-break-time", 956 .data = &lease_break_time, 957 .maxlen = sizeof(int), 958 .mode = 0644, 959 .proc_handler = &proc_dointvec, 960 }, 961 { 962 .ctl_name = FS_AIO_NR, 963 .procname = "aio-nr", 964 .data = &aio_nr, 965 .maxlen = sizeof(aio_nr), 966 .mode = 0444, 967 .proc_handler = &proc_doulongvec_minmax, 968 }, 969 { 970 .ctl_name = FS_AIO_MAX_NR, 971 .procname = "aio-max-nr", 972 .data = &aio_max_nr, 973 .maxlen = sizeof(aio_max_nr), 974 .mode = 0644, 975 .proc_handler = &proc_doulongvec_minmax, 976 }, 977 #ifdef CONFIG_INOTIFY_USER 978 { 979 .ctl_name = FS_INOTIFY, 980 .procname = "inotify", 981 .mode = 0555, 982 .child = inotify_table, 983 }, 984 #endif 985 #endif 986 { 987 .ctl_name = KERN_SETUID_DUMPABLE, 988 .procname = "suid_dumpable", 989 .data = &suid_dumpable, 990 .maxlen = sizeof(int), 991 .mode = 0644, 992 .proc_handler = &proc_dointvec, 993 }, 994 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) 995 { 996 .ctl_name = CTL_UNNUMBERED, 997 .procname = "binfmt_misc", 998 .mode = 0555, 999 .child = binfmt_misc_table, 1000 }, 1001 #endif 1002 { .ctl_name = 0 } 1003 }; 1004 1005 static ctl_table debug_table[] = { 1006 { .ctl_name = 0 } 1007 }; 1008 1009 static ctl_table dev_table[] = { 1010 { .ctl_name = 0 } 1011 }; 1012 1013 static DEFINE_SPINLOCK(sysctl_lock); 1014 1015 /* called under sysctl_lock */ 1016 static int use_table(struct ctl_table_header *p) 1017 { 1018 if (unlikely(p->unregistering)) 1019 return 0; 1020 p->used++; 1021 return 1; 1022 } 1023 1024 /* called under sysctl_lock */ 1025 static void unuse_table(struct ctl_table_header *p) 1026 { 1027 if (!--p->used) 1028 if (unlikely(p->unregistering)) 1029 complete(p->unregistering); 1030 } 1031 1032 /* called under sysctl_lock, will reacquire if has to wait */ 1033 static void start_unregistering(struct ctl_table_header *p) 1034 { 1035 /* 1036 * if p->used is 0, nobody will ever touch that entry again; 1037 * we'll eliminate all paths to it before dropping sysctl_lock 1038 */ 1039 if (unlikely(p->used)) { 1040 struct completion wait; 1041 init_completion(&wait); 1042 p->unregistering = &wait; 1043 spin_unlock(&sysctl_lock); 1044 wait_for_completion(&wait); 1045 spin_lock(&sysctl_lock); 1046 } 1047 /* 1048 * do not remove from the list until nobody holds it; walking the 1049 * list in do_sysctl() relies on that. 1050 */ 1051 list_del_init(&p->ctl_entry); 1052 } 1053 1054 void sysctl_head_finish(struct ctl_table_header *head) 1055 { 1056 if (!head) 1057 return; 1058 spin_lock(&sysctl_lock); 1059 unuse_table(head); 1060 spin_unlock(&sysctl_lock); 1061 } 1062 1063 struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev) 1064 { 1065 struct ctl_table_header *head; 1066 struct list_head *tmp; 1067 spin_lock(&sysctl_lock); 1068 if (prev) { 1069 tmp = &prev->ctl_entry; 1070 unuse_table(prev); 1071 goto next; 1072 } 1073 tmp = &root_table_header.ctl_entry; 1074 for (;;) { 1075 head = list_entry(tmp, struct ctl_table_header, ctl_entry); 1076 1077 if (!use_table(head)) 1078 goto next; 1079 spin_unlock(&sysctl_lock); 1080 return head; 1081 next: 1082 tmp = tmp->next; 1083 if (tmp == &root_table_header.ctl_entry) 1084 break; 1085 } 1086 spin_unlock(&sysctl_lock); 1087 return NULL; 1088 } 1089 1090 #ifdef CONFIG_SYSCTL_SYSCALL 1091 int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, 1092 void __user *newval, size_t newlen) 1093 { 1094 struct ctl_table_header *head; 1095 int error = -ENOTDIR; 1096 1097 if (nlen <= 0 || nlen >= CTL_MAXNAME) 1098 return -ENOTDIR; 1099 if (oldval) { 1100 int old_len; 1101 if (!oldlenp || get_user(old_len, oldlenp)) 1102 return -EFAULT; 1103 } 1104 1105 for (head = sysctl_head_next(NULL); head; 1106 head = sysctl_head_next(head)) { 1107 error = parse_table(name, nlen, oldval, oldlenp, 1108 newval, newlen, head->ctl_table); 1109 if (error != -ENOTDIR) { 1110 sysctl_head_finish(head); 1111 break; 1112 } 1113 } 1114 return error; 1115 } 1116 1117 asmlinkage long sys_sysctl(struct __sysctl_args __user *args) 1118 { 1119 struct __sysctl_args tmp; 1120 int error; 1121 1122 if (copy_from_user(&tmp, args, sizeof(tmp))) 1123 return -EFAULT; 1124 1125 lock_kernel(); 1126 error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp, 1127 tmp.newval, tmp.newlen); 1128 unlock_kernel(); 1129 return error; 1130 } 1131 #endif /* CONFIG_SYSCTL_SYSCALL */ 1132 1133 /* 1134 * sysctl_perm does NOT grant the superuser all rights automatically, because 1135 * some sysctl variables are readonly even to root. 1136 */ 1137 1138 static int test_perm(int mode, int op) 1139 { 1140 if (!current->euid) 1141 mode >>= 6; 1142 else if (in_egroup_p(0)) 1143 mode >>= 3; 1144 if ((mode & op & 0007) == op) 1145 return 0; 1146 return -EACCES; 1147 } 1148 1149 int sysctl_perm(ctl_table *table, int op) 1150 { 1151 int error; 1152 error = security_sysctl(table, op); 1153 if (error) 1154 return error; 1155 return test_perm(table->mode, op); 1156 } 1157 1158 #ifdef CONFIG_SYSCTL_SYSCALL 1159 static int parse_table(int __user *name, int nlen, 1160 void __user *oldval, size_t __user *oldlenp, 1161 void __user *newval, size_t newlen, 1162 ctl_table *table) 1163 { 1164 int n; 1165 repeat: 1166 if (!nlen) 1167 return -ENOTDIR; 1168 if (get_user(n, name)) 1169 return -EFAULT; 1170 for ( ; table->ctl_name || table->procname; table++) { 1171 if (!table->ctl_name) 1172 continue; 1173 if (n == table->ctl_name) { 1174 int error; 1175 if (table->child) { 1176 if (sysctl_perm(table, 001)) 1177 return -EPERM; 1178 name++; 1179 nlen--; 1180 table = table->child; 1181 goto repeat; 1182 } 1183 error = do_sysctl_strategy(table, name, nlen, 1184 oldval, oldlenp, 1185 newval, newlen); 1186 return error; 1187 } 1188 } 1189 return -ENOTDIR; 1190 } 1191 1192 /* Perform the actual read/write of a sysctl table entry. */ 1193 int do_sysctl_strategy (ctl_table *table, 1194 int __user *name, int nlen, 1195 void __user *oldval, size_t __user *oldlenp, 1196 void __user *newval, size_t newlen) 1197 { 1198 int op = 0, rc; 1199 size_t len; 1200 1201 if (oldval) 1202 op |= 004; 1203 if (newval) 1204 op |= 002; 1205 if (sysctl_perm(table, op)) 1206 return -EPERM; 1207 1208 if (table->strategy) { 1209 rc = table->strategy(table, name, nlen, oldval, oldlenp, 1210 newval, newlen); 1211 if (rc < 0) 1212 return rc; 1213 if (rc > 0) 1214 return 0; 1215 } 1216 1217 /* If there is no strategy routine, or if the strategy returns 1218 * zero, proceed with automatic r/w */ 1219 if (table->data && table->maxlen) { 1220 if (oldval && oldlenp) { 1221 if (get_user(len, oldlenp)) 1222 return -EFAULT; 1223 if (len) { 1224 if (len > table->maxlen) 1225 len = table->maxlen; 1226 if(copy_to_user(oldval, table->data, len)) 1227 return -EFAULT; 1228 if(put_user(len, oldlenp)) 1229 return -EFAULT; 1230 } 1231 } 1232 if (newval && newlen) { 1233 len = newlen; 1234 if (len > table->maxlen) 1235 len = table->maxlen; 1236 if(copy_from_user(table->data, newval, len)) 1237 return -EFAULT; 1238 } 1239 } 1240 return 0; 1241 } 1242 #endif /* CONFIG_SYSCTL_SYSCALL */ 1243 1244 static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table) 1245 { 1246 for (; table->ctl_name || table->procname; table++) { 1247 table->parent = parent; 1248 if (table->child) 1249 sysctl_set_parent(table, table->child); 1250 } 1251 } 1252 1253 static __init int sysctl_init(void) 1254 { 1255 sysctl_set_parent(NULL, root_table); 1256 return 0; 1257 } 1258 1259 core_initcall(sysctl_init); 1260 1261 /** 1262 * register_sysctl_table - register a sysctl hierarchy 1263 * @table: the top-level table structure 1264 * 1265 * Register a sysctl table hierarchy. @table should be a filled in ctl_table 1266 * array. An entry with a ctl_name of 0 terminates the table. 1267 * 1268 * The members of the &ctl_table structure are used as follows: 1269 * 1270 * ctl_name - This is the numeric sysctl value used by sysctl(2). The number 1271 * must be unique within that level of sysctl 1272 * 1273 * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not 1274 * enter a sysctl file 1275 * 1276 * data - a pointer to data for use by proc_handler 1277 * 1278 * maxlen - the maximum size in bytes of the data 1279 * 1280 * mode - the file permissions for the /proc/sys file, and for sysctl(2) 1281 * 1282 * child - a pointer to the child sysctl table if this entry is a directory, or 1283 * %NULL. 1284 * 1285 * proc_handler - the text handler routine (described below) 1286 * 1287 * strategy - the strategy routine (described below) 1288 * 1289 * de - for internal use by the sysctl routines 1290 * 1291 * extra1, extra2 - extra pointers usable by the proc handler routines 1292 * 1293 * Leaf nodes in the sysctl tree will be represented by a single file 1294 * under /proc; non-leaf nodes will be represented by directories. 1295 * 1296 * sysctl(2) can automatically manage read and write requests through 1297 * the sysctl table. The data and maxlen fields of the ctl_table 1298 * struct enable minimal validation of the values being written to be 1299 * performed, and the mode field allows minimal authentication. 1300 * 1301 * More sophisticated management can be enabled by the provision of a 1302 * strategy routine with the table entry. This will be called before 1303 * any automatic read or write of the data is performed. 1304 * 1305 * The strategy routine may return 1306 * 1307 * < 0 - Error occurred (error is passed to user process) 1308 * 1309 * 0 - OK - proceed with automatic read or write. 1310 * 1311 * > 0 - OK - read or write has been done by the strategy routine, so 1312 * return immediately. 1313 * 1314 * There must be a proc_handler routine for any terminal nodes 1315 * mirrored under /proc/sys (non-terminals are handled by a built-in 1316 * directory handler). Several default handlers are available to 1317 * cover common cases - 1318 * 1319 * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(), 1320 * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(), 1321 * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax() 1322 * 1323 * It is the handler's job to read the input buffer from user memory 1324 * and process it. The handler should return 0 on success. 1325 * 1326 * This routine returns %NULL on a failure to register, and a pointer 1327 * to the table header on success. 1328 */ 1329 struct ctl_table_header *register_sysctl_table(ctl_table * table) 1330 { 1331 struct ctl_table_header *tmp; 1332 tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL); 1333 if (!tmp) 1334 return NULL; 1335 tmp->ctl_table = table; 1336 INIT_LIST_HEAD(&tmp->ctl_entry); 1337 tmp->used = 0; 1338 tmp->unregistering = NULL; 1339 sysctl_set_parent(NULL, table); 1340 spin_lock(&sysctl_lock); 1341 list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); 1342 spin_unlock(&sysctl_lock); 1343 return tmp; 1344 } 1345 1346 /** 1347 * unregister_sysctl_table - unregister a sysctl table hierarchy 1348 * @header: the header returned from register_sysctl_table 1349 * 1350 * Unregisters the sysctl table and all children. proc entries may not 1351 * actually be removed until they are no longer used by anyone. 1352 */ 1353 void unregister_sysctl_table(struct ctl_table_header * header) 1354 { 1355 might_sleep(); 1356 spin_lock(&sysctl_lock); 1357 start_unregistering(header); 1358 spin_unlock(&sysctl_lock); 1359 kfree(header); 1360 } 1361 1362 #else /* !CONFIG_SYSCTL */ 1363 struct ctl_table_header *register_sysctl_table(ctl_table * table) 1364 { 1365 return NULL; 1366 } 1367 1368 void unregister_sysctl_table(struct ctl_table_header * table) 1369 { 1370 } 1371 1372 #endif /* CONFIG_SYSCTL */ 1373 1374 /* 1375 * /proc/sys support 1376 */ 1377 1378 #ifdef CONFIG_PROC_SYSCTL 1379 1380 static int _proc_do_string(void* data, int maxlen, int write, 1381 struct file *filp, void __user *buffer, 1382 size_t *lenp, loff_t *ppos) 1383 { 1384 size_t len; 1385 char __user *p; 1386 char c; 1387 1388 if (!data || !maxlen || !*lenp) { 1389 *lenp = 0; 1390 return 0; 1391 } 1392 1393 if (write) { 1394 len = 0; 1395 p = buffer; 1396 while (len < *lenp) { 1397 if (get_user(c, p++)) 1398 return -EFAULT; 1399 if (c == 0 || c == '\n') 1400 break; 1401 len++; 1402 } 1403 if (len >= maxlen) 1404 len = maxlen-1; 1405 if(copy_from_user(data, buffer, len)) 1406 return -EFAULT; 1407 ((char *) data)[len] = 0; 1408 *ppos += *lenp; 1409 } else { 1410 len = strlen(data); 1411 if (len > maxlen) 1412 len = maxlen; 1413 1414 if (*ppos > len) { 1415 *lenp = 0; 1416 return 0; 1417 } 1418 1419 data += *ppos; 1420 len -= *ppos; 1421 1422 if (len > *lenp) 1423 len = *lenp; 1424 if (len) 1425 if(copy_to_user(buffer, data, len)) 1426 return -EFAULT; 1427 if (len < *lenp) { 1428 if(put_user('\n', ((char __user *) buffer) + len)) 1429 return -EFAULT; 1430 len++; 1431 } 1432 *lenp = len; 1433 *ppos += len; 1434 } 1435 return 0; 1436 } 1437 1438 /** 1439 * proc_dostring - read a string sysctl 1440 * @table: the sysctl table 1441 * @write: %TRUE if this is a write to the sysctl file 1442 * @filp: the file structure 1443 * @buffer: the user buffer 1444 * @lenp: the size of the user buffer 1445 * @ppos: file position 1446 * 1447 * Reads/writes a string from/to the user buffer. If the kernel 1448 * buffer provided is not large enough to hold the string, the 1449 * string is truncated. The copied string is %NULL-terminated. 1450 * If the string is being read by the user process, it is copied 1451 * and a newline '\n' is added. It is truncated if the buffer is 1452 * not large enough. 1453 * 1454 * Returns 0 on success. 1455 */ 1456 int proc_dostring(ctl_table *table, int write, struct file *filp, 1457 void __user *buffer, size_t *lenp, loff_t *ppos) 1458 { 1459 return _proc_do_string(table->data, table->maxlen, write, filp, 1460 buffer, lenp, ppos); 1461 } 1462 1463 1464 static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, 1465 int *valp, 1466 int write, void *data) 1467 { 1468 if (write) { 1469 *valp = *negp ? -*lvalp : *lvalp; 1470 } else { 1471 int val = *valp; 1472 if (val < 0) { 1473 *negp = -1; 1474 *lvalp = (unsigned long)-val; 1475 } else { 1476 *negp = 0; 1477 *lvalp = (unsigned long)val; 1478 } 1479 } 1480 return 0; 1481 } 1482 1483 static int __do_proc_dointvec(void *tbl_data, ctl_table *table, 1484 int write, struct file *filp, void __user *buffer, 1485 size_t *lenp, loff_t *ppos, 1486 int (*conv)(int *negp, unsigned long *lvalp, int *valp, 1487 int write, void *data), 1488 void *data) 1489 { 1490 #define TMPBUFLEN 21 1491 int *i, vleft, first=1, neg, val; 1492 unsigned long lval; 1493 size_t left, len; 1494 1495 char buf[TMPBUFLEN], *p; 1496 char __user *s = buffer; 1497 1498 if (!tbl_data || !table->maxlen || !*lenp || 1499 (*ppos && !write)) { 1500 *lenp = 0; 1501 return 0; 1502 } 1503 1504 i = (int *) tbl_data; 1505 vleft = table->maxlen / sizeof(*i); 1506 left = *lenp; 1507 1508 if (!conv) 1509 conv = do_proc_dointvec_conv; 1510 1511 for (; left && vleft--; i++, first=0) { 1512 if (write) { 1513 while (left) { 1514 char c; 1515 if (get_user(c, s)) 1516 return -EFAULT; 1517 if (!isspace(c)) 1518 break; 1519 left--; 1520 s++; 1521 } 1522 if (!left) 1523 break; 1524 neg = 0; 1525 len = left; 1526 if (len > sizeof(buf) - 1) 1527 len = sizeof(buf) - 1; 1528 if (copy_from_user(buf, s, len)) 1529 return -EFAULT; 1530 buf[len] = 0; 1531 p = buf; 1532 if (*p == '-' && left > 1) { 1533 neg = 1; 1534 p++; 1535 } 1536 if (*p < '0' || *p > '9') 1537 break; 1538 1539 lval = simple_strtoul(p, &p, 0); 1540 1541 len = p-buf; 1542 if ((len < left) && *p && !isspace(*p)) 1543 break; 1544 if (neg) 1545 val = -val; 1546 s += len; 1547 left -= len; 1548 1549 if (conv(&neg, &lval, i, 1, data)) 1550 break; 1551 } else { 1552 p = buf; 1553 if (!first) 1554 *p++ = '\t'; 1555 1556 if (conv(&neg, &lval, i, 0, data)) 1557 break; 1558 1559 sprintf(p, "%s%lu", neg ? "-" : "", lval); 1560 len = strlen(buf); 1561 if (len > left) 1562 len = left; 1563 if(copy_to_user(s, buf, len)) 1564 return -EFAULT; 1565 left -= len; 1566 s += len; 1567 } 1568 } 1569 1570 if (!write && !first && left) { 1571 if(put_user('\n', s)) 1572 return -EFAULT; 1573 left--, s++; 1574 } 1575 if (write) { 1576 while (left) { 1577 char c; 1578 if (get_user(c, s++)) 1579 return -EFAULT; 1580 if (!isspace(c)) 1581 break; 1582 left--; 1583 } 1584 } 1585 if (write && first) 1586 return -EINVAL; 1587 *lenp -= left; 1588 *ppos += *lenp; 1589 return 0; 1590 #undef TMPBUFLEN 1591 } 1592 1593 static int do_proc_dointvec(ctl_table *table, int write, struct file *filp, 1594 void __user *buffer, size_t *lenp, loff_t *ppos, 1595 int (*conv)(int *negp, unsigned long *lvalp, int *valp, 1596 int write, void *data), 1597 void *data) 1598 { 1599 return __do_proc_dointvec(table->data, table, write, filp, 1600 buffer, lenp, ppos, conv, data); 1601 } 1602 1603 /** 1604 * proc_dointvec - read a vector of integers 1605 * @table: the sysctl table 1606 * @write: %TRUE if this is a write to the sysctl file 1607 * @filp: the file structure 1608 * @buffer: the user buffer 1609 * @lenp: the size of the user buffer 1610 * @ppos: file position 1611 * 1612 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 1613 * values from/to the user buffer, treated as an ASCII string. 1614 * 1615 * Returns 0 on success. 1616 */ 1617 int proc_dointvec(ctl_table *table, int write, struct file *filp, 1618 void __user *buffer, size_t *lenp, loff_t *ppos) 1619 { 1620 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 1621 NULL,NULL); 1622 } 1623 1624 #define OP_SET 0 1625 #define OP_AND 1 1626 #define OP_OR 2 1627 1628 static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, 1629 int *valp, 1630 int write, void *data) 1631 { 1632 int op = *(int *)data; 1633 if (write) { 1634 int val = *negp ? -*lvalp : *lvalp; 1635 switch(op) { 1636 case OP_SET: *valp = val; break; 1637 case OP_AND: *valp &= val; break; 1638 case OP_OR: *valp |= val; break; 1639 } 1640 } else { 1641 int val = *valp; 1642 if (val < 0) { 1643 *negp = -1; 1644 *lvalp = (unsigned long)-val; 1645 } else { 1646 *negp = 0; 1647 *lvalp = (unsigned long)val; 1648 } 1649 } 1650 return 0; 1651 } 1652 1653 /* 1654 * init may raise the set. 1655 */ 1656 1657 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, 1658 void __user *buffer, size_t *lenp, loff_t *ppos) 1659 { 1660 int op; 1661 1662 if (write && !capable(CAP_SYS_MODULE)) { 1663 return -EPERM; 1664 } 1665 1666 op = is_init(current) ? OP_SET : OP_AND; 1667 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 1668 do_proc_dointvec_bset_conv,&op); 1669 } 1670 1671 /* 1672 * Taint values can only be increased 1673 */ 1674 static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp, 1675 void __user *buffer, size_t *lenp, loff_t *ppos) 1676 { 1677 int op; 1678 1679 if (!capable(CAP_SYS_ADMIN)) 1680 return -EPERM; 1681 1682 op = OP_OR; 1683 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 1684 do_proc_dointvec_bset_conv,&op); 1685 } 1686 1687 struct do_proc_dointvec_minmax_conv_param { 1688 int *min; 1689 int *max; 1690 }; 1691 1692 static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp, 1693 int *valp, 1694 int write, void *data) 1695 { 1696 struct do_proc_dointvec_minmax_conv_param *param = data; 1697 if (write) { 1698 int val = *negp ? -*lvalp : *lvalp; 1699 if ((param->min && *param->min > val) || 1700 (param->max && *param->max < val)) 1701 return -EINVAL; 1702 *valp = val; 1703 } else { 1704 int val = *valp; 1705 if (val < 0) { 1706 *negp = -1; 1707 *lvalp = (unsigned long)-val; 1708 } else { 1709 *negp = 0; 1710 *lvalp = (unsigned long)val; 1711 } 1712 } 1713 return 0; 1714 } 1715 1716 /** 1717 * proc_dointvec_minmax - read a vector of integers with min/max values 1718 * @table: the sysctl table 1719 * @write: %TRUE if this is a write to the sysctl file 1720 * @filp: the file structure 1721 * @buffer: the user buffer 1722 * @lenp: the size of the user buffer 1723 * @ppos: file position 1724 * 1725 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 1726 * values from/to the user buffer, treated as an ASCII string. 1727 * 1728 * This routine will ensure the values are within the range specified by 1729 * table->extra1 (min) and table->extra2 (max). 1730 * 1731 * Returns 0 on success. 1732 */ 1733 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, 1734 void __user *buffer, size_t *lenp, loff_t *ppos) 1735 { 1736 struct do_proc_dointvec_minmax_conv_param param = { 1737 .min = (int *) table->extra1, 1738 .max = (int *) table->extra2, 1739 }; 1740 return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, 1741 do_proc_dointvec_minmax_conv, ¶m); 1742 } 1743 1744 static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write, 1745 struct file *filp, 1746 void __user *buffer, 1747 size_t *lenp, loff_t *ppos, 1748 unsigned long convmul, 1749 unsigned long convdiv) 1750 { 1751 #define TMPBUFLEN 21 1752 unsigned long *i, *min, *max, val; 1753 int vleft, first=1, neg; 1754 size_t len, left; 1755 char buf[TMPBUFLEN], *p; 1756 char __user *s = buffer; 1757 1758 if (!data || !table->maxlen || !*lenp || 1759 (*ppos && !write)) { 1760 *lenp = 0; 1761 return 0; 1762 } 1763 1764 i = (unsigned long *) data; 1765 min = (unsigned long *) table->extra1; 1766 max = (unsigned long *) table->extra2; 1767 vleft = table->maxlen / sizeof(unsigned long); 1768 left = *lenp; 1769 1770 for (; left && vleft--; i++, min++, max++, first=0) { 1771 if (write) { 1772 while (left) { 1773 char c; 1774 if (get_user(c, s)) 1775 return -EFAULT; 1776 if (!isspace(c)) 1777 break; 1778 left--; 1779 s++; 1780 } 1781 if (!left) 1782 break; 1783 neg = 0; 1784 len = left; 1785 if (len > TMPBUFLEN-1) 1786 len = TMPBUFLEN-1; 1787 if (copy_from_user(buf, s, len)) 1788 return -EFAULT; 1789 buf[len] = 0; 1790 p = buf; 1791 if (*p == '-' && left > 1) { 1792 neg = 1; 1793 p++; 1794 } 1795 if (*p < '0' || *p > '9') 1796 break; 1797 val = simple_strtoul(p, &p, 0) * convmul / convdiv ; 1798 len = p-buf; 1799 if ((len < left) && *p && !isspace(*p)) 1800 break; 1801 if (neg) 1802 val = -val; 1803 s += len; 1804 left -= len; 1805 1806 if(neg) 1807 continue; 1808 if ((min && val < *min) || (max && val > *max)) 1809 continue; 1810 *i = val; 1811 } else { 1812 p = buf; 1813 if (!first) 1814 *p++ = '\t'; 1815 sprintf(p, "%lu", convdiv * (*i) / convmul); 1816 len = strlen(buf); 1817 if (len > left) 1818 len = left; 1819 if(copy_to_user(s, buf, len)) 1820 return -EFAULT; 1821 left -= len; 1822 s += len; 1823 } 1824 } 1825 1826 if (!write && !first && left) { 1827 if(put_user('\n', s)) 1828 return -EFAULT; 1829 left--, s++; 1830 } 1831 if (write) { 1832 while (left) { 1833 char c; 1834 if (get_user(c, s++)) 1835 return -EFAULT; 1836 if (!isspace(c)) 1837 break; 1838 left--; 1839 } 1840 } 1841 if (write && first) 1842 return -EINVAL; 1843 *lenp -= left; 1844 *ppos += *lenp; 1845 return 0; 1846 #undef TMPBUFLEN 1847 } 1848 1849 static int do_proc_doulongvec_minmax(ctl_table *table, int write, 1850 struct file *filp, 1851 void __user *buffer, 1852 size_t *lenp, loff_t *ppos, 1853 unsigned long convmul, 1854 unsigned long convdiv) 1855 { 1856 return __do_proc_doulongvec_minmax(table->data, table, write, 1857 filp, buffer, lenp, ppos, convmul, convdiv); 1858 } 1859 1860 /** 1861 * proc_doulongvec_minmax - read a vector of long integers with min/max values 1862 * @table: the sysctl table 1863 * @write: %TRUE if this is a write to the sysctl file 1864 * @filp: the file structure 1865 * @buffer: the user buffer 1866 * @lenp: the size of the user buffer 1867 * @ppos: file position 1868 * 1869 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long 1870 * values from/to the user buffer, treated as an ASCII string. 1871 * 1872 * This routine will ensure the values are within the range specified by 1873 * table->extra1 (min) and table->extra2 (max). 1874 * 1875 * Returns 0 on success. 1876 */ 1877 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, 1878 void __user *buffer, size_t *lenp, loff_t *ppos) 1879 { 1880 return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l); 1881 } 1882 1883 /** 1884 * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values 1885 * @table: the sysctl table 1886 * @write: %TRUE if this is a write to the sysctl file 1887 * @filp: the file structure 1888 * @buffer: the user buffer 1889 * @lenp: the size of the user buffer 1890 * @ppos: file position 1891 * 1892 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long 1893 * values from/to the user buffer, treated as an ASCII string. The values 1894 * are treated as milliseconds, and converted to jiffies when they are stored. 1895 * 1896 * This routine will ensure the values are within the range specified by 1897 * table->extra1 (min) and table->extra2 (max). 1898 * 1899 * Returns 0 on success. 1900 */ 1901 int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write, 1902 struct file *filp, 1903 void __user *buffer, 1904 size_t *lenp, loff_t *ppos) 1905 { 1906 return do_proc_doulongvec_minmax(table, write, filp, buffer, 1907 lenp, ppos, HZ, 1000l); 1908 } 1909 1910 1911 static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp, 1912 int *valp, 1913 int write, void *data) 1914 { 1915 if (write) { 1916 if (*lvalp > LONG_MAX / HZ) 1917 return 1; 1918 *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ); 1919 } else { 1920 int val = *valp; 1921 unsigned long lval; 1922 if (val < 0) { 1923 *negp = -1; 1924 lval = (unsigned long)-val; 1925 } else { 1926 *negp = 0; 1927 lval = (unsigned long)val; 1928 } 1929 *lvalp = lval / HZ; 1930 } 1931 return 0; 1932 } 1933 1934 static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp, 1935 int *valp, 1936 int write, void *data) 1937 { 1938 if (write) { 1939 if (USER_HZ < HZ && *lvalp > (LONG_MAX / HZ) * USER_HZ) 1940 return 1; 1941 *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp); 1942 } else { 1943 int val = *valp; 1944 unsigned long lval; 1945 if (val < 0) { 1946 *negp = -1; 1947 lval = (unsigned long)-val; 1948 } else { 1949 *negp = 0; 1950 lval = (unsigned long)val; 1951 } 1952 *lvalp = jiffies_to_clock_t(lval); 1953 } 1954 return 0; 1955 } 1956 1957 static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp, 1958 int *valp, 1959 int write, void *data) 1960 { 1961 if (write) { 1962 *valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp); 1963 } else { 1964 int val = *valp; 1965 unsigned long lval; 1966 if (val < 0) { 1967 *negp = -1; 1968 lval = (unsigned long)-val; 1969 } else { 1970 *negp = 0; 1971 lval = (unsigned long)val; 1972 } 1973 *lvalp = jiffies_to_msecs(lval); 1974 } 1975 return 0; 1976 } 1977 1978 /** 1979 * proc_dointvec_jiffies - read a vector of integers as seconds 1980 * @table: the sysctl table 1981 * @write: %TRUE if this is a write to the sysctl file 1982 * @filp: the file structure 1983 * @buffer: the user buffer 1984 * @lenp: the size of the user buffer 1985 * @ppos: file position 1986 * 1987 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 1988 * values from/to the user buffer, treated as an ASCII string. 1989 * The values read are assumed to be in seconds, and are converted into 1990 * jiffies. 1991 * 1992 * Returns 0 on success. 1993 */ 1994 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, 1995 void __user *buffer, size_t *lenp, loff_t *ppos) 1996 { 1997 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 1998 do_proc_dointvec_jiffies_conv,NULL); 1999 } 2000 2001 /** 2002 * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds 2003 * @table: the sysctl table 2004 * @write: %TRUE if this is a write to the sysctl file 2005 * @filp: the file structure 2006 * @buffer: the user buffer 2007 * @lenp: the size of the user buffer 2008 * @ppos: pointer to the file position 2009 * 2010 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 2011 * values from/to the user buffer, treated as an ASCII string. 2012 * The values read are assumed to be in 1/USER_HZ seconds, and 2013 * are converted into jiffies. 2014 * 2015 * Returns 0 on success. 2016 */ 2017 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, 2018 void __user *buffer, size_t *lenp, loff_t *ppos) 2019 { 2020 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 2021 do_proc_dointvec_userhz_jiffies_conv,NULL); 2022 } 2023 2024 /** 2025 * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds 2026 * @table: the sysctl table 2027 * @write: %TRUE if this is a write to the sysctl file 2028 * @filp: the file structure 2029 * @buffer: the user buffer 2030 * @lenp: the size of the user buffer 2031 * @ppos: file position 2032 * @ppos: the current position in the file 2033 * 2034 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 2035 * values from/to the user buffer, treated as an ASCII string. 2036 * The values read are assumed to be in 1/1000 seconds, and 2037 * are converted into jiffies. 2038 * 2039 * Returns 0 on success. 2040 */ 2041 int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp, 2042 void __user *buffer, size_t *lenp, loff_t *ppos) 2043 { 2044 return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, 2045 do_proc_dointvec_ms_jiffies_conv, NULL); 2046 } 2047 2048 static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, 2049 void __user *buffer, size_t *lenp, loff_t *ppos) 2050 { 2051 struct pid *new_pid; 2052 pid_t tmp; 2053 int r; 2054 2055 tmp = pid_nr(cad_pid); 2056 2057 r = __do_proc_dointvec(&tmp, table, write, filp, buffer, 2058 lenp, ppos, NULL, NULL); 2059 if (r || !write) 2060 return r; 2061 2062 new_pid = find_get_pid(tmp); 2063 if (!new_pid) 2064 return -ESRCH; 2065 2066 put_pid(xchg(&cad_pid, new_pid)); 2067 return 0; 2068 } 2069 2070 #else /* CONFIG_PROC_FS */ 2071 2072 int proc_dostring(ctl_table *table, int write, struct file *filp, 2073 void __user *buffer, size_t *lenp, loff_t *ppos) 2074 { 2075 return -ENOSYS; 2076 } 2077 2078 int proc_dointvec(ctl_table *table, int write, struct file *filp, 2079 void __user *buffer, size_t *lenp, loff_t *ppos) 2080 { 2081 return -ENOSYS; 2082 } 2083 2084 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, 2085 void __user *buffer, size_t *lenp, loff_t *ppos) 2086 { 2087 return -ENOSYS; 2088 } 2089 2090 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, 2091 void __user *buffer, size_t *lenp, loff_t *ppos) 2092 { 2093 return -ENOSYS; 2094 } 2095 2096 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, 2097 void __user *buffer, size_t *lenp, loff_t *ppos) 2098 { 2099 return -ENOSYS; 2100 } 2101 2102 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, 2103 void __user *buffer, size_t *lenp, loff_t *ppos) 2104 { 2105 return -ENOSYS; 2106 } 2107 2108 int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp, 2109 void __user *buffer, size_t *lenp, loff_t *ppos) 2110 { 2111 return -ENOSYS; 2112 } 2113 2114 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, 2115 void __user *buffer, size_t *lenp, loff_t *ppos) 2116 { 2117 return -ENOSYS; 2118 } 2119 2120 int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write, 2121 struct file *filp, 2122 void __user *buffer, 2123 size_t *lenp, loff_t *ppos) 2124 { 2125 return -ENOSYS; 2126 } 2127 2128 2129 #endif /* CONFIG_PROC_FS */ 2130 2131 2132 #ifdef CONFIG_SYSCTL_SYSCALL 2133 /* 2134 * General sysctl support routines 2135 */ 2136 2137 /* The generic string strategy routine: */ 2138 int sysctl_string(ctl_table *table, int __user *name, int nlen, 2139 void __user *oldval, size_t __user *oldlenp, 2140 void __user *newval, size_t newlen) 2141 { 2142 if (!table->data || !table->maxlen) 2143 return -ENOTDIR; 2144 2145 if (oldval && oldlenp) { 2146 size_t bufsize; 2147 if (get_user(bufsize, oldlenp)) 2148 return -EFAULT; 2149 if (bufsize) { 2150 size_t len = strlen(table->data), copied; 2151 2152 /* This shouldn't trigger for a well-formed sysctl */ 2153 if (len > table->maxlen) 2154 len = table->maxlen; 2155 2156 /* Copy up to a max of bufsize-1 bytes of the string */ 2157 copied = (len >= bufsize) ? bufsize - 1 : len; 2158 2159 if (copy_to_user(oldval, table->data, copied) || 2160 put_user(0, (char __user *)(oldval + copied))) 2161 return -EFAULT; 2162 if (put_user(len, oldlenp)) 2163 return -EFAULT; 2164 } 2165 } 2166 if (newval && newlen) { 2167 size_t len = newlen; 2168 if (len > table->maxlen) 2169 len = table->maxlen; 2170 if(copy_from_user(table->data, newval, len)) 2171 return -EFAULT; 2172 if (len == table->maxlen) 2173 len--; 2174 ((char *) table->data)[len] = 0; 2175 } 2176 return 1; 2177 } 2178 2179 /* 2180 * This function makes sure that all of the integers in the vector 2181 * are between the minimum and maximum values given in the arrays 2182 * table->extra1 and table->extra2, respectively. 2183 */ 2184 int sysctl_intvec(ctl_table *table, int __user *name, int nlen, 2185 void __user *oldval, size_t __user *oldlenp, 2186 void __user *newval, size_t newlen) 2187 { 2188 2189 if (newval && newlen) { 2190 int __user *vec = (int __user *) newval; 2191 int *min = (int *) table->extra1; 2192 int *max = (int *) table->extra2; 2193 size_t length; 2194 int i; 2195 2196 if (newlen % sizeof(int) != 0) 2197 return -EINVAL; 2198 2199 if (!table->extra1 && !table->extra2) 2200 return 0; 2201 2202 if (newlen > table->maxlen) 2203 newlen = table->maxlen; 2204 length = newlen / sizeof(int); 2205 2206 for (i = 0; i < length; i++) { 2207 int value; 2208 if (get_user(value, vec + i)) 2209 return -EFAULT; 2210 if (min && value < min[i]) 2211 return -EINVAL; 2212 if (max && value > max[i]) 2213 return -EINVAL; 2214 } 2215 } 2216 return 0; 2217 } 2218 2219 /* Strategy function to convert jiffies to seconds */ 2220 int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, 2221 void __user *oldval, size_t __user *oldlenp, 2222 void __user *newval, size_t newlen) 2223 { 2224 if (oldval && oldlenp) { 2225 size_t olen; 2226 2227 if (get_user(olen, oldlenp)) 2228 return -EFAULT; 2229 if (olen) { 2230 int val; 2231 2232 if (olen < sizeof(int)) 2233 return -EINVAL; 2234 2235 val = *(int *)(table->data) / HZ; 2236 if (put_user(val, (int __user *)oldval)) 2237 return -EFAULT; 2238 if (put_user(sizeof(int), oldlenp)) 2239 return -EFAULT; 2240 } 2241 } 2242 if (newval && newlen) { 2243 int new; 2244 if (newlen != sizeof(int)) 2245 return -EINVAL; 2246 if (get_user(new, (int __user *)newval)) 2247 return -EFAULT; 2248 *(int *)(table->data) = new*HZ; 2249 } 2250 return 1; 2251 } 2252 2253 /* Strategy function to convert jiffies to seconds */ 2254 int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, 2255 void __user *oldval, size_t __user *oldlenp, 2256 void __user *newval, size_t newlen) 2257 { 2258 if (oldval && oldlenp) { 2259 size_t olen; 2260 2261 if (get_user(olen, oldlenp)) 2262 return -EFAULT; 2263 if (olen) { 2264 int val; 2265 2266 if (olen < sizeof(int)) 2267 return -EINVAL; 2268 2269 val = jiffies_to_msecs(*(int *)(table->data)); 2270 if (put_user(val, (int __user *)oldval)) 2271 return -EFAULT; 2272 if (put_user(sizeof(int), oldlenp)) 2273 return -EFAULT; 2274 } 2275 } 2276 if (newval && newlen) { 2277 int new; 2278 if (newlen != sizeof(int)) 2279 return -EINVAL; 2280 if (get_user(new, (int __user *)newval)) 2281 return -EFAULT; 2282 *(int *)(table->data) = msecs_to_jiffies(new); 2283 } 2284 return 1; 2285 } 2286 2287 2288 2289 #else /* CONFIG_SYSCTL_SYSCALL */ 2290 2291 2292 asmlinkage long sys_sysctl(struct __sysctl_args __user *args) 2293 { 2294 static int msg_count; 2295 struct __sysctl_args tmp; 2296 int name[CTL_MAXNAME]; 2297 int i; 2298 2299 /* Read in the sysctl name for better debug message logging */ 2300 if (copy_from_user(&tmp, args, sizeof(tmp))) 2301 return -EFAULT; 2302 if (tmp.nlen <= 0 || tmp.nlen >= CTL_MAXNAME) 2303 return -ENOTDIR; 2304 for (i = 0; i < tmp.nlen; i++) 2305 if (get_user(name[i], tmp.name + i)) 2306 return -EFAULT; 2307 2308 /* Ignore accesses to kernel.version */ 2309 if ((tmp.nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION)) 2310 goto out; 2311 2312 if (msg_count < 5) { 2313 msg_count++; 2314 printk(KERN_INFO 2315 "warning: process `%s' used the removed sysctl " 2316 "system call with ", current->comm); 2317 for (i = 0; i < tmp.nlen; i++) 2318 printk("%d.", name[i]); 2319 printk("\n"); 2320 } 2321 out: 2322 return -ENOSYS; 2323 } 2324 2325 int sysctl_string(ctl_table *table, int __user *name, int nlen, 2326 void __user *oldval, size_t __user *oldlenp, 2327 void __user *newval, size_t newlen) 2328 { 2329 return -ENOSYS; 2330 } 2331 2332 int sysctl_intvec(ctl_table *table, int __user *name, int nlen, 2333 void __user *oldval, size_t __user *oldlenp, 2334 void __user *newval, size_t newlen) 2335 { 2336 return -ENOSYS; 2337 } 2338 2339 int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, 2340 void __user *oldval, size_t __user *oldlenp, 2341 void __user *newval, size_t newlen) 2342 { 2343 return -ENOSYS; 2344 } 2345 2346 int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, 2347 void __user *oldval, size_t __user *oldlenp, 2348 void __user *newval, size_t newlen) 2349 { 2350 return -ENOSYS; 2351 } 2352 2353 #endif /* CONFIG_SYSCTL_SYSCALL */ 2354 2355 /* 2356 * No sense putting this after each symbol definition, twice, 2357 * exception granted :-) 2358 */ 2359 EXPORT_SYMBOL(proc_dointvec); 2360 EXPORT_SYMBOL(proc_dointvec_jiffies); 2361 EXPORT_SYMBOL(proc_dointvec_minmax); 2362 EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); 2363 EXPORT_SYMBOL(proc_dointvec_ms_jiffies); 2364 EXPORT_SYMBOL(proc_dostring); 2365 EXPORT_SYMBOL(proc_doulongvec_minmax); 2366 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); 2367 EXPORT_SYMBOL(register_sysctl_table); 2368 EXPORT_SYMBOL(sysctl_intvec); 2369 EXPORT_SYMBOL(sysctl_jiffies); 2370 EXPORT_SYMBOL(sysctl_ms_jiffies); 2371 EXPORT_SYMBOL(sysctl_string); 2372 EXPORT_SYMBOL(unregister_sysctl_table); 2373