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 kfree(context); 1004 if (error != -ENOTDIR) 1005 return error; 1006 tmp = tmp->next; 1007 } while (tmp != &root_table_header.ctl_entry); 1008 return -ENOTDIR; 1009 } 1010 1011 asmlinkage long sys_sysctl(struct __sysctl_args __user *args) 1012 { 1013 struct __sysctl_args tmp; 1014 int error; 1015 1016 if (copy_from_user(&tmp, args, sizeof(tmp))) 1017 return -EFAULT; 1018 1019 lock_kernel(); 1020 error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp, 1021 tmp.newval, tmp.newlen); 1022 unlock_kernel(); 1023 return error; 1024 } 1025 1026 /* 1027 * ctl_perm does NOT grant the superuser all rights automatically, because 1028 * some sysctl variables are readonly even to root. 1029 */ 1030 1031 static int test_perm(int mode, int op) 1032 { 1033 if (!current->euid) 1034 mode >>= 6; 1035 else if (in_egroup_p(0)) 1036 mode >>= 3; 1037 if ((mode & op & 0007) == op) 1038 return 0; 1039 return -EACCES; 1040 } 1041 1042 static inline int ctl_perm(ctl_table *table, int op) 1043 { 1044 int error; 1045 error = security_sysctl(table, op); 1046 if (error) 1047 return error; 1048 return test_perm(table->mode, op); 1049 } 1050 1051 static int parse_table(int __user *name, int nlen, 1052 void __user *oldval, size_t __user *oldlenp, 1053 void __user *newval, size_t newlen, 1054 ctl_table *table, void **context) 1055 { 1056 int n; 1057 repeat: 1058 if (!nlen) 1059 return -ENOTDIR; 1060 if (get_user(n, name)) 1061 return -EFAULT; 1062 for ( ; table->ctl_name; table++) { 1063 if (n == table->ctl_name || table->ctl_name == CTL_ANY) { 1064 int error; 1065 if (table->child) { 1066 if (ctl_perm(table, 001)) 1067 return -EPERM; 1068 if (table->strategy) { 1069 error = table->strategy( 1070 table, name, nlen, 1071 oldval, oldlenp, 1072 newval, newlen, context); 1073 if (error) 1074 return error; 1075 } 1076 name++; 1077 nlen--; 1078 table = table->child; 1079 goto repeat; 1080 } 1081 error = do_sysctl_strategy(table, name, nlen, 1082 oldval, oldlenp, 1083 newval, newlen, context); 1084 return error; 1085 } 1086 } 1087 return -ENOTDIR; 1088 } 1089 1090 /* Perform the actual read/write of a sysctl table entry. */ 1091 int do_sysctl_strategy (ctl_table *table, 1092 int __user *name, int nlen, 1093 void __user *oldval, size_t __user *oldlenp, 1094 void __user *newval, size_t newlen, void **context) 1095 { 1096 int op = 0, rc; 1097 size_t len; 1098 1099 if (oldval) 1100 op |= 004; 1101 if (newval) 1102 op |= 002; 1103 if (ctl_perm(table, op)) 1104 return -EPERM; 1105 1106 if (table->strategy) { 1107 rc = table->strategy(table, name, nlen, oldval, oldlenp, 1108 newval, newlen, context); 1109 if (rc < 0) 1110 return rc; 1111 if (rc > 0) 1112 return 0; 1113 } 1114 1115 /* If there is no strategy routine, or if the strategy returns 1116 * zero, proceed with automatic r/w */ 1117 if (table->data && table->maxlen) { 1118 if (oldval && oldlenp) { 1119 if (get_user(len, oldlenp)) 1120 return -EFAULT; 1121 if (len) { 1122 if (len > table->maxlen) 1123 len = table->maxlen; 1124 if(copy_to_user(oldval, table->data, len)) 1125 return -EFAULT; 1126 if(put_user(len, oldlenp)) 1127 return -EFAULT; 1128 } 1129 } 1130 if (newval && newlen) { 1131 len = newlen; 1132 if (len > table->maxlen) 1133 len = table->maxlen; 1134 if(copy_from_user(table->data, newval, len)) 1135 return -EFAULT; 1136 } 1137 } 1138 return 0; 1139 } 1140 1141 /** 1142 * register_sysctl_table - register a sysctl hierarchy 1143 * @table: the top-level table structure 1144 * @insert_at_head: whether the entry should be inserted in front or at the end 1145 * 1146 * Register a sysctl table hierarchy. @table should be a filled in ctl_table 1147 * array. An entry with a ctl_name of 0 terminates the table. 1148 * 1149 * The members of the &ctl_table structure are used as follows: 1150 * 1151 * ctl_name - This is the numeric sysctl value used by sysctl(2). The number 1152 * must be unique within that level of sysctl 1153 * 1154 * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not 1155 * enter a sysctl file 1156 * 1157 * data - a pointer to data for use by proc_handler 1158 * 1159 * maxlen - the maximum size in bytes of the data 1160 * 1161 * mode - the file permissions for the /proc/sys file, and for sysctl(2) 1162 * 1163 * child - a pointer to the child sysctl table if this entry is a directory, or 1164 * %NULL. 1165 * 1166 * proc_handler - the text handler routine (described below) 1167 * 1168 * strategy - the strategy routine (described below) 1169 * 1170 * de - for internal use by the sysctl routines 1171 * 1172 * extra1, extra2 - extra pointers usable by the proc handler routines 1173 * 1174 * Leaf nodes in the sysctl tree will be represented by a single file 1175 * under /proc; non-leaf nodes will be represented by directories. 1176 * 1177 * sysctl(2) can automatically manage read and write requests through 1178 * the sysctl table. The data and maxlen fields of the ctl_table 1179 * struct enable minimal validation of the values being written to be 1180 * performed, and the mode field allows minimal authentication. 1181 * 1182 * More sophisticated management can be enabled by the provision of a 1183 * strategy routine with the table entry. This will be called before 1184 * any automatic read or write of the data is performed. 1185 * 1186 * The strategy routine may return 1187 * 1188 * < 0 - Error occurred (error is passed to user process) 1189 * 1190 * 0 - OK - proceed with automatic read or write. 1191 * 1192 * > 0 - OK - read or write has been done by the strategy routine, so 1193 * return immediately. 1194 * 1195 * There must be a proc_handler routine for any terminal nodes 1196 * mirrored under /proc/sys (non-terminals are handled by a built-in 1197 * directory handler). Several default handlers are available to 1198 * cover common cases - 1199 * 1200 * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(), 1201 * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(), 1202 * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax() 1203 * 1204 * It is the handler's job to read the input buffer from user memory 1205 * and process it. The handler should return 0 on success. 1206 * 1207 * This routine returns %NULL on a failure to register, and a pointer 1208 * to the table header on success. 1209 */ 1210 struct ctl_table_header *register_sysctl_table(ctl_table * table, 1211 int insert_at_head) 1212 { 1213 struct ctl_table_header *tmp; 1214 tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL); 1215 if (!tmp) 1216 return NULL; 1217 tmp->ctl_table = table; 1218 INIT_LIST_HEAD(&tmp->ctl_entry); 1219 if (insert_at_head) 1220 list_add(&tmp->ctl_entry, &root_table_header.ctl_entry); 1221 else 1222 list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); 1223 #ifdef CONFIG_PROC_FS 1224 register_proc_table(table, proc_sys_root); 1225 #endif 1226 return tmp; 1227 } 1228 1229 /** 1230 * unregister_sysctl_table - unregister a sysctl table hierarchy 1231 * @header: the header returned from register_sysctl_table 1232 * 1233 * Unregisters the sysctl table and all children. proc entries may not 1234 * actually be removed until they are no longer used by anyone. 1235 */ 1236 void unregister_sysctl_table(struct ctl_table_header * header) 1237 { 1238 list_del(&header->ctl_entry); 1239 #ifdef CONFIG_PROC_FS 1240 unregister_proc_table(header->ctl_table, proc_sys_root); 1241 #endif 1242 kfree(header); 1243 } 1244 1245 /* 1246 * /proc/sys support 1247 */ 1248 1249 #ifdef CONFIG_PROC_FS 1250 1251 /* Scan the sysctl entries in table and add them all into /proc */ 1252 static void register_proc_table(ctl_table * table, struct proc_dir_entry *root) 1253 { 1254 struct proc_dir_entry *de; 1255 int len; 1256 mode_t mode; 1257 1258 for (; table->ctl_name; table++) { 1259 /* Can't do anything without a proc name. */ 1260 if (!table->procname) 1261 continue; 1262 /* Maybe we can't do anything with it... */ 1263 if (!table->proc_handler && !table->child) { 1264 printk(KERN_WARNING "SYSCTL: Can't register %s\n", 1265 table->procname); 1266 continue; 1267 } 1268 1269 len = strlen(table->procname); 1270 mode = table->mode; 1271 1272 de = NULL; 1273 if (table->proc_handler) 1274 mode |= S_IFREG; 1275 else { 1276 mode |= S_IFDIR; 1277 for (de = root->subdir; de; de = de->next) { 1278 if (proc_match(len, table->procname, de)) 1279 break; 1280 } 1281 /* If the subdir exists already, de is non-NULL */ 1282 } 1283 1284 if (!de) { 1285 de = create_proc_entry(table->procname, mode, root); 1286 if (!de) 1287 continue; 1288 de->data = (void *) table; 1289 if (table->proc_handler) 1290 de->proc_fops = &proc_sys_file_operations; 1291 } 1292 table->de = de; 1293 if (de->mode & S_IFDIR) 1294 register_proc_table(table->child, de); 1295 } 1296 } 1297 1298 /* 1299 * Unregister a /proc sysctl table and any subdirectories. 1300 */ 1301 static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root) 1302 { 1303 struct proc_dir_entry *de; 1304 for (; table->ctl_name; table++) { 1305 if (!(de = table->de)) 1306 continue; 1307 if (de->mode & S_IFDIR) { 1308 if (!table->child) { 1309 printk (KERN_ALERT "Help - malformed sysctl tree on free\n"); 1310 continue; 1311 } 1312 unregister_proc_table(table->child, de); 1313 1314 /* Don't unregister directories which still have entries.. */ 1315 if (de->subdir) 1316 continue; 1317 } 1318 1319 /* Don't unregister proc entries that are still being used.. */ 1320 if (atomic_read(&de->count)) 1321 continue; 1322 1323 table->de = NULL; 1324 remove_proc_entry(table->procname, root); 1325 } 1326 } 1327 1328 static ssize_t do_rw_proc(int write, struct file * file, char __user * buf, 1329 size_t count, loff_t *ppos) 1330 { 1331 int op; 1332 struct proc_dir_entry *de; 1333 struct ctl_table *table; 1334 size_t res; 1335 ssize_t error; 1336 1337 de = PDE(file->f_dentry->d_inode); 1338 if (!de || !de->data) 1339 return -ENOTDIR; 1340 table = (struct ctl_table *) de->data; 1341 if (!table || !table->proc_handler) 1342 return -ENOTDIR; 1343 op = (write ? 002 : 004); 1344 if (ctl_perm(table, op)) 1345 return -EPERM; 1346 1347 res = count; 1348 1349 error = (*table->proc_handler) (table, write, file, buf, &res, ppos); 1350 if (error) 1351 return error; 1352 return res; 1353 } 1354 1355 static int proc_opensys(struct inode *inode, struct file *file) 1356 { 1357 if (file->f_mode & FMODE_WRITE) { 1358 /* 1359 * sysctl entries that are not writable, 1360 * are _NOT_ writable, capabilities or not. 1361 */ 1362 if (!(inode->i_mode & S_IWUSR)) 1363 return -EPERM; 1364 } 1365 1366 return 0; 1367 } 1368 1369 static ssize_t proc_readsys(struct file * file, char __user * buf, 1370 size_t count, loff_t *ppos) 1371 { 1372 return do_rw_proc(0, file, buf, count, ppos); 1373 } 1374 1375 static ssize_t proc_writesys(struct file * file, const char __user * buf, 1376 size_t count, loff_t *ppos) 1377 { 1378 return do_rw_proc(1, file, (char __user *) buf, count, ppos); 1379 } 1380 1381 /** 1382 * proc_dostring - read a string sysctl 1383 * @table: the sysctl table 1384 * @write: %TRUE if this is a write to the sysctl file 1385 * @filp: the file structure 1386 * @buffer: the user buffer 1387 * @lenp: the size of the user buffer 1388 * @ppos: file position 1389 * 1390 * Reads/writes a string from/to the user buffer. If the kernel 1391 * buffer provided is not large enough to hold the string, the 1392 * string is truncated. The copied string is %NULL-terminated. 1393 * If the string is being read by the user process, it is copied 1394 * and a newline '\n' is added. It is truncated if the buffer is 1395 * not large enough. 1396 * 1397 * Returns 0 on success. 1398 */ 1399 int proc_dostring(ctl_table *table, int write, struct file *filp, 1400 void __user *buffer, size_t *lenp, loff_t *ppos) 1401 { 1402 size_t len; 1403 char __user *p; 1404 char c; 1405 1406 if (!table->data || !table->maxlen || !*lenp || 1407 (*ppos && !write)) { 1408 *lenp = 0; 1409 return 0; 1410 } 1411 1412 if (write) { 1413 len = 0; 1414 p = buffer; 1415 while (len < *lenp) { 1416 if (get_user(c, p++)) 1417 return -EFAULT; 1418 if (c == 0 || c == '\n') 1419 break; 1420 len++; 1421 } 1422 if (len >= table->maxlen) 1423 len = table->maxlen-1; 1424 if(copy_from_user(table->data, buffer, len)) 1425 return -EFAULT; 1426 ((char *) table->data)[len] = 0; 1427 *ppos += *lenp; 1428 } else { 1429 len = strlen(table->data); 1430 if (len > table->maxlen) 1431 len = table->maxlen; 1432 if (len > *lenp) 1433 len = *lenp; 1434 if (len) 1435 if(copy_to_user(buffer, table->data, len)) 1436 return -EFAULT; 1437 if (len < *lenp) { 1438 if(put_user('\n', ((char __user *) buffer) + len)) 1439 return -EFAULT; 1440 len++; 1441 } 1442 *lenp = len; 1443 *ppos += len; 1444 } 1445 return 0; 1446 } 1447 1448 /* 1449 * Special case of dostring for the UTS structure. This has locks 1450 * to observe. Should this be in kernel/sys.c ???? 1451 */ 1452 1453 static int proc_doutsstring(ctl_table *table, int write, struct file *filp, 1454 void __user *buffer, size_t *lenp, loff_t *ppos) 1455 { 1456 int r; 1457 1458 if (!write) { 1459 down_read(&uts_sem); 1460 r=proc_dostring(table,0,filp,buffer,lenp, ppos); 1461 up_read(&uts_sem); 1462 } else { 1463 down_write(&uts_sem); 1464 r=proc_dostring(table,1,filp,buffer,lenp, ppos); 1465 up_write(&uts_sem); 1466 } 1467 return r; 1468 } 1469 1470 static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, 1471 int *valp, 1472 int write, void *data) 1473 { 1474 if (write) { 1475 *valp = *negp ? -*lvalp : *lvalp; 1476 } else { 1477 int val = *valp; 1478 if (val < 0) { 1479 *negp = -1; 1480 *lvalp = (unsigned long)-val; 1481 } else { 1482 *negp = 0; 1483 *lvalp = (unsigned long)val; 1484 } 1485 } 1486 return 0; 1487 } 1488 1489 static int do_proc_dointvec(ctl_table *table, int write, struct file *filp, 1490 void __user *buffer, size_t *lenp, loff_t *ppos, 1491 int (*conv)(int *negp, unsigned long *lvalp, int *valp, 1492 int write, void *data), 1493 void *data) 1494 { 1495 #define TMPBUFLEN 21 1496 int *i, vleft, first=1, neg, val; 1497 unsigned long lval; 1498 size_t left, len; 1499 1500 char buf[TMPBUFLEN], *p; 1501 char __user *s = buffer; 1502 1503 if (!table->data || !table->maxlen || !*lenp || 1504 (*ppos && !write)) { 1505 *lenp = 0; 1506 return 0; 1507 } 1508 1509 i = (int *) table->data; 1510 vleft = table->maxlen / sizeof(*i); 1511 left = *lenp; 1512 1513 if (!conv) 1514 conv = do_proc_dointvec_conv; 1515 1516 for (; left && vleft--; i++, first=0) { 1517 if (write) { 1518 while (left) { 1519 char c; 1520 if (get_user(c, s)) 1521 return -EFAULT; 1522 if (!isspace(c)) 1523 break; 1524 left--; 1525 s++; 1526 } 1527 if (!left) 1528 break; 1529 neg = 0; 1530 len = left; 1531 if (len > sizeof(buf) - 1) 1532 len = sizeof(buf) - 1; 1533 if (copy_from_user(buf, s, len)) 1534 return -EFAULT; 1535 buf[len] = 0; 1536 p = buf; 1537 if (*p == '-' && left > 1) { 1538 neg = 1; 1539 left--, p++; 1540 } 1541 if (*p < '0' || *p > '9') 1542 break; 1543 1544 lval = simple_strtoul(p, &p, 0); 1545 1546 len = p-buf; 1547 if ((len < left) && *p && !isspace(*p)) 1548 break; 1549 if (neg) 1550 val = -val; 1551 s += len; 1552 left -= len; 1553 1554 if (conv(&neg, &lval, i, 1, data)) 1555 break; 1556 } else { 1557 p = buf; 1558 if (!first) 1559 *p++ = '\t'; 1560 1561 if (conv(&neg, &lval, i, 0, data)) 1562 break; 1563 1564 sprintf(p, "%s%lu", neg ? "-" : "", lval); 1565 len = strlen(buf); 1566 if (len > left) 1567 len = left; 1568 if(copy_to_user(s, buf, len)) 1569 return -EFAULT; 1570 left -= len; 1571 s += len; 1572 } 1573 } 1574 1575 if (!write && !first && left) { 1576 if(put_user('\n', s)) 1577 return -EFAULT; 1578 left--, s++; 1579 } 1580 if (write) { 1581 while (left) { 1582 char c; 1583 if (get_user(c, s++)) 1584 return -EFAULT; 1585 if (!isspace(c)) 1586 break; 1587 left--; 1588 } 1589 } 1590 if (write && first) 1591 return -EINVAL; 1592 *lenp -= left; 1593 *ppos += *lenp; 1594 return 0; 1595 #undef TMPBUFLEN 1596 } 1597 1598 /** 1599 * proc_dointvec - read a vector of integers 1600 * @table: the sysctl table 1601 * @write: %TRUE if this is a write to the sysctl file 1602 * @filp: the file structure 1603 * @buffer: the user buffer 1604 * @lenp: the size of the user buffer 1605 * @ppos: file position 1606 * 1607 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 1608 * values from/to the user buffer, treated as an ASCII string. 1609 * 1610 * Returns 0 on success. 1611 */ 1612 int proc_dointvec(ctl_table *table, int write, struct file *filp, 1613 void __user *buffer, size_t *lenp, loff_t *ppos) 1614 { 1615 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 1616 NULL,NULL); 1617 } 1618 1619 #define OP_SET 0 1620 #define OP_AND 1 1621 #define OP_OR 2 1622 #define OP_MAX 3 1623 #define OP_MIN 4 1624 1625 static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, 1626 int *valp, 1627 int write, void *data) 1628 { 1629 int op = *(int *)data; 1630 if (write) { 1631 int val = *negp ? -*lvalp : *lvalp; 1632 switch(op) { 1633 case OP_SET: *valp = val; break; 1634 case OP_AND: *valp &= val; break; 1635 case OP_OR: *valp |= val; break; 1636 case OP_MAX: if(*valp < val) 1637 *valp = val; 1638 break; 1639 case OP_MIN: if(*valp > val) 1640 *valp = val; 1641 break; 1642 } 1643 } else { 1644 int val = *valp; 1645 if (val < 0) { 1646 *negp = -1; 1647 *lvalp = (unsigned long)-val; 1648 } else { 1649 *negp = 0; 1650 *lvalp = (unsigned long)val; 1651 } 1652 } 1653 return 0; 1654 } 1655 1656 /* 1657 * init may raise the set. 1658 */ 1659 1660 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, 1661 void __user *buffer, size_t *lenp, loff_t *ppos) 1662 { 1663 int op; 1664 1665 if (!capable(CAP_SYS_MODULE)) { 1666 return -EPERM; 1667 } 1668 1669 op = (current->pid == 1) ? OP_SET : OP_AND; 1670 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 1671 do_proc_dointvec_bset_conv,&op); 1672 } 1673 1674 struct do_proc_dointvec_minmax_conv_param { 1675 int *min; 1676 int *max; 1677 }; 1678 1679 static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp, 1680 int *valp, 1681 int write, void *data) 1682 { 1683 struct do_proc_dointvec_minmax_conv_param *param = data; 1684 if (write) { 1685 int val = *negp ? -*lvalp : *lvalp; 1686 if ((param->min && *param->min > val) || 1687 (param->max && *param->max < val)) 1688 return -EINVAL; 1689 *valp = val; 1690 } else { 1691 int val = *valp; 1692 if (val < 0) { 1693 *negp = -1; 1694 *lvalp = (unsigned long)-val; 1695 } else { 1696 *negp = 0; 1697 *lvalp = (unsigned long)val; 1698 } 1699 } 1700 return 0; 1701 } 1702 1703 /** 1704 * proc_dointvec_minmax - read a vector of integers with min/max values 1705 * @table: the sysctl table 1706 * @write: %TRUE if this is a write to the sysctl file 1707 * @filp: the file structure 1708 * @buffer: the user buffer 1709 * @lenp: the size of the user buffer 1710 * @ppos: file position 1711 * 1712 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 1713 * values from/to the user buffer, treated as an ASCII string. 1714 * 1715 * This routine will ensure the values are within the range specified by 1716 * table->extra1 (min) and table->extra2 (max). 1717 * 1718 * Returns 0 on success. 1719 */ 1720 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, 1721 void __user *buffer, size_t *lenp, loff_t *ppos) 1722 { 1723 struct do_proc_dointvec_minmax_conv_param param = { 1724 .min = (int *) table->extra1, 1725 .max = (int *) table->extra2, 1726 }; 1727 return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, 1728 do_proc_dointvec_minmax_conv, ¶m); 1729 } 1730 1731 static int do_proc_doulongvec_minmax(ctl_table *table, int write, 1732 struct file *filp, 1733 void __user *buffer, 1734 size_t *lenp, loff_t *ppos, 1735 unsigned long convmul, 1736 unsigned long convdiv) 1737 { 1738 #define TMPBUFLEN 21 1739 unsigned long *i, *min, *max, val; 1740 int vleft, first=1, neg; 1741 size_t len, left; 1742 char buf[TMPBUFLEN], *p; 1743 char __user *s = buffer; 1744 1745 if (!table->data || !table->maxlen || !*lenp || 1746 (*ppos && !write)) { 1747 *lenp = 0; 1748 return 0; 1749 } 1750 1751 i = (unsigned long *) table->data; 1752 min = (unsigned long *) table->extra1; 1753 max = (unsigned long *) table->extra2; 1754 vleft = table->maxlen / sizeof(unsigned long); 1755 left = *lenp; 1756 1757 for (; left && vleft--; i++, min++, max++, first=0) { 1758 if (write) { 1759 while (left) { 1760 char c; 1761 if (get_user(c, s)) 1762 return -EFAULT; 1763 if (!isspace(c)) 1764 break; 1765 left--; 1766 s++; 1767 } 1768 if (!left) 1769 break; 1770 neg = 0; 1771 len = left; 1772 if (len > TMPBUFLEN-1) 1773 len = TMPBUFLEN-1; 1774 if (copy_from_user(buf, s, len)) 1775 return -EFAULT; 1776 buf[len] = 0; 1777 p = buf; 1778 if (*p == '-' && left > 1) { 1779 neg = 1; 1780 left--, p++; 1781 } 1782 if (*p < '0' || *p > '9') 1783 break; 1784 val = simple_strtoul(p, &p, 0) * convmul / convdiv ; 1785 len = p-buf; 1786 if ((len < left) && *p && !isspace(*p)) 1787 break; 1788 if (neg) 1789 val = -val; 1790 s += len; 1791 left -= len; 1792 1793 if(neg) 1794 continue; 1795 if ((min && val < *min) || (max && val > *max)) 1796 continue; 1797 *i = val; 1798 } else { 1799 p = buf; 1800 if (!first) 1801 *p++ = '\t'; 1802 sprintf(p, "%lu", convdiv * (*i) / convmul); 1803 len = strlen(buf); 1804 if (len > left) 1805 len = left; 1806 if(copy_to_user(s, buf, len)) 1807 return -EFAULT; 1808 left -= len; 1809 s += len; 1810 } 1811 } 1812 1813 if (!write && !first && left) { 1814 if(put_user('\n', s)) 1815 return -EFAULT; 1816 left--, s++; 1817 } 1818 if (write) { 1819 while (left) { 1820 char c; 1821 if (get_user(c, s++)) 1822 return -EFAULT; 1823 if (!isspace(c)) 1824 break; 1825 left--; 1826 } 1827 } 1828 if (write && first) 1829 return -EINVAL; 1830 *lenp -= left; 1831 *ppos += *lenp; 1832 return 0; 1833 #undef TMPBUFLEN 1834 } 1835 1836 /** 1837 * proc_doulongvec_minmax - read a vector of long integers with min/max values 1838 * @table: the sysctl table 1839 * @write: %TRUE if this is a write to the sysctl file 1840 * @filp: the file structure 1841 * @buffer: the user buffer 1842 * @lenp: the size of the user buffer 1843 * @ppos: file position 1844 * 1845 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long 1846 * values from/to the user buffer, treated as an ASCII string. 1847 * 1848 * This routine will ensure the values are within the range specified by 1849 * table->extra1 (min) and table->extra2 (max). 1850 * 1851 * Returns 0 on success. 1852 */ 1853 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, 1854 void __user *buffer, size_t *lenp, loff_t *ppos) 1855 { 1856 return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l); 1857 } 1858 1859 /** 1860 * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values 1861 * @table: the sysctl table 1862 * @write: %TRUE if this is a write to the sysctl file 1863 * @filp: the file structure 1864 * @buffer: the user buffer 1865 * @lenp: the size of the user buffer 1866 * @ppos: file position 1867 * 1868 * Reads/writes up to table->maxlen/sizeof(unsigned long) unsigned long 1869 * values from/to the user buffer, treated as an ASCII string. The values 1870 * are treated as milliseconds, and converted to jiffies when they are stored. 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_ms_jiffies_minmax(ctl_table *table, int write, 1878 struct file *filp, 1879 void __user *buffer, 1880 size_t *lenp, loff_t *ppos) 1881 { 1882 return do_proc_doulongvec_minmax(table, write, filp, buffer, 1883 lenp, ppos, HZ, 1000l); 1884 } 1885 1886 1887 static int do_proc_dointvec_jiffies_conv(int *negp, unsigned long *lvalp, 1888 int *valp, 1889 int write, void *data) 1890 { 1891 if (write) { 1892 *valp = *negp ? -(*lvalp*HZ) : (*lvalp*HZ); 1893 } else { 1894 int val = *valp; 1895 unsigned long lval; 1896 if (val < 0) { 1897 *negp = -1; 1898 lval = (unsigned long)-val; 1899 } else { 1900 *negp = 0; 1901 lval = (unsigned long)val; 1902 } 1903 *lvalp = lval / HZ; 1904 } 1905 return 0; 1906 } 1907 1908 static int do_proc_dointvec_userhz_jiffies_conv(int *negp, unsigned long *lvalp, 1909 int *valp, 1910 int write, void *data) 1911 { 1912 if (write) { 1913 *valp = clock_t_to_jiffies(*negp ? -*lvalp : *lvalp); 1914 } else { 1915 int val = *valp; 1916 unsigned long lval; 1917 if (val < 0) { 1918 *negp = -1; 1919 lval = (unsigned long)-val; 1920 } else { 1921 *negp = 0; 1922 lval = (unsigned long)val; 1923 } 1924 *lvalp = jiffies_to_clock_t(lval); 1925 } 1926 return 0; 1927 } 1928 1929 static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp, 1930 int *valp, 1931 int write, void *data) 1932 { 1933 if (write) { 1934 *valp = msecs_to_jiffies(*negp ? -*lvalp : *lvalp); 1935 } else { 1936 int val = *valp; 1937 unsigned long lval; 1938 if (val < 0) { 1939 *negp = -1; 1940 lval = (unsigned long)-val; 1941 } else { 1942 *negp = 0; 1943 lval = (unsigned long)val; 1944 } 1945 *lvalp = jiffies_to_msecs(lval); 1946 } 1947 return 0; 1948 } 1949 1950 /** 1951 * proc_dointvec_jiffies - read a vector of integers as seconds 1952 * @table: the sysctl table 1953 * @write: %TRUE if this is a write to the sysctl file 1954 * @filp: the file structure 1955 * @buffer: the user buffer 1956 * @lenp: the size of the user buffer 1957 * @ppos: file position 1958 * 1959 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 1960 * values from/to the user buffer, treated as an ASCII string. 1961 * The values read are assumed to be in seconds, and are converted into 1962 * jiffies. 1963 * 1964 * Returns 0 on success. 1965 */ 1966 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, 1967 void __user *buffer, size_t *lenp, loff_t *ppos) 1968 { 1969 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 1970 do_proc_dointvec_jiffies_conv,NULL); 1971 } 1972 1973 /** 1974 * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds 1975 * @table: the sysctl table 1976 * @write: %TRUE if this is a write to the sysctl file 1977 * @filp: the file structure 1978 * @buffer: the user buffer 1979 * @lenp: the size of the user buffer 1980 * 1981 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 1982 * values from/to the user buffer, treated as an ASCII string. 1983 * The values read are assumed to be in 1/USER_HZ seconds, and 1984 * are converted into jiffies. 1985 * 1986 * Returns 0 on success. 1987 */ 1988 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, 1989 void __user *buffer, size_t *lenp, loff_t *ppos) 1990 { 1991 return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, 1992 do_proc_dointvec_userhz_jiffies_conv,NULL); 1993 } 1994 1995 /** 1996 * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds 1997 * @table: the sysctl table 1998 * @write: %TRUE if this is a write to the sysctl file 1999 * @filp: the file structure 2000 * @buffer: the user buffer 2001 * @lenp: the size of the user buffer 2002 * @ppos: file position 2003 * @ppos: the current position in the file 2004 * 2005 * Reads/writes up to table->maxlen/sizeof(unsigned int) integer 2006 * values from/to the user buffer, treated as an ASCII string. 2007 * The values read are assumed to be in 1/1000 seconds, and 2008 * are converted into jiffies. 2009 * 2010 * Returns 0 on success. 2011 */ 2012 int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp, 2013 void __user *buffer, size_t *lenp, loff_t *ppos) 2014 { 2015 return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, 2016 do_proc_dointvec_ms_jiffies_conv, NULL); 2017 } 2018 2019 #else /* CONFIG_PROC_FS */ 2020 2021 int proc_dostring(ctl_table *table, int write, struct file *filp, 2022 void __user *buffer, size_t *lenp, loff_t *ppos) 2023 { 2024 return -ENOSYS; 2025 } 2026 2027 static int proc_doutsstring(ctl_table *table, int write, struct file *filp, 2028 void __user *buffer, size_t *lenp, loff_t *ppos) 2029 { 2030 return -ENOSYS; 2031 } 2032 2033 int proc_dointvec(ctl_table *table, int write, struct file *filp, 2034 void __user *buffer, size_t *lenp, loff_t *ppos) 2035 { 2036 return -ENOSYS; 2037 } 2038 2039 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, 2040 void __user *buffer, size_t *lenp, loff_t *ppos) 2041 { 2042 return -ENOSYS; 2043 } 2044 2045 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, 2046 void __user *buffer, size_t *lenp, loff_t *ppos) 2047 { 2048 return -ENOSYS; 2049 } 2050 2051 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, 2052 void __user *buffer, size_t *lenp, loff_t *ppos) 2053 { 2054 return -ENOSYS; 2055 } 2056 2057 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, 2058 void __user *buffer, size_t *lenp, loff_t *ppos) 2059 { 2060 return -ENOSYS; 2061 } 2062 2063 int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp, 2064 void __user *buffer, size_t *lenp, loff_t *ppos) 2065 { 2066 return -ENOSYS; 2067 } 2068 2069 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, 2070 void __user *buffer, size_t *lenp, loff_t *ppos) 2071 { 2072 return -ENOSYS; 2073 } 2074 2075 int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write, 2076 struct file *filp, 2077 void __user *buffer, 2078 size_t *lenp, loff_t *ppos) 2079 { 2080 return -ENOSYS; 2081 } 2082 2083 2084 #endif /* CONFIG_PROC_FS */ 2085 2086 2087 /* 2088 * General sysctl support routines 2089 */ 2090 2091 /* The generic string strategy routine: */ 2092 int sysctl_string(ctl_table *table, int __user *name, int nlen, 2093 void __user *oldval, size_t __user *oldlenp, 2094 void __user *newval, size_t newlen, void **context) 2095 { 2096 size_t l, len; 2097 2098 if (!table->data || !table->maxlen) 2099 return -ENOTDIR; 2100 2101 if (oldval && oldlenp) { 2102 if (get_user(len, oldlenp)) 2103 return -EFAULT; 2104 if (len) { 2105 l = strlen(table->data); 2106 if (len > l) len = l; 2107 if (len >= table->maxlen) 2108 len = table->maxlen; 2109 if(copy_to_user(oldval, table->data, len)) 2110 return -EFAULT; 2111 if(put_user(0, ((char __user *) oldval) + len)) 2112 return -EFAULT; 2113 if(put_user(len, oldlenp)) 2114 return -EFAULT; 2115 } 2116 } 2117 if (newval && newlen) { 2118 len = newlen; 2119 if (len > table->maxlen) 2120 len = table->maxlen; 2121 if(copy_from_user(table->data, newval, len)) 2122 return -EFAULT; 2123 if (len == table->maxlen) 2124 len--; 2125 ((char *) table->data)[len] = 0; 2126 } 2127 return 0; 2128 } 2129 2130 /* 2131 * This function makes sure that all of the integers in the vector 2132 * are between the minimum and maximum values given in the arrays 2133 * table->extra1 and table->extra2, respectively. 2134 */ 2135 int sysctl_intvec(ctl_table *table, int __user *name, int nlen, 2136 void __user *oldval, size_t __user *oldlenp, 2137 void __user *newval, size_t newlen, void **context) 2138 { 2139 2140 if (newval && newlen) { 2141 int __user *vec = (int __user *) newval; 2142 int *min = (int *) table->extra1; 2143 int *max = (int *) table->extra2; 2144 size_t length; 2145 int i; 2146 2147 if (newlen % sizeof(int) != 0) 2148 return -EINVAL; 2149 2150 if (!table->extra1 && !table->extra2) 2151 return 0; 2152 2153 if (newlen > table->maxlen) 2154 newlen = table->maxlen; 2155 length = newlen / sizeof(int); 2156 2157 for (i = 0; i < length; i++) { 2158 int value; 2159 if (get_user(value, vec + i)) 2160 return -EFAULT; 2161 if (min && value < min[i]) 2162 return -EINVAL; 2163 if (max && value > max[i]) 2164 return -EINVAL; 2165 } 2166 } 2167 return 0; 2168 } 2169 2170 /* Strategy function to convert jiffies to seconds */ 2171 int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, 2172 void __user *oldval, size_t __user *oldlenp, 2173 void __user *newval, size_t newlen, void **context) 2174 { 2175 if (oldval) { 2176 size_t olen; 2177 if (oldlenp) { 2178 if (get_user(olen, oldlenp)) 2179 return -EFAULT; 2180 if (olen!=sizeof(int)) 2181 return -EINVAL; 2182 } 2183 if (put_user(*(int *)(table->data)/HZ, (int __user *)oldval) || 2184 (oldlenp && put_user(sizeof(int),oldlenp))) 2185 return -EFAULT; 2186 } 2187 if (newval && newlen) { 2188 int new; 2189 if (newlen != sizeof(int)) 2190 return -EINVAL; 2191 if (get_user(new, (int __user *)newval)) 2192 return -EFAULT; 2193 *(int *)(table->data) = new*HZ; 2194 } 2195 return 1; 2196 } 2197 2198 /* Strategy function to convert jiffies to seconds */ 2199 int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, 2200 void __user *oldval, size_t __user *oldlenp, 2201 void __user *newval, size_t newlen, void **context) 2202 { 2203 if (oldval) { 2204 size_t olen; 2205 if (oldlenp) { 2206 if (get_user(olen, oldlenp)) 2207 return -EFAULT; 2208 if (olen!=sizeof(int)) 2209 return -EINVAL; 2210 } 2211 if (put_user(jiffies_to_msecs(*(int *)(table->data)), (int __user *)oldval) || 2212 (oldlenp && put_user(sizeof(int),oldlenp))) 2213 return -EFAULT; 2214 } 2215 if (newval && newlen) { 2216 int new; 2217 if (newlen != sizeof(int)) 2218 return -EINVAL; 2219 if (get_user(new, (int __user *)newval)) 2220 return -EFAULT; 2221 *(int *)(table->data) = msecs_to_jiffies(new); 2222 } 2223 return 1; 2224 } 2225 2226 #else /* CONFIG_SYSCTL */ 2227 2228 2229 asmlinkage long sys_sysctl(struct __sysctl_args __user *args) 2230 { 2231 return -ENOSYS; 2232 } 2233 2234 int sysctl_string(ctl_table *table, int __user *name, int nlen, 2235 void __user *oldval, size_t __user *oldlenp, 2236 void __user *newval, size_t newlen, void **context) 2237 { 2238 return -ENOSYS; 2239 } 2240 2241 int sysctl_intvec(ctl_table *table, int __user *name, int nlen, 2242 void __user *oldval, size_t __user *oldlenp, 2243 void __user *newval, size_t newlen, void **context) 2244 { 2245 return -ENOSYS; 2246 } 2247 2248 int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, 2249 void __user *oldval, size_t __user *oldlenp, 2250 void __user *newval, size_t newlen, void **context) 2251 { 2252 return -ENOSYS; 2253 } 2254 2255 int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, 2256 void __user *oldval, size_t __user *oldlenp, 2257 void __user *newval, size_t newlen, void **context) 2258 { 2259 return -ENOSYS; 2260 } 2261 2262 int proc_dostring(ctl_table *table, int write, struct file *filp, 2263 void __user *buffer, size_t *lenp, loff_t *ppos) 2264 { 2265 return -ENOSYS; 2266 } 2267 2268 int proc_dointvec(ctl_table *table, int write, struct file *filp, 2269 void __user *buffer, size_t *lenp, loff_t *ppos) 2270 { 2271 return -ENOSYS; 2272 } 2273 2274 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, 2275 void __user *buffer, size_t *lenp, loff_t *ppos) 2276 { 2277 return -ENOSYS; 2278 } 2279 2280 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, 2281 void __user *buffer, size_t *lenp, loff_t *ppos) 2282 { 2283 return -ENOSYS; 2284 } 2285 2286 int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, 2287 void __user *buffer, size_t *lenp, loff_t *ppos) 2288 { 2289 return -ENOSYS; 2290 } 2291 2292 int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, 2293 void __user *buffer, size_t *lenp, loff_t *ppos) 2294 { 2295 return -ENOSYS; 2296 } 2297 2298 int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp, 2299 void __user *buffer, size_t *lenp, loff_t *ppos) 2300 { 2301 return -ENOSYS; 2302 } 2303 2304 int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, 2305 void __user *buffer, size_t *lenp, loff_t *ppos) 2306 { 2307 return -ENOSYS; 2308 } 2309 2310 int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write, 2311 struct file *filp, 2312 void __user *buffer, 2313 size_t *lenp, loff_t *ppos) 2314 { 2315 return -ENOSYS; 2316 } 2317 2318 struct ctl_table_header * register_sysctl_table(ctl_table * table, 2319 int insert_at_head) 2320 { 2321 return NULL; 2322 } 2323 2324 void unregister_sysctl_table(struct ctl_table_header * table) 2325 { 2326 } 2327 2328 #endif /* CONFIG_SYSCTL */ 2329 2330 /* 2331 * No sense putting this after each symbol definition, twice, 2332 * exception granted :-) 2333 */ 2334 EXPORT_SYMBOL(proc_dointvec); 2335 EXPORT_SYMBOL(proc_dointvec_jiffies); 2336 EXPORT_SYMBOL(proc_dointvec_minmax); 2337 EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); 2338 EXPORT_SYMBOL(proc_dointvec_ms_jiffies); 2339 EXPORT_SYMBOL(proc_dostring); 2340 EXPORT_SYMBOL(proc_doulongvec_minmax); 2341 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); 2342 EXPORT_SYMBOL(register_sysctl_table); 2343 EXPORT_SYMBOL(sysctl_intvec); 2344 EXPORT_SYMBOL(sysctl_jiffies); 2345 EXPORT_SYMBOL(sysctl_ms_jiffies); 2346 EXPORT_SYMBOL(sysctl_string); 2347 EXPORT_SYMBOL(unregister_sysctl_table); 2348