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