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