1/* 2 * Copyright (c) 2000-2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ 29/*- 30 * Copyright (c) 1982, 1986, 1989, 1993 31 * The Regents of the University of California. All rights reserved. 32 * 33 * This code is derived from software contributed to Berkeley by 34 * Mike Karels at Berkeley Software Design, Inc. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. All advertising materials mentioning features or use of this software 45 * must display the following acknowledgement: 46 * This product includes software developed by the University of 47 * California, Berkeley and its contributors. 48 * 4. Neither the name of the University nor the names of its contributors 49 * may be used to endorse or promote products derived from this software 50 * without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * SUCH DAMAGE. 63 * 64 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94 65 */ 66/* 67 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce 68 * support for mandatory and extensible security protections. This notice 69 * is included in support of clause 2.2 (b) of the Apple Public License, 70 * Version 2.0. 71 */ 72 73/* 74* DEPRECATED sysctl system call code 75 * 76 * Everything in this file is deprecated. Sysctls should be handled 77 * by the code in kern_newsysctl.c. 78 * The remaining "case" sections are supposed to be converted into 79 * SYSCTL_*-style definitions, and as soon as all of them are gone, 80 * this source file is supposed to die. 81 * 82 * DO NOT ADD ANY MORE "case" SECTIONS TO THIS FILE, instead define 83 * your sysctl with SYSCTL_INT, SYSCTL_PROC etc. in your source file. 84 */ 85 86#include <sys/param.h> 87#include <sys/systm.h> 88#include <sys/kernel.h> 89#include <sys/malloc.h> 90#include <sys/proc_internal.h> 91#include <sys/kauth.h> 92#include <sys/file_internal.h> 93#include <sys/vnode_internal.h> 94#include <sys/unistd.h> 95#include <sys/buf.h> 96#include <sys/ioctl.h> 97#include <sys/namei.h> 98#include <sys/tty.h> 99#include <sys/disklabel.h> 100#include <sys/vm.h> 101#include <sys/sysctl.h> 102#include <sys/user.h> 103#include <sys/aio_kern.h> 104#include <sys/reboot.h> 105 106#include <security/audit/audit.h> 107#include <kern/kalloc.h> 108 109#include <mach/machine.h> 110#include <mach/mach_host.h> 111#include <mach/mach_types.h> 112#include <mach/vm_param.h> 113#include <kern/mach_param.h> 114#include <kern/task.h> 115#include <kern/thread.h> 116#include <kern/lock.h> 117#include <kern/processor.h> 118#include <kern/debug.h> 119#include <vm/vm_kern.h> 120#include <vm/vm_map.h> 121#include <mach/host_info.h> 122 123#include <sys/mount_internal.h> 124#include <sys/kdebug.h> 125#include <sys/sysproto.h> 126 127#include <IOKit/IOPlatformExpert.h> 128#include <pexpert/pexpert.h> 129 130#include <machine/machine_routines.h> 131#include <machine/exec.h> 132 133#include <vm/vm_protos.h> 134#include <sys/imgsrc.h> 135 136#if defined(__i386__) || defined(__x86_64__) 137#include <i386/cpuid.h> 138#endif 139 140#if CONFIG_FREEZE 141#include <sys/kern_memorystatus.h> 142#endif 143 144/* 145 * deliberately setting max requests to really high number 146 * so that runaway settings do not cause MALLOC overflows 147 */ 148#define AIO_MAX_REQUESTS (128 * CONFIG_AIO_MAX) 149 150extern sysctlfn net_sysctl; 151extern sysctlfn cpu_sysctl; 152extern int aio_max_requests; 153extern int aio_max_requests_per_process; 154extern int aio_worker_threads; 155extern int lowpri_IO_window_msecs; 156extern int lowpri_IO_delay_msecs; 157extern int nx_enabled; 158extern int speculative_reads_disabled; 159extern int ignore_is_ssd; 160extern unsigned int speculative_prefetch_max; 161extern unsigned int speculative_prefetch_max_iosize; 162extern unsigned int preheat_pages_max; 163extern unsigned int preheat_pages_min; 164extern long numvnodes; 165 166extern unsigned int vm_max_delayed_work_limit; 167extern unsigned int vm_max_batch; 168 169extern unsigned int vm_page_free_min; 170extern unsigned int vm_page_free_target; 171extern unsigned int vm_page_free_reserved; 172extern unsigned int vm_page_speculative_percentage; 173extern unsigned int vm_page_speculative_q_age_ms; 174 175/* 176 * Conditionally allow dtrace to see these functions for debugging purposes. 177 */ 178#ifdef STATIC 179#undef STATIC 180#endif 181#if 0 182#define STATIC 183#else 184#define STATIC static 185#endif 186 187extern boolean_t mach_timer_coalescing_enabled; 188 189STATIC void 190fill_user32_eproc(proc_t, struct user32_eproc *__restrict); 191STATIC void 192fill_user32_externproc(proc_t, struct user32_extern_proc *__restrict); 193STATIC void 194fill_user64_eproc(proc_t, struct user64_eproc *__restrict); 195STATIC void 196fill_user64_proc(proc_t, struct user64_kinfo_proc *__restrict); 197STATIC void 198fill_user64_externproc(proc_t, struct user64_extern_proc *__restrict); 199STATIC void 200fill_user32_proc(proc_t, struct user32_kinfo_proc *__restrict); 201 202extern int 203kdbg_control(int *name, u_int namelen, user_addr_t where, size_t * sizep); 204#if NFSCLIENT 205extern int 206netboot_root(void); 207#endif 208int 209pcsamples_ops(int *name, u_int namelen, user_addr_t where, size_t *sizep, 210 proc_t p); 211__private_extern__ kern_return_t 212reset_vmobjectcache(unsigned int val1, unsigned int val2); 213int 214sysctl_procargs(int *name, u_int namelen, user_addr_t where, 215 size_t *sizep, proc_t cur_proc); 216STATIC int 217sysctl_procargsx(int *name, u_int namelen, user_addr_t where, size_t *sizep, 218 proc_t cur_proc, int argc_yes); 219int 220sysctl_struct(user_addr_t oldp, size_t *oldlenp, user_addr_t newp, 221 size_t newlen, void *sp, int len); 222 223STATIC int sysdoproc_filt_KERN_PROC_PID(proc_t p, void * arg); 224STATIC int sysdoproc_filt_KERN_PROC_PGRP(proc_t p, void * arg); 225STATIC int sysdoproc_filt_KERN_PROC_TTY(proc_t p, void * arg); 226STATIC int sysdoproc_filt_KERN_PROC_UID(proc_t p, void * arg); 227STATIC int sysdoproc_filt_KERN_PROC_RUID(proc_t p, void * arg); 228#if CONFIG_LCTX 229STATIC int sysdoproc_filt_KERN_PROC_LCID(proc_t p, void * arg); 230#endif 231int sysdoproc_callback(proc_t p, void *arg); 232 233 234/* forward declarations for non-static STATIC */ 235STATIC void fill_loadavg64(struct loadavg *la, struct user64_loadavg *la64); 236STATIC void fill_loadavg32(struct loadavg *la, struct user32_loadavg *la32); 237STATIC int sysctl_handle_kern_threadname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 238STATIC int sysctl_sched_stats(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 239STATIC int sysctl_sched_stats_enable(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 240STATIC int sysctl_kdebug_ops SYSCTL_HANDLER_ARGS; 241STATIC int sysctl_dotranslate SYSCTL_HANDLER_ARGS; 242STATIC int sysctl_doaffinity SYSCTL_HANDLER_ARGS; 243#if COUNT_SYSCALLS 244STATIC int sysctl_docountsyscalls SYSCTL_HANDLER_ARGS; 245#endif /* COUNT_SYSCALLS */ 246#if !CONFIG_EMBEDDED 247STATIC int sysctl_doprocargs SYSCTL_HANDLER_ARGS; 248#endif /* !CONFIG_EMBEDDED */ 249STATIC int sysctl_doprocargs2 SYSCTL_HANDLER_ARGS; 250STATIC int sysctl_prochandle SYSCTL_HANDLER_ARGS; 251#if DEBUG 252STATIC int sysctl_dodebug SYSCTL_HANDLER_ARGS; 253#endif 254STATIC int sysctl_aiomax(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 255STATIC int sysctl_aioprocmax(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 256STATIC int sysctl_aiothreads(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 257STATIC int sysctl_maxproc(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 258STATIC int sysctl_osversion(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 259STATIC int sysctl_sysctl_bootargs(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 260STATIC int sysctl_maxvnodes(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 261STATIC int sysctl_securelvl(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 262STATIC int sysctl_domainname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 263STATIC int sysctl_hostname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 264STATIC int sysctl_procname(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 265STATIC int sysctl_boottime(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 266STATIC int sysctl_symfile(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 267#if NFSCLIENT 268STATIC int sysctl_netboot(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 269#endif 270#ifdef CONFIG_IMGSRC_ACCESS 271STATIC int sysctl_imgsrcdev(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 272#endif 273STATIC int sysctl_usrstack(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 274STATIC int sysctl_usrstack64(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 275STATIC int sysctl_coredump(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 276STATIC int sysctl_suid_coredump(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 277STATIC int sysctl_delayterm(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 278STATIC int sysctl_rage_vnode(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 279STATIC int sysctl_kern_check_openevt(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 280STATIC int sysctl_nx(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 281STATIC int sysctl_loadavg(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 282STATIC int sysctl_vm_toggle_address_reuse(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 283STATIC int sysctl_swapusage(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 284#if defined(__i386__) || defined(__x86_64__) 285STATIC int sysctl_sysctl_exec_affinity(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 286#endif 287STATIC int fetch_process_cputype( proc_t cur_proc, int *name, u_int namelen, cpu_type_t *cputype); 288STATIC int sysctl_sysctl_native(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 289STATIC int sysctl_sysctl_cputype(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 290STATIC int sysctl_safeboot(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 291STATIC int sysctl_singleuser(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 292STATIC int sysctl_slide(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req); 293 294 295extern void IORegistrySetOSBuildVersion(char * build_version); 296 297STATIC void 298fill_loadavg64(struct loadavg *la, struct user64_loadavg *la64) 299{ 300 la64->ldavg[0] = la->ldavg[0]; 301 la64->ldavg[1] = la->ldavg[1]; 302 la64->ldavg[2] = la->ldavg[2]; 303 la64->fscale = (user64_long_t)la->fscale; 304} 305 306STATIC void 307fill_loadavg32(struct loadavg *la, struct user32_loadavg *la32) 308{ 309 la32->ldavg[0] = la->ldavg[0]; 310 la32->ldavg[1] = la->ldavg[1]; 311 la32->ldavg[2] = la->ldavg[2]; 312 la32->fscale = (user32_long_t)la->fscale; 313} 314 315/* 316 * sysctl_mem_hold 317 * 318 * Description: Wire down the callers address map on behalf of sysctl's 319 * that perform their own copy operations while holding 320 * locks e.g. in the paging path, which could lead to a 321 * deadlock, or while holding a spinlock. 322 * 323 * Parameters: addr User buffer address 324 * len User buffer length 325 * 326 * Returns: 0 Success 327 * vslock:ENOMEM Insufficient physical pages to wire 328 * vslock:EACCES Bad protection mode 329 * vslock:EINVAL Invalid parameters 330 * 331 * Notes: This code is invoked for the first OID element where the 332 * CTLFLAG_LOCKED is not specified for a given OID node 333 * element durng OID traversal, and is held for all 334 * subsequent node traversals, and only released after the 335 * leaf node handler invocation is complete. 336 * 337 * Legacy: For legacy scyctl's provided by third party code which 338 * expect funnel protection for calls into their code, this 339 * routine will also take the funnel, which will also only 340 * be released after the leaf node handler is complete. 341 * 342 * This is to support legacy 32 bit BSD KEXTs and legacy 32 343 * bit single threaded filesystem KEXTs and similar code 344 * which relies on funnel protection, e.g. for things like 345 * FSID based sysctl's. 346 * 347 * NEW CODE SHOULD NOT RELY ON THIS BEHAVIOUR! IT WILL BE 348 * REMOVED IN A FUTURE RELASE OF Mac OS X! 349 * 350 * Bugs: This routine does nothing with the new_addr and new_len 351 * at present, but it should, since read from the user space 352 * process adddress space which could potentially trigger 353 * paging may also be occurring deep down. This is due to 354 * a current limitation of the vslock() routine, which will 355 * always request a wired mapping be read/write, due to not 356 * taking an access mode parameter. Note that this could 357 * also cause problems for output on architectures where 358 * write access does not require read acccess if the current 359 * mapping lacks read access. 360 * 361 * XXX: To be moved to kern_newsysctl.c to avoid __private_extern__ 362 */ 363int sysctl_mem_lock(user_addr_t old_addr, user_size_t old_len, user_addr_t new_addr, user_size_t new_len); 364int 365sysctl_mem_lock(__unused user_addr_t old_addr, __unused user_size_t old_len, __unused user_addr_t new_addr, __unused user_size_t new_len) 366{ 367 return 0; 368} 369 370/* 371 * Locking and stats 372 */ 373 374/* sysctl() syscall */ 375int 376__sysctl(proc_t p, struct __sysctl_args *uap, __unused int32_t *retval) 377{ 378 boolean_t funnel_state = FALSE; /* not held if unknown */ 379 int error; 380 size_t savelen = 0, oldlen = 0, newlen; 381 int name[CTL_MAXNAME]; 382 int error1; 383 boolean_t vslock_taken = FALSE; 384 boolean_t funnel_taken = FALSE; 385#if CONFIG_MACF 386 kauth_cred_t my_cred; 387#endif 388 389 /* 390 * all top-level sysctl names are non-terminal 391 */ 392 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 393 return (EINVAL); 394 error = copyin(uap->name, &name[0], uap->namelen * sizeof(int)); 395 if (error) 396 return (error); 397 398 AUDIT_ARG(ctlname, name, uap->namelen); 399 400 if (proc_is64bit(p)) { 401 /* uap->newlen is a size_t value which grows to 64 bits 402 * when coming from a 64-bit process. since it's doubtful we'll 403 * have a sysctl newp buffer greater than 4GB we shrink it to size_t 404 */ 405 newlen = CAST_DOWN(size_t, uap->newlen); 406 } 407 else { 408 newlen = uap->newlen; 409 } 410 411/* 412 * XXX TODO: push down rights check for CTL_HW OIDs; most duplicate 413 * XXX it anyway, which is a performance sink, and requires use 414 * XXX of SUID root programs (see <rdar://3915692>). 415 * 416 * Note: Opt out of non-leaf node enforcement by removing this 417 * check for the top level OID value, and then adding 418 * CTLFLAG_ANYBODY to the leaf nodes in question. Enforce as 419 * suser for writed in leaf nodes by omitting this flag. 420 * Enforce with a higher granularity by making the leaf node 421 * of type SYSCTL_PROC() in order to provide a procedural 422 * enforcement call site. 423 * 424 * NOTE: This function is called prior to any subfunctions being 425 * called with a fallback to userland_sysctl(); as such, this 426 * permissions check here will veto the fallback operation. 427 */ 428 /* CTL_UNSPEC is used to get oid to AUTO_OID */ 429 if (uap->new != USER_ADDR_NULL 430 && ((name[0] == CTL_HW) 431 || (name[0] == CTL_VM)) 432 && (error = suser(kauth_cred_get(), &p->p_acflag))) 433 return (error); 434 435// XXX need to relocate into each terminal instead of leaving this here... 436// XXX macf preemptory check. 437#if CONFIG_MACF 438 my_cred = kauth_cred_proc_ref(p); 439 error = mac_system_check_sysctl( 440 my_cred, 441 (int *) name, 442 uap->namelen, 443 uap->old, 444 uap->oldlenp, 445 0, /* XXX 1 for CTL_KERN checks */ 446 uap->new, 447 newlen 448 ); 449 kauth_cred_unref(&my_cred); 450 if (error) 451 return (error); 452#endif 453 454 if (uap->oldlenp != USER_ADDR_NULL) { 455 uint64_t oldlen64 = fuulong(uap->oldlenp); 456 457 oldlen = CAST_DOWN(size_t, oldlen64); 458 /* 459 * If more than 4G, clamp to 4G - useracc() below will catch 460 * with an EFAULT, if it's actually necessary. 461 */ 462 if (oldlen64 > 0x00000000ffffffffULL) 463 oldlen = 0xffffffffUL; 464 } 465 466 if ((name[0] == CTL_VFS || name[0] == CTL_VM)) { 467 /* 468 * Always take the funnel for CTL_VFS and CTL_VM 469 * 470 * XXX We should also take it for any OID without the 471 * XXX CTLFLAG_LOCKED set on it; fix this later! 472 */ 473 funnel_state = thread_funnel_set(kernel_flock, TRUE); 474 funnel_taken = TRUE; 475 476 /* 477 * XXX Take the vslock() only when we are copying out; this 478 * XXX erroneously assumes that the copy in will not cause 479 * XXX a fault if caled from the paging path due to the 480 * XXX having been recently touched in order to establish 481 * XXX the input data. This is a bad assumption. 482 * 483 * Note: This is overkill, but third parties might 484 * already call sysctl internally in KEXTs that 485 * implement mass storage drivers. If you are 486 * writing a new KEXT, don't do that. 487 */ 488 if(uap->old != USER_ADDR_NULL) { 489 if (!useracc(uap->old, (user_size_t)oldlen, B_WRITE)) { 490 thread_funnel_set(kernel_flock, funnel_state); 491 return (EFAULT); 492 } 493 494 if (oldlen) { 495 if ((error = vslock(uap->old, (user_size_t)oldlen))) { 496 thread_funnel_set(kernel_flock, funnel_state); 497 return(error); 498 } 499 savelen = oldlen; 500 vslock_taken = TRUE; 501 } 502 } 503 } 504 505 /* 506 * XXX convert vfs_sysctl subelements to newsysctl; this is hard 507 * XXX because of VFS_NUMMNTOPS being top level. 508 */ 509 error = ENOTSUP; 510 if (name[0] == CTL_VFS) { 511 error = vfs_sysctl(name + 1, uap->namelen - 1, uap->old, 512 &oldlen, uap->new, newlen, p); 513 } 514 515 if (vslock_taken == TRUE) { 516 error1 = vsunlock(uap->old, (user_size_t)savelen, B_WRITE); 517 if (!error) 518 error = error1; 519 } 520 521 if ( (name[0] != CTL_VFS) && (error == ENOTSUP) ) { 522 size_t tmp = oldlen; 523 error = userland_sysctl(p, name, uap->namelen, uap->old, &tmp, 524 uap->new, newlen, &oldlen); 525 } 526 527 /* 528 * If we took the funnel, which we only do for CTL_VFS and CTL_VM on 529 * 32 bit architectures, then drop it. 530 * 531 * XXX the grabbing and dropping need to move into the leaf nodes, 532 * XXX for sysctl's that are not marked CTLFLAG_LOCKED, but this is 533 * XXX true for the vslock, as well. We have a start at a routine 534 * to wrapper this (above), but it's not turned on. The current code 535 * removed the funnel and the vslock() from all but these two top 536 * level OIDs. Note that VFS only needs to take the funnel if the FS 537 * against which it's operating is not thread safe (but since an FS 538 * can be in the paging path, it still needs to take the vslock()). 539 */ 540 if (funnel_taken) 541 thread_funnel_set(kernel_flock, funnel_state); 542 543 if ((error) && (error != ENOMEM)) 544 return (error); 545 546 if (uap->oldlenp != USER_ADDR_NULL) 547 error = suulong(uap->oldlenp, oldlen); 548 549 return (error); 550} 551 552/* 553 * Attributes stored in the kernel. 554 */ 555__private_extern__ char corefilename[MAXPATHLEN+1]; 556__private_extern__ int do_coredump; 557__private_extern__ int sugid_coredump; 558 559#if COUNT_SYSCALLS 560__private_extern__ int do_count_syscalls; 561#endif 562 563#ifdef INSECURE 564int securelevel = -1; 565#else 566int securelevel; 567#endif 568 569STATIC int 570sysctl_doaffinity SYSCTL_HANDLER_ARGS 571{ 572 __unused int cmd = oidp->oid_arg2; /* subcommand*/ 573 int *name = arg1; /* oid element argument vector */ 574 int namelen = arg2; /* number of oid element arguments */ 575 user_addr_t oldp = req->oldptr; /* user buffer copy out address */ 576 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */ 577 user_addr_t newp = req->newptr; /* user buffer copy in address */ 578// size_t newlen = req->newlen; /* user buffer copy in size */ 579 580 int error = ENOTSUP; /* Default to failure */ 581 582 proc_t cur_proc = current_proc(); 583 584 if (namelen < 1) 585 return (ENOTSUP); 586 587 if (name[0] == 0 && 1 == namelen) { 588 error = sysctl_rdint(oldp, oldlenp, newp, 589 (cur_proc->p_flag & P_AFFINITY) ? 1 : 0); 590 } else if (name[0] == 1 && 2 == namelen) { 591 if (name[1] == 0) { 592 OSBitAndAtomic(~((uint32_t)P_AFFINITY), &cur_proc->p_flag); 593 } else { 594 OSBitOrAtomic(P_AFFINITY, &cur_proc->p_flag); 595 } 596 error = 0; 597 } 598 599 /* adjust index so we return the right required/consumed amount */ 600 if (!error) 601 req->oldidx += req->oldlen; 602 603 return (error); 604} 605SYSCTL_PROC(_kern, KERN_AFFINITY, affinity, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 606 0, /* Pointer argument (arg1) */ 607 0, /* Integer argument (arg2) */ 608 sysctl_doaffinity, /* Handler function */ 609 NULL, /* Data pointer */ 610 ""); 611 612STATIC int 613sysctl_dotranslate SYSCTL_HANDLER_ARGS 614{ 615 __unused int cmd = oidp->oid_arg2; /* subcommand*/ 616 int *name = arg1; /* oid element argument vector */ 617 int namelen = arg2; /* number of oid element arguments */ 618 user_addr_t oldp = req->oldptr; /* user buffer copy out address */ 619 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */ 620 user_addr_t newp = req->newptr; /* user buffer copy in address */ 621// size_t newlen = req->newlen; /* user buffer copy in size */ 622 int error; 623 624 proc_t cur_proc = current_proc(); 625 proc_t p; 626 int istranslated = 0; 627 kauth_cred_t my_cred; 628 uid_t uid; 629 630 if (namelen != 1) 631 return (ENOTSUP); 632 633 p = proc_find(name[0]); 634 if (p == NULL) 635 return (EINVAL); 636 637 my_cred = kauth_cred_proc_ref(p); 638 uid = kauth_cred_getuid(my_cred); 639 kauth_cred_unref(&my_cred); 640 if ((uid != kauth_cred_getuid(kauth_cred_get())) 641 && suser(kauth_cred_get(), &cur_proc->p_acflag)) { 642 proc_rele(p); 643 return (EPERM); 644 } 645 646 istranslated = (p->p_flag & P_TRANSLATED); 647 proc_rele(p); 648 error = sysctl_rdint(oldp, oldlenp, newp, 649 (istranslated != 0) ? 1 : 0); 650 651 /* adjust index so we return the right required/consumed amount */ 652 if (!error) 653 req->oldidx += req->oldlen; 654 655 return (error); 656} 657/* 658 * XXX make CTLFLAG_RW so sysctl_rdint() will EPERM on attempts to write; 659 * XXX this may not be necessary. 660 */ 661SYSCTL_PROC(_kern, KERN_TRANSLATE, translate, CTLTYPE_NODE|CTLFLAG_RW | CTLFLAG_LOCKED, 662 0, /* Pointer argument (arg1) */ 663 0, /* Integer argument (arg2) */ 664 sysctl_dotranslate, /* Handler function */ 665 NULL, /* Data pointer */ 666 ""); 667 668STATIC int 669sysctl_handle_kern_threadname( __unused struct sysctl_oid *oidp, __unused void *arg1, 670 __unused int arg2, struct sysctl_req *req) 671{ 672 int error; 673 struct uthread *ut = get_bsdthread_info(current_thread()); 674 user_addr_t oldp=0, newp=0; 675 size_t *oldlenp=NULL; 676 size_t newlen=0; 677 678 oldp = req->oldptr; 679 oldlenp = &(req->oldlen); 680 newp = req->newptr; 681 newlen = req->newlen; 682 683 /* We want the current length, and maybe the string itself */ 684 if(oldlenp) { 685 /* if we have no thread name yet tell'em we want MAXTHREADNAMESIZE - 1 */ 686 size_t currlen = MAXTHREADNAMESIZE - 1; 687 688 if(ut->pth_name) 689 /* use length of current thread name */ 690 currlen = strlen(ut->pth_name); 691 if(oldp) { 692 if(*oldlenp < currlen) 693 return ENOMEM; 694 /* NOTE - we do not copy the NULL terminator */ 695 if(ut->pth_name) { 696 error = copyout(ut->pth_name,oldp,currlen); 697 if(error) 698 return error; 699 } 700 } 701 /* return length of thread name minus NULL terminator (just like strlen) */ 702 req->oldidx = currlen; 703 } 704 705 /* We want to set the name to something */ 706 if(newp) 707 { 708 if(newlen > (MAXTHREADNAMESIZE - 1)) 709 return ENAMETOOLONG; 710 if(!ut->pth_name) 711 { 712 ut->pth_name = (char*)kalloc( MAXTHREADNAMESIZE ); 713 if(!ut->pth_name) 714 return ENOMEM; 715 } 716 bzero(ut->pth_name, MAXTHREADNAMESIZE); 717 error = copyin(newp, ut->pth_name, newlen); 718 if(error) 719 return error; 720 } 721 722 return 0; 723} 724 725SYSCTL_PROC(_kern, KERN_THREADNAME, threadname, CTLFLAG_ANYBODY | CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0, sysctl_handle_kern_threadname,"A",""); 726 727#define BSD_HOST 1 728STATIC int 729sysctl_sched_stats(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 730{ 731 host_basic_info_data_t hinfo; 732 kern_return_t kret; 733 uint32_t size; 734 int changed; 735 mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; 736 struct _processor_statistics_np *buf; 737 int error; 738 739 kret = host_info((host_t)BSD_HOST, HOST_BASIC_INFO, (host_info_t)&hinfo, &count); 740 if (kret != KERN_SUCCESS) { 741 return EINVAL; 742 } 743 744 size = sizeof(struct _processor_statistics_np) * (hinfo.logical_cpu_max + 2); /* One for RT Queue, One for Fair Share Queue */ 745 746 if (req->oldlen < size) { 747 return EINVAL; 748 } 749 750 MALLOC(buf, struct _processor_statistics_np*, size, M_TEMP, M_ZERO | M_WAITOK); 751 752 kret = get_sched_statistics(buf, &size); 753 if (kret != KERN_SUCCESS) { 754 error = EINVAL; 755 goto out; 756 } 757 758 error = sysctl_io_opaque(req, buf, size, &changed); 759 if (error) { 760 goto out; 761 } 762 763 if (changed) { 764 panic("Sched info changed?!"); 765 } 766out: 767 FREE(buf, M_TEMP); 768 return error; 769} 770 771SYSCTL_PROC(_kern, OID_AUTO, sched_stats, CTLFLAG_LOCKED, 0, 0, sysctl_sched_stats, "-", ""); 772 773STATIC int 774sysctl_sched_stats_enable(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, __unused struct sysctl_req *req) 775{ 776 boolean_t active; 777 int res; 778 779 if (req->newlen != sizeof(active)) { 780 return EINVAL; 781 } 782 783 res = copyin(req->newptr, &active, sizeof(active)); 784 if (res != 0) { 785 return res; 786 } 787 788 return set_sched_stats_active(active); 789} 790 791SYSCTL_PROC(_kern, OID_AUTO, sched_stats_enable, CTLFLAG_LOCKED | CTLFLAG_WR, 0, 0, sysctl_sched_stats_enable, "-", ""); 792 793extern int get_kernel_symfile(proc_t, char **); 794 795#if COUNT_SYSCALLS 796#define KERN_COUNT_SYSCALLS (KERN_OSTYPE + 1000) 797 798extern int nsysent; 799extern int syscalls_log[]; 800extern const char *syscallnames[]; 801 802STATIC int 803sysctl_docountsyscalls SYSCTL_HANDLER_ARGS 804{ 805 __unused int cmd = oidp->oid_arg2; /* subcommand*/ 806 __unused int *name = arg1; /* oid element argument vector */ 807 __unused int namelen = arg2; /* number of oid element arguments */ 808 user_addr_t oldp = req->oldptr; /* user buffer copy out address */ 809 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */ 810 user_addr_t newp = req->newptr; /* user buffer copy in address */ 811 size_t newlen = req->newlen; /* user buffer copy in size */ 812 int error; 813 814 int tmp; 815 816 /* valid values passed in: 817 * = 0 means don't keep called counts for each bsd syscall 818 * > 0 means keep called counts for each bsd syscall 819 * = 2 means dump current counts to the system log 820 * = 3 means reset all counts 821 * for example, to dump current counts: 822 * sysctl -w kern.count_calls=2 823 */ 824 error = sysctl_int(oldp, oldlenp, newp, newlen, &tmp); 825 if ( error != 0 ) { 826 return (error); 827 } 828 829 if ( tmp == 1 ) { 830 do_count_syscalls = 1; 831 } 832 else if ( tmp == 0 || tmp == 2 || tmp == 3 ) { 833 int i; 834 for ( i = 0; i < nsysent; i++ ) { 835 if ( syscalls_log[i] != 0 ) { 836 if ( tmp == 2 ) { 837 printf("%d calls - name %s \n", syscalls_log[i], syscallnames[i]); 838 } 839 else { 840 syscalls_log[i] = 0; 841 } 842 } 843 } 844 if ( tmp != 0 ) { 845 do_count_syscalls = 1; 846 } 847 } 848 849 /* adjust index so we return the right required/consumed amount */ 850 if (!error) 851 req->oldidx += req->oldlen; 852 853 return (error); 854} 855SYSCTL_PROC(_kern, KERN_COUNT_SYSCALLS, count_syscalls, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 856 0, /* Pointer argument (arg1) */ 857 0, /* Integer argument (arg2) */ 858 sysctl_docountsyscalls, /* Handler function */ 859 NULL, /* Data pointer */ 860 ""); 861#endif /* COUNT_SYSCALLS */ 862 863#if DEBUG 864/* 865 * Debugging related system variables. 866 */ 867#if DIAGNOSTIC 868extern 869#endif /* DIAGNOSTIC */ 870struct ctldebug debug0, debug1; 871struct ctldebug debug2, debug3, debug4; 872struct ctldebug debug5, debug6, debug7, debug8, debug9; 873struct ctldebug debug10, debug11, debug12, debug13, debug14; 874struct ctldebug debug15, debug16, debug17, debug18, debug19; 875STATIC struct ctldebug *debugvars[CTL_DEBUG_MAXID] = { 876 &debug0, &debug1, &debug2, &debug3, &debug4, 877 &debug5, &debug6, &debug7, &debug8, &debug9, 878 &debug10, &debug11, &debug12, &debug13, &debug14, 879 &debug15, &debug16, &debug17, &debug18, &debug19, 880}; 881STATIC int 882sysctl_dodebug SYSCTL_HANDLER_ARGS 883{ 884 int cmd = oidp->oid_arg2; /* subcommand*/ 885 int *name = arg1; /* oid element argument vector */ 886 int namelen = arg2; /* number of oid element arguments */ 887 user_addr_t oldp = req->oldptr; /* user buffer copy out address */ 888 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */ 889 user_addr_t newp = req->newptr; /* user buffer copy in address */ 890 size_t newlen = req->newlen; /* user buffer copy in size */ 891 int error; 892 893 struct ctldebug *cdp; 894 895 /* all sysctl names at this level are name and field */ 896 if (namelen != 1) 897 return (ENOTSUP); /* overloaded */ 898 if (cmd < 0 || cmd >= CTL_DEBUG_MAXID) 899 return (ENOTSUP); 900 cdp = debugvars[cmd]; 901 if (cdp->debugname == 0) 902 return (ENOTSUP); 903 switch (name[0]) { 904 case CTL_DEBUG_NAME: 905 error = sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname); 906 break; 907 case CTL_DEBUG_VALUE: 908 error = sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar); 909 break; 910 default: 911 error = ENOTSUP; 912 break; 913 } 914 915 /* adjust index so we return the right required/consumed amount */ 916 if (!error) 917 req->oldidx += req->oldlen; 918 919 return (error); 920} 921/* 922 * XXX We mark this RW instead of RD to let sysctl_rdstring() return the 923 * XXX historical error. 924 */ 925SYSCTL_PROC(_debug, CTL_DEBUG_NAME, name, CTLTYPE_NODE|CTLFLAG_RW | CTLFLAG_LOCKED, 926 0, /* Pointer argument (arg1) */ 927 CTL_DEBUG_NAME, /* Integer argument (arg2) */ 928 sysctl_dodebug, /* Handler function */ 929 NULL, /* Data pointer */ 930 "Debugging"); 931SYSCTL_PROC(_debug, CTL_DEBUG_VALUE, value, CTLTYPE_NODE|CTLFLAG_RW | CTLFLAG_LOCKED, 932 0, /* Pointer argument (arg1) */ 933 CTL_DEBUG_VALUE, /* Integer argument (arg2) */ 934 sysctl_dodebug, /* Handler function */ 935 NULL, /* Data pointer */ 936 "Debugging"); 937#endif /* DEBUG */ 938 939/* 940 * The following sysctl_* functions should not be used 941 * any more, as they can only cope with callers in 942 * user mode: Use new-style 943 * sysctl_io_number() 944 * sysctl_io_string() 945 * sysctl_io_opaque() 946 * instead. 947 */ 948 949/* 950 * Validate parameters and get old / set new parameters 951 * for an integer-valued sysctl function. 952 */ 953int 954sysctl_int(user_addr_t oldp, size_t *oldlenp, 955 user_addr_t newp, size_t newlen, int *valp) 956{ 957 int error = 0; 958 959 if (oldp != USER_ADDR_NULL && oldlenp == NULL) 960 return (EFAULT); 961 if (oldp && *oldlenp < sizeof(int)) 962 return (ENOMEM); 963 if (newp && newlen != sizeof(int)) 964 return (EINVAL); 965 *oldlenp = sizeof(int); 966 if (oldp) 967 error = copyout(valp, oldp, sizeof(int)); 968 if (error == 0 && newp) { 969 error = copyin(newp, valp, sizeof(int)); 970 AUDIT_ARG(value32, *valp); 971 } 972 return (error); 973} 974 975/* 976 * As above, but read-only. 977 */ 978int 979sysctl_rdint(user_addr_t oldp, size_t *oldlenp, user_addr_t newp, int val) 980{ 981 int error = 0; 982 983 if (oldp != USER_ADDR_NULL && oldlenp == NULL) 984 return (EFAULT); 985 if (oldp && *oldlenp < sizeof(int)) 986 return (ENOMEM); 987 if (newp) 988 return (EPERM); 989 *oldlenp = sizeof(int); 990 if (oldp) 991 error = copyout((caddr_t)&val, oldp, sizeof(int)); 992 return (error); 993} 994 995/* 996 * Validate parameters and get old / set new parameters 997 * for an quad(64bit)-valued sysctl function. 998 */ 999int 1000sysctl_quad(user_addr_t oldp, size_t *oldlenp, 1001 user_addr_t newp, size_t newlen, quad_t *valp) 1002{ 1003 int error = 0; 1004 1005 if (oldp != USER_ADDR_NULL && oldlenp == NULL) 1006 return (EFAULT); 1007 if (oldp && *oldlenp < sizeof(quad_t)) 1008 return (ENOMEM); 1009 if (newp && newlen != sizeof(quad_t)) 1010 return (EINVAL); 1011 *oldlenp = sizeof(quad_t); 1012 if (oldp) 1013 error = copyout(valp, oldp, sizeof(quad_t)); 1014 if (error == 0 && newp) 1015 error = copyin(newp, valp, sizeof(quad_t)); 1016 return (error); 1017} 1018 1019/* 1020 * As above, but read-only. 1021 */ 1022int 1023sysctl_rdquad(user_addr_t oldp, size_t *oldlenp, user_addr_t newp, quad_t val) 1024{ 1025 int error = 0; 1026 1027 if (oldp != USER_ADDR_NULL && oldlenp == NULL) 1028 return (EFAULT); 1029 if (oldp && *oldlenp < sizeof(quad_t)) 1030 return (ENOMEM); 1031 if (newp) 1032 return (EPERM); 1033 *oldlenp = sizeof(quad_t); 1034 if (oldp) 1035 error = copyout((caddr_t)&val, oldp, sizeof(quad_t)); 1036 return (error); 1037} 1038 1039/* 1040 * Validate parameters and get old / set new parameters 1041 * for a string-valued sysctl function. Unlike sysctl_string, if you 1042 * give it a too small (but larger than 0 bytes) buffer, instead of 1043 * returning ENOMEM, it truncates the returned string to the buffer 1044 * size. This preserves the semantics of some library routines 1045 * implemented via sysctl, which truncate their returned data, rather 1046 * than simply returning an error. The returned string is always NUL 1047 * terminated. 1048 */ 1049int 1050sysctl_trstring(user_addr_t oldp, size_t *oldlenp, 1051 user_addr_t newp, size_t newlen, char *str, int maxlen) 1052{ 1053 int len, copylen, error = 0; 1054 1055 if (oldp != USER_ADDR_NULL && oldlenp == NULL) 1056 return (EFAULT); 1057 copylen = len = strlen(str) + 1; 1058 if (oldp && (len < 0 || *oldlenp < 1)) 1059 return (ENOMEM); 1060 if (oldp && (*oldlenp < (size_t)len)) 1061 copylen = *oldlenp + 1; 1062 if (newp && (maxlen < 0 || newlen >= (size_t)maxlen)) 1063 return (EINVAL); 1064 *oldlenp = copylen - 1; /* deal with NULL strings correctly */ 1065 if (oldp) { 1066 error = copyout(str, oldp, copylen); 1067 if (!error) { 1068 unsigned char c = 0; 1069 /* NUL terminate */ 1070 oldp += *oldlenp; 1071 error = copyout((void *)&c, oldp, sizeof(char)); 1072 } 1073 } 1074 if (error == 0 && newp) { 1075 error = copyin(newp, str, newlen); 1076 str[newlen] = 0; 1077 AUDIT_ARG(text, (char *)str); 1078 } 1079 return (error); 1080} 1081 1082/* 1083 * Validate parameters and get old / set new parameters 1084 * for a string-valued sysctl function. 1085 */ 1086int 1087sysctl_string(user_addr_t oldp, size_t *oldlenp, 1088 user_addr_t newp, size_t newlen, char *str, int maxlen) 1089{ 1090 int len, error = 0; 1091 1092 if (oldp != USER_ADDR_NULL && oldlenp == NULL) 1093 return (EFAULT); 1094 len = strlen(str) + 1; 1095 if (oldp && (len < 0 || *oldlenp < (size_t)len)) 1096 return (ENOMEM); 1097 if (newp && (maxlen < 0 || newlen >= (size_t)maxlen)) 1098 return (EINVAL); 1099 *oldlenp = len -1; /* deal with NULL strings correctly */ 1100 if (oldp) { 1101 error = copyout(str, oldp, len); 1102 } 1103 if (error == 0 && newp) { 1104 error = copyin(newp, str, newlen); 1105 str[newlen] = 0; 1106 AUDIT_ARG(text, (char *)str); 1107 } 1108 return (error); 1109} 1110 1111/* 1112 * As above, but read-only. 1113 */ 1114int 1115sysctl_rdstring(user_addr_t oldp, size_t *oldlenp, 1116 user_addr_t newp, char *str) 1117{ 1118 int len, error = 0; 1119 1120 if (oldp != USER_ADDR_NULL && oldlenp == NULL) 1121 return (EFAULT); 1122 len = strlen(str) + 1; 1123 if (oldp && *oldlenp < (size_t)len) 1124 return (ENOMEM); 1125 if (newp) 1126 return (EPERM); 1127 *oldlenp = len; 1128 if (oldp) 1129 error = copyout(str, oldp, len); 1130 return (error); 1131} 1132 1133/* 1134 * Validate parameters and get old / set new parameters 1135 * for a structure oriented sysctl function. 1136 */ 1137int 1138sysctl_struct(user_addr_t oldp, size_t *oldlenp, 1139 user_addr_t newp, size_t newlen, void *sp, int len) 1140{ 1141 int error = 0; 1142 1143 if (oldp != USER_ADDR_NULL && oldlenp == NULL) 1144 return (EFAULT); 1145 if (oldp && (len < 0 || *oldlenp < (size_t)len)) 1146 return (ENOMEM); 1147 if (newp && (len < 0 || newlen > (size_t)len)) 1148 return (EINVAL); 1149 if (oldp) { 1150 *oldlenp = len; 1151 error = copyout(sp, oldp, len); 1152 } 1153 if (error == 0 && newp) 1154 error = copyin(newp, sp, len); 1155 return (error); 1156} 1157 1158/* 1159 * Validate parameters and get old parameters 1160 * for a structure oriented sysctl function. 1161 */ 1162int 1163sysctl_rdstruct(user_addr_t oldp, size_t *oldlenp, 1164 user_addr_t newp, void *sp, int len) 1165{ 1166 int error = 0; 1167 1168 if (oldp != USER_ADDR_NULL && oldlenp == NULL) 1169 return (EFAULT); 1170 if (oldp && (len < 0 || *oldlenp < (size_t)len)) 1171 return (ENOMEM); 1172 if (newp) 1173 return (EPERM); 1174 *oldlenp = len; 1175 if (oldp) 1176 error = copyout(sp, oldp, len); 1177 return (error); 1178} 1179 1180STATIC int 1181sysdoproc_filt_KERN_PROC_PID(proc_t p, void * arg) 1182{ 1183 if (p->p_pid != (pid_t)*(int*)arg) 1184 return(0); 1185 else 1186 return(1); 1187} 1188 1189STATIC int 1190sysdoproc_filt_KERN_PROC_PGRP(proc_t p, void * arg) 1191{ 1192 if (p->p_pgrpid != (pid_t)*(int*)arg) 1193 return(0); 1194 else 1195 return(1); 1196} 1197 1198STATIC int 1199sysdoproc_filt_KERN_PROC_TTY(proc_t p, void * arg) 1200{ 1201 boolean_t funnel_state; 1202 int retval; 1203 struct tty *tp; 1204 1205 1206 funnel_state = thread_funnel_set(kernel_flock, TRUE); 1207 /* This is very racy but list lock is held.. Hmmm. */ 1208 if ((p->p_flag & P_CONTROLT) == 0 || 1209 (p->p_pgrp == NULL) || (p->p_pgrp->pg_session == NULL) || 1210 (tp = SESSION_TP(p->p_pgrp->pg_session)) == TTY_NULL || 1211 tp->t_dev != (dev_t)*(int*)arg) 1212 retval = 0; 1213 else 1214 retval = 1; 1215 1216 thread_funnel_set(kernel_flock, funnel_state); 1217 1218 return(retval); 1219} 1220 1221STATIC int 1222sysdoproc_filt_KERN_PROC_UID(proc_t p, void * arg) 1223{ 1224 kauth_cred_t my_cred; 1225 uid_t uid; 1226 1227 if (p->p_ucred == NULL) 1228 return(0); 1229 my_cred = kauth_cred_proc_ref(p); 1230 uid = kauth_cred_getuid(my_cred); 1231 kauth_cred_unref(&my_cred); 1232 1233 if (uid != (uid_t)*(int*)arg) 1234 return(0); 1235 else 1236 return(1); 1237} 1238 1239 1240STATIC int 1241sysdoproc_filt_KERN_PROC_RUID(proc_t p, void * arg) 1242{ 1243 kauth_cred_t my_cred; 1244 uid_t ruid; 1245 1246 if (p->p_ucred == NULL) 1247 return(0); 1248 my_cred = kauth_cred_proc_ref(p); 1249 ruid = kauth_cred_getruid(my_cred); 1250 kauth_cred_unref(&my_cred); 1251 1252 if (ruid != (uid_t)*(int*)arg) 1253 return(0); 1254 else 1255 return(1); 1256} 1257 1258#if CONFIG_LCTX 1259STATIC int 1260sysdoproc_filt_KERN_PROC_LCID(proc_t p, void * arg) 1261{ 1262 if ((p->p_lctx == NULL) || 1263 (p->p_lctx->lc_id != (pid_t)*(int*)arg)) 1264 return(0); 1265 else 1266 return(1); 1267} 1268#endif 1269 1270/* 1271 * try over estimating by 5 procs 1272 */ 1273#define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc)) 1274struct sysdoproc_args { 1275 int buflen; 1276 void *kprocp; 1277 boolean_t is_64_bit; 1278 user_addr_t dp; 1279 size_t needed; 1280 int sizeof_kproc; 1281 int *errorp; 1282 int uidcheck; 1283 int ruidcheck; 1284 int ttycheck; 1285 int uidval; 1286}; 1287 1288int 1289sysdoproc_callback(proc_t p, void *arg) 1290{ 1291 struct sysdoproc_args *args = arg; 1292 1293 if (args->buflen >= args->sizeof_kproc) { 1294 if ((args->ruidcheck != 0) && (sysdoproc_filt_KERN_PROC_RUID(p, &args->uidval) == 0)) 1295 return (PROC_RETURNED); 1296 if ((args->uidcheck != 0) && (sysdoproc_filt_KERN_PROC_UID(p, &args->uidval) == 0)) 1297 return (PROC_RETURNED); 1298 if ((args->ttycheck != 0) && (sysdoproc_filt_KERN_PROC_TTY(p, &args->uidval) == 0)) 1299 return (PROC_RETURNED); 1300 1301 bzero(args->kprocp, args->sizeof_kproc); 1302 if (args->is_64_bit) 1303 fill_user64_proc(p, args->kprocp); 1304 else 1305 fill_user32_proc(p, args->kprocp); 1306 int error = copyout(args->kprocp, args->dp, args->sizeof_kproc); 1307 if (error) { 1308 *args->errorp = error; 1309 return (PROC_RETURNED_DONE); 1310 } 1311 args->dp += args->sizeof_kproc; 1312 args->buflen -= args->sizeof_kproc; 1313 } 1314 args->needed += args->sizeof_kproc; 1315 return (PROC_RETURNED); 1316} 1317 1318SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD | CTLFLAG_LOCKED, 0, ""); 1319STATIC int 1320sysctl_prochandle SYSCTL_HANDLER_ARGS 1321{ 1322 int cmd = oidp->oid_arg2; /* subcommand for multiple nodes */ 1323 int *name = arg1; /* oid element argument vector */ 1324 int namelen = arg2; /* number of oid element arguments */ 1325 user_addr_t where = req->oldptr;/* user buffer copy out address */ 1326 1327 user_addr_t dp = where; 1328 size_t needed = 0; 1329 int buflen = where != USER_ADDR_NULL ? req->oldlen : 0; 1330 int error = 0; 1331 boolean_t is_64_bit = proc_is64bit(current_proc()); 1332 struct user32_kinfo_proc user32_kproc; 1333 struct user64_kinfo_proc user_kproc; 1334 int sizeof_kproc; 1335 void *kprocp; 1336 int (*filterfn)(proc_t, void *) = 0; 1337 struct sysdoproc_args args; 1338 int uidcheck = 0; 1339 int ruidcheck = 0; 1340 int ttycheck = 0; 1341 1342 if (namelen != 1 && !(namelen == 0 && cmd == KERN_PROC_ALL)) 1343 return (EINVAL); 1344 1345 if (is_64_bit) { 1346 sizeof_kproc = sizeof(user_kproc); 1347 kprocp = &user_kproc; 1348 } else { 1349 sizeof_kproc = sizeof(user32_kproc); 1350 kprocp = &user32_kproc; 1351 } 1352 1353 switch (cmd) { 1354 1355 case KERN_PROC_PID: 1356 filterfn = sysdoproc_filt_KERN_PROC_PID; 1357 break; 1358 1359 case KERN_PROC_PGRP: 1360 filterfn = sysdoproc_filt_KERN_PROC_PGRP; 1361 break; 1362 1363 case KERN_PROC_TTY: 1364 ttycheck = 1; 1365 break; 1366 1367 case KERN_PROC_UID: 1368 uidcheck = 1; 1369 break; 1370 1371 case KERN_PROC_RUID: 1372 ruidcheck = 1; 1373 break; 1374 1375#if CONFIG_LCTX 1376 case KERN_PROC_LCID: 1377 filterfn = sysdoproc_filt_KERN_PROC_LCID; 1378 break; 1379#endif 1380 case KERN_PROC_ALL: 1381 break; 1382 1383 default: 1384 /* must be kern.proc.<unknown> */ 1385 return (ENOTSUP); 1386 } 1387 1388 error = 0; 1389 args.buflen = buflen; 1390 args.kprocp = kprocp; 1391 args.is_64_bit = is_64_bit; 1392 args.dp = dp; 1393 args.needed = needed; 1394 args.errorp = &error; 1395 args.uidcheck = uidcheck; 1396 args.ruidcheck = ruidcheck; 1397 args.ttycheck = ttycheck; 1398 args.sizeof_kproc = sizeof_kproc; 1399 if (namelen) 1400 args.uidval = name[0]; 1401 1402 proc_iterate((PROC_ALLPROCLIST | PROC_ZOMBPROCLIST), 1403 sysdoproc_callback, &args, filterfn, name); 1404 1405 if (error) 1406 return (error); 1407 1408 dp = args.dp; 1409 needed = args.needed; 1410 1411 if (where != USER_ADDR_NULL) { 1412 req->oldlen = dp - where; 1413 if (needed > req->oldlen) 1414 return (ENOMEM); 1415 } else { 1416 needed += KERN_PROCSLOP; 1417 req->oldlen = needed; 1418 } 1419 /* adjust index so we return the right required/consumed amount */ 1420 req->oldidx += req->oldlen; 1421 return (0); 1422} 1423 1424/* 1425 * We specify the subcommand code for multiple nodes as the 'req->arg2' value 1426 * in the sysctl declaration itself, which comes into the handler function 1427 * as 'oidp->oid_arg2'. 1428 * 1429 * For these particular sysctls, since they have well known OIDs, we could 1430 * have just obtained it from the '((int *)arg1)[0]' parameter, but that would 1431 * not demonstrate how to handle multiple sysctls that used OID_AUTO instead 1432 * of a well known value with a common handler function. This is desirable, 1433 * because we want well known values to "go away" at some future date. 1434 * 1435 * It should be noted that the value of '((int *)arg1)[1]' is used for many 1436 * an integer parameter to the subcommand for many of these sysctls; we'd 1437 * rather have used '((int *)arg1)[0]' for that, or even better, an element 1438 * in a structure passed in as the the 'newp' argument to sysctlbyname(3), 1439 * and then use leaf-node permissions enforcement, but that would have 1440 * necessitated modifying user space code to correspond to the interface 1441 * change, and we are striving for binary backward compatibility here; even 1442 * though these are SPI, and not intended for use by user space applications 1443 * which are not themselves system tools or libraries, some applications 1444 * have erroneously used them. 1445 */ 1446SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 1447 0, /* Pointer argument (arg1) */ 1448 KERN_PROC_ALL, /* Integer argument (arg2) */ 1449 sysctl_prochandle, /* Handler function */ 1450 NULL, /* Data is size variant on ILP32/LP64 */ 1451 ""); 1452SYSCTL_PROC(_kern_proc, KERN_PROC_PID, pid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 1453 0, /* Pointer argument (arg1) */ 1454 KERN_PROC_PID, /* Integer argument (arg2) */ 1455 sysctl_prochandle, /* Handler function */ 1456 NULL, /* Data is size variant on ILP32/LP64 */ 1457 ""); 1458SYSCTL_PROC(_kern_proc, KERN_PROC_TTY, tty, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 1459 0, /* Pointer argument (arg1) */ 1460 KERN_PROC_TTY, /* Integer argument (arg2) */ 1461 sysctl_prochandle, /* Handler function */ 1462 NULL, /* Data is size variant on ILP32/LP64 */ 1463 ""); 1464SYSCTL_PROC(_kern_proc, KERN_PROC_PGRP, pgrp, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 1465 0, /* Pointer argument (arg1) */ 1466 KERN_PROC_PGRP, /* Integer argument (arg2) */ 1467 sysctl_prochandle, /* Handler function */ 1468 NULL, /* Data is size variant on ILP32/LP64 */ 1469 ""); 1470SYSCTL_PROC(_kern_proc, KERN_PROC_UID, uid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 1471 0, /* Pointer argument (arg1) */ 1472 KERN_PROC_UID, /* Integer argument (arg2) */ 1473 sysctl_prochandle, /* Handler function */ 1474 NULL, /* Data is size variant on ILP32/LP64 */ 1475 ""); 1476SYSCTL_PROC(_kern_proc, KERN_PROC_RUID, ruid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 1477 0, /* Pointer argument (arg1) */ 1478 KERN_PROC_RUID, /* Integer argument (arg2) */ 1479 sysctl_prochandle, /* Handler function */ 1480 NULL, /* Data is size variant on ILP32/LP64 */ 1481 ""); 1482SYSCTL_PROC(_kern_proc, KERN_PROC_LCID, lcid, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 1483 0, /* Pointer argument (arg1) */ 1484 KERN_PROC_LCID, /* Integer argument (arg2) */ 1485 sysctl_prochandle, /* Handler function */ 1486 NULL, /* Data is size variant on ILP32/LP64 */ 1487 ""); 1488 1489 1490/* 1491 * Fill in non-zero fields of an eproc structure for the specified process. 1492 */ 1493STATIC void 1494fill_user32_eproc(proc_t p, struct user32_eproc *__restrict ep) 1495{ 1496 struct tty *tp; 1497 struct pgrp *pg; 1498 struct session *sessp; 1499 kauth_cred_t my_cred; 1500 1501 pg = proc_pgrp(p); 1502 sessp = proc_session(p); 1503 1504 if (pg != PGRP_NULL) { 1505 ep->e_pgid = p->p_pgrpid; 1506 ep->e_jobc = pg->pg_jobc; 1507 if (sessp != SESSION_NULL && sessp->s_ttyvp) 1508 ep->e_flag = EPROC_CTTY; 1509 } 1510#if CONFIG_LCTX 1511 if (p->p_lctx) 1512 ep->e_lcid = p->p_lctx->lc_id; 1513#endif 1514 ep->e_ppid = p->p_ppid; 1515 if (p->p_ucred) { 1516 my_cred = kauth_cred_proc_ref(p); 1517 1518 /* A fake historical pcred */ 1519 ep->e_pcred.p_ruid = kauth_cred_getruid(my_cred); 1520 ep->e_pcred.p_svuid = kauth_cred_getsvuid(my_cred); 1521 ep->e_pcred.p_rgid = kauth_cred_getrgid(my_cred); 1522 ep->e_pcred.p_svgid = kauth_cred_getsvgid(my_cred); 1523 1524 /* A fake historical *kauth_cred_t */ 1525 ep->e_ucred.cr_ref = my_cred->cr_ref; 1526 ep->e_ucred.cr_uid = kauth_cred_getuid(my_cred); 1527 ep->e_ucred.cr_ngroups = posix_cred_get(my_cred)->cr_ngroups; 1528 bcopy(posix_cred_get(my_cred)->cr_groups, 1529 ep->e_ucred.cr_groups, NGROUPS * sizeof (gid_t)); 1530 1531 kauth_cred_unref(&my_cred); 1532 } 1533 1534 if ((p->p_flag & P_CONTROLT) && (sessp != SESSION_NULL) && 1535 (tp = SESSION_TP(sessp))) { 1536 ep->e_tdev = tp->t_dev; 1537 ep->e_tpgid = sessp->s_ttypgrpid; 1538 } else 1539 ep->e_tdev = NODEV; 1540 1541 if (sessp != SESSION_NULL) { 1542 if (SESS_LEADER(p, sessp)) 1543 ep->e_flag |= EPROC_SLEADER; 1544 session_rele(sessp); 1545 } 1546 if (pg != PGRP_NULL) 1547 pg_rele(pg); 1548} 1549 1550/* 1551 * Fill in non-zero fields of an LP64 eproc structure for the specified process. 1552 */ 1553STATIC void 1554fill_user64_eproc(proc_t p, struct user64_eproc *__restrict ep) 1555{ 1556 struct tty *tp; 1557 struct pgrp *pg; 1558 struct session *sessp; 1559 kauth_cred_t my_cred; 1560 1561 pg = proc_pgrp(p); 1562 sessp = proc_session(p); 1563 1564 if (pg != PGRP_NULL) { 1565 ep->e_pgid = p->p_pgrpid; 1566 ep->e_jobc = pg->pg_jobc; 1567 if (sessp != SESSION_NULL && sessp->s_ttyvp) 1568 ep->e_flag = EPROC_CTTY; 1569 } 1570#if CONFIG_LCTX 1571 if (p->p_lctx) 1572 ep->e_lcid = p->p_lctx->lc_id; 1573#endif 1574 ep->e_ppid = p->p_ppid; 1575 if (p->p_ucred) { 1576 my_cred = kauth_cred_proc_ref(p); 1577 1578 /* A fake historical pcred */ 1579 ep->e_pcred.p_ruid = kauth_cred_getruid(my_cred); 1580 ep->e_pcred.p_svuid = kauth_cred_getsvuid(my_cred); 1581 ep->e_pcred.p_rgid = kauth_cred_getrgid(my_cred); 1582 ep->e_pcred.p_svgid = kauth_cred_getsvgid(my_cred); 1583 1584 /* A fake historical *kauth_cred_t */ 1585 ep->e_ucred.cr_ref = my_cred->cr_ref; 1586 ep->e_ucred.cr_uid = kauth_cred_getuid(my_cred); 1587 ep->e_ucred.cr_ngroups = posix_cred_get(my_cred)->cr_ngroups; 1588 bcopy(posix_cred_get(my_cred)->cr_groups, 1589 ep->e_ucred.cr_groups, NGROUPS * sizeof (gid_t)); 1590 1591 kauth_cred_unref(&my_cred); 1592 } 1593 1594 if ((p->p_flag & P_CONTROLT) && (sessp != SESSION_NULL) && 1595 (tp = SESSION_TP(sessp))) { 1596 ep->e_tdev = tp->t_dev; 1597 ep->e_tpgid = sessp->s_ttypgrpid; 1598 } else 1599 ep->e_tdev = NODEV; 1600 1601 if (sessp != SESSION_NULL) { 1602 if (SESS_LEADER(p, sessp)) 1603 ep->e_flag |= EPROC_SLEADER; 1604 session_rele(sessp); 1605 } 1606 if (pg != PGRP_NULL) 1607 pg_rele(pg); 1608} 1609 1610/* 1611 * Fill in an eproc structure for the specified process. 1612 * bzeroed by our caller, so only set non-zero fields. 1613 */ 1614STATIC void 1615fill_user32_externproc(proc_t p, struct user32_extern_proc *__restrict exp) 1616{ 1617 exp->p_starttime.tv_sec = p->p_start.tv_sec; 1618 exp->p_starttime.tv_usec = p->p_start.tv_usec; 1619 exp->p_flag = p->p_flag; 1620 if (p->p_lflag & P_LTRACED) 1621 exp->p_flag |= P_TRACED; 1622 if (p->p_lflag & P_LPPWAIT) 1623 exp->p_flag |= P_PPWAIT; 1624 if (p->p_lflag & P_LEXIT) 1625 exp->p_flag |= P_WEXIT; 1626 exp->p_stat = p->p_stat; 1627 exp->p_pid = p->p_pid; 1628 exp->p_oppid = p->p_oppid; 1629 /* Mach related */ 1630 exp->user_stack = p->user_stack; 1631 exp->p_debugger = p->p_debugger; 1632 exp->sigwait = p->sigwait; 1633 /* scheduling */ 1634#ifdef _PROC_HAS_SCHEDINFO_ 1635 exp->p_estcpu = p->p_estcpu; 1636 exp->p_pctcpu = p->p_pctcpu; 1637 exp->p_slptime = p->p_slptime; 1638#endif 1639 exp->p_realtimer.it_interval.tv_sec = 1640 (user32_time_t)p->p_realtimer.it_interval.tv_sec; 1641 exp->p_realtimer.it_interval.tv_usec = 1642 (__int32_t)p->p_realtimer.it_interval.tv_usec; 1643 1644 exp->p_realtimer.it_value.tv_sec = 1645 (user32_time_t)p->p_realtimer.it_value.tv_sec; 1646 exp->p_realtimer.it_value.tv_usec = 1647 (__int32_t)p->p_realtimer.it_value.tv_usec; 1648 1649 exp->p_rtime.tv_sec = (user32_time_t)p->p_rtime.tv_sec; 1650 exp->p_rtime.tv_usec = (__int32_t)p->p_rtime.tv_usec; 1651 1652 exp->p_sigignore = p->p_sigignore; 1653 exp->p_sigcatch = p->p_sigcatch; 1654 exp->p_priority = p->p_priority; 1655 exp->p_nice = p->p_nice; 1656 bcopy(&p->p_comm, &exp->p_comm, MAXCOMLEN); 1657 exp->p_xstat = p->p_xstat; 1658 exp->p_acflag = p->p_acflag; 1659} 1660 1661/* 1662 * Fill in an LP64 version of extern_proc structure for the specified process. 1663 */ 1664STATIC void 1665fill_user64_externproc(proc_t p, struct user64_extern_proc *__restrict exp) 1666{ 1667 exp->p_starttime.tv_sec = p->p_start.tv_sec; 1668 exp->p_starttime.tv_usec = p->p_start.tv_usec; 1669 exp->p_flag = p->p_flag; 1670 if (p->p_lflag & P_LTRACED) 1671 exp->p_flag |= P_TRACED; 1672 if (p->p_lflag & P_LPPWAIT) 1673 exp->p_flag |= P_PPWAIT; 1674 if (p->p_lflag & P_LEXIT) 1675 exp->p_flag |= P_WEXIT; 1676 exp->p_stat = p->p_stat; 1677 exp->p_pid = p->p_pid; 1678 exp->p_oppid = p->p_oppid; 1679 /* Mach related */ 1680 exp->user_stack = p->user_stack; 1681 exp->p_debugger = p->p_debugger; 1682 exp->sigwait = p->sigwait; 1683 /* scheduling */ 1684#ifdef _PROC_HAS_SCHEDINFO_ 1685 exp->p_estcpu = p->p_estcpu; 1686 exp->p_pctcpu = p->p_pctcpu; 1687 exp->p_slptime = p->p_slptime; 1688#endif 1689 exp->p_realtimer.it_interval.tv_sec = p->p_realtimer.it_interval.tv_sec; 1690 exp->p_realtimer.it_interval.tv_usec = p->p_realtimer.it_interval.tv_usec; 1691 1692 exp->p_realtimer.it_value.tv_sec = p->p_realtimer.it_value.tv_sec; 1693 exp->p_realtimer.it_value.tv_usec = p->p_realtimer.it_value.tv_usec; 1694 1695 exp->p_rtime.tv_sec = p->p_rtime.tv_sec; 1696 exp->p_rtime.tv_usec = p->p_rtime.tv_usec; 1697 1698 exp->p_sigignore = p->p_sigignore; 1699 exp->p_sigcatch = p->p_sigcatch; 1700 exp->p_priority = p->p_priority; 1701 exp->p_nice = p->p_nice; 1702 bcopy(&p->p_comm, &exp->p_comm, MAXCOMLEN); 1703 exp->p_xstat = p->p_xstat; 1704 exp->p_acflag = p->p_acflag; 1705} 1706 1707STATIC void 1708fill_user32_proc(proc_t p, struct user32_kinfo_proc *__restrict kp) 1709{ 1710 /* on a 64 bit kernel, 32 bit users get some truncated information */ 1711 fill_user32_externproc(p, &kp->kp_proc); 1712 fill_user32_eproc(p, &kp->kp_eproc); 1713} 1714 1715STATIC void 1716fill_user64_proc(proc_t p, struct user64_kinfo_proc *__restrict kp) 1717{ 1718 fill_user64_externproc(p, &kp->kp_proc); 1719 fill_user64_eproc(p, &kp->kp_eproc); 1720} 1721 1722STATIC int 1723sysctl_kdebug_ops SYSCTL_HANDLER_ARGS 1724{ 1725 __unused int cmd = oidp->oid_arg2; /* subcommand*/ 1726 int *name = arg1; /* oid element argument vector */ 1727 int namelen = arg2; /* number of oid element arguments */ 1728 user_addr_t oldp = req->oldptr; /* user buffer copy out address */ 1729 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */ 1730// user_addr_t newp = req->newptr; /* user buffer copy in address */ 1731// size_t newlen = req->newlen; /* user buffer copy in size */ 1732 1733 proc_t p = current_proc(); 1734 int ret=0; 1735 1736 if (namelen == 0) 1737 return(ENOTSUP); 1738 1739 ret = suser(kauth_cred_get(), &p->p_acflag); 1740 if (ret) 1741 return(ret); 1742 1743 switch(name[0]) { 1744 case KERN_KDEFLAGS: 1745 case KERN_KDDFLAGS: 1746 case KERN_KDENABLE: 1747 case KERN_KDGETBUF: 1748 case KERN_KDSETUP: 1749 case KERN_KDREMOVE: 1750 case KERN_KDSETREG: 1751 case KERN_KDGETREG: 1752 case KERN_KDREADTR: 1753 case KERN_KDWRITETR: 1754 case KERN_KDWRITEMAP: 1755 case KERN_KDPIDTR: 1756 case KERN_KDTHRMAP: 1757 case KERN_KDPIDEX: 1758 case KERN_KDSETRTCDEC: 1759 case KERN_KDSETBUF: 1760 case KERN_KDGETENTROPY: 1761 case KERN_KDENABLE_BG_TRACE: 1762 case KERN_KDDISABLE_BG_TRACE: 1763 case KERN_KDSET_TYPEFILTER: 1764 1765 ret = kdbg_control(name, namelen, oldp, oldlenp); 1766 break; 1767 default: 1768 ret= ENOTSUP; 1769 break; 1770 } 1771 1772 /* adjust index so we return the right required/consumed amount */ 1773 if (!ret) 1774 req->oldidx += req->oldlen; 1775 1776 return (ret); 1777} 1778SYSCTL_PROC(_kern, KERN_KDEBUG, kdebug, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 1779 0, /* Pointer argument (arg1) */ 1780 0, /* Integer argument (arg2) */ 1781 sysctl_kdebug_ops, /* Handler function */ 1782 NULL, /* Data pointer */ 1783 ""); 1784 1785 1786#if !CONFIG_EMBEDDED 1787/* 1788 * Return the top *sizep bytes of the user stack, or the entire area of the 1789 * user stack down through the saved exec_path, whichever is smaller. 1790 */ 1791STATIC int 1792sysctl_doprocargs SYSCTL_HANDLER_ARGS 1793{ 1794 __unused int cmd = oidp->oid_arg2; /* subcommand*/ 1795 int *name = arg1; /* oid element argument vector */ 1796 int namelen = arg2; /* number of oid element arguments */ 1797 user_addr_t oldp = req->oldptr; /* user buffer copy out address */ 1798 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */ 1799// user_addr_t newp = req->newptr; /* user buffer copy in address */ 1800// size_t newlen = req->newlen; /* user buffer copy in size */ 1801 int error; 1802 1803 error = sysctl_procargsx( name, namelen, oldp, oldlenp, current_proc(), 0); 1804 1805 /* adjust index so we return the right required/consumed amount */ 1806 if (!error) 1807 req->oldidx += req->oldlen; 1808 1809 return (error); 1810} 1811SYSCTL_PROC(_kern, KERN_PROCARGS, procargs, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 1812 0, /* Pointer argument (arg1) */ 1813 0, /* Integer argument (arg2) */ 1814 sysctl_doprocargs, /* Handler function */ 1815 NULL, /* Data pointer */ 1816 ""); 1817#endif /* !CONFIG_EMBEDDED */ 1818 1819STATIC int 1820sysctl_doprocargs2 SYSCTL_HANDLER_ARGS 1821{ 1822 __unused int cmd = oidp->oid_arg2; /* subcommand*/ 1823 int *name = arg1; /* oid element argument vector */ 1824 int namelen = arg2; /* number of oid element arguments */ 1825 user_addr_t oldp = req->oldptr; /* user buffer copy out address */ 1826 size_t *oldlenp = &req->oldlen; /* user buffer copy out size */ 1827// user_addr_t newp = req->newptr; /* user buffer copy in address */ 1828// size_t newlen = req->newlen; /* user buffer copy in size */ 1829 int error; 1830 1831 error = sysctl_procargsx( name, namelen, oldp, oldlenp, current_proc(), 1); 1832 1833 /* adjust index so we return the right required/consumed amount */ 1834 if (!error) 1835 req->oldidx += req->oldlen; 1836 1837 return (error); 1838} 1839SYSCTL_PROC(_kern, KERN_PROCARGS2, procargs2, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 1840 0, /* Pointer argument (arg1) */ 1841 0, /* Integer argument (arg2) */ 1842 sysctl_doprocargs2, /* Handler function */ 1843 NULL, /* Data pointer */ 1844 ""); 1845 1846STATIC int 1847sysctl_procargsx(int *name, u_int namelen, user_addr_t where, 1848 size_t *sizep, proc_t cur_proc, int argc_yes) 1849{ 1850 proc_t p; 1851 int buflen = where != USER_ADDR_NULL ? *sizep : 0; 1852 int error = 0; 1853 struct _vm_map *proc_map; 1854 struct task * task; 1855 vm_map_copy_t tmp; 1856 user_addr_t arg_addr; 1857 size_t arg_size; 1858 caddr_t data; 1859 size_t argslen=0; 1860 int size; 1861 vm_offset_t copy_start, copy_end; 1862 kern_return_t ret; 1863 int pid; 1864 kauth_cred_t my_cred; 1865 uid_t uid; 1866 1867 if ( namelen < 1 ) 1868 return(EINVAL); 1869 1870 if (argc_yes) 1871 buflen -= sizeof(int); /* reserve first word to return argc */ 1872 1873 /* we only care about buflen when where (oldp from sysctl) is not NULL. */ 1874 /* when where (oldp from sysctl) is NULL and sizep (oldlenp from sysctl */ 1875 /* is not NULL then the caller wants us to return the length needed to */ 1876 /* hold the data we would return */ 1877 if (where != USER_ADDR_NULL && (buflen <= 0 || buflen > ARG_MAX)) { 1878 return(EINVAL); 1879 } 1880 arg_size = buflen; 1881 1882 /* 1883 * Lookup process by pid 1884 */ 1885 pid = name[0]; 1886 p = proc_find(pid); 1887 if (p == NULL) { 1888 return(EINVAL); 1889 } 1890 1891 /* 1892 * Copy the top N bytes of the stack. 1893 * On all machines we have so far, the stack grows 1894 * downwards. 1895 * 1896 * If the user expects no more than N bytes of 1897 * argument list, use that as a guess for the 1898 * size. 1899 */ 1900 1901 if (!p->user_stack) { 1902 proc_rele(p); 1903 return(EINVAL); 1904 } 1905 1906 if (where == USER_ADDR_NULL) { 1907 /* caller only wants to know length of proc args data */ 1908 if (sizep == NULL) { 1909 proc_rele(p); 1910 return(EFAULT); 1911 } 1912 1913 size = p->p_argslen; 1914 proc_rele(p); 1915 if (argc_yes) { 1916 size += sizeof(int); 1917 } 1918 else { 1919 /* 1920 * old PROCARGS will return the executable's path and plus some 1921 * extra space for work alignment and data tags 1922 */ 1923 size += PATH_MAX + (6 * sizeof(int)); 1924 } 1925 size += (size & (sizeof(int) - 1)) ? (sizeof(int) - (size & (sizeof(int) - 1))) : 0; 1926 *sizep = size; 1927 return (0); 1928 } 1929 1930 my_cred = kauth_cred_proc_ref(p); 1931 uid = kauth_cred_getuid(my_cred); 1932 kauth_cred_unref(&my_cred); 1933 1934 if ((uid != kauth_cred_getuid(kauth_cred_get())) 1935 && suser(kauth_cred_get(), &cur_proc->p_acflag)) { 1936 proc_rele(p); 1937 return (EINVAL); 1938 } 1939 1940 if ((u_int)arg_size > p->p_argslen) 1941 arg_size = round_page(p->p_argslen); 1942 1943 arg_addr = p->user_stack - arg_size; 1944 1945 1946 /* 1947 * Before we can block (any VM code), make another 1948 * reference to the map to keep it alive. We do 1949 * that by getting a reference on the task itself. 1950 */ 1951 task = p->task; 1952 if (task == NULL) { 1953 proc_rele(p); 1954 return(EINVAL); 1955 } 1956 1957 argslen = p->p_argslen; 1958 /* 1959 * Once we have a task reference we can convert that into a 1960 * map reference, which we will use in the calls below. The 1961 * task/process may change its map after we take this reference 1962 * (see execve), but the worst that will happen then is a return 1963 * of stale info (which is always a possibility). 1964 */ 1965 task_reference(task); 1966 proc_rele(p); 1967 proc_map = get_task_map_reference(task); 1968 task_deallocate(task); 1969 1970 if (proc_map == NULL) 1971 return(EINVAL); 1972 1973 1974 ret = kmem_alloc(kernel_map, ©_start, round_page(arg_size)); 1975 if (ret != KERN_SUCCESS) { 1976 vm_map_deallocate(proc_map); 1977 return(ENOMEM); 1978 } 1979 1980 copy_end = round_page(copy_start + arg_size); 1981 1982 if( vm_map_copyin(proc_map, (vm_map_address_t)arg_addr, 1983 (vm_map_size_t)arg_size, FALSE, &tmp) != KERN_SUCCESS) { 1984 vm_map_deallocate(proc_map); 1985 kmem_free(kernel_map, copy_start, 1986 round_page(arg_size)); 1987 return (EIO); 1988 } 1989 1990 /* 1991 * Now that we've done the copyin from the process' 1992 * map, we can release the reference to it. 1993 */ 1994 vm_map_deallocate(proc_map); 1995 1996 if( vm_map_copy_overwrite(kernel_map, 1997 (vm_map_address_t)copy_start, 1998 tmp, FALSE) != KERN_SUCCESS) { 1999 kmem_free(kernel_map, copy_start, 2000 round_page(arg_size)); 2001 return (EIO); 2002 } 2003 2004 if (arg_size > argslen) { 2005 data = (caddr_t) (copy_end - argslen); 2006 size = argslen; 2007 } else { 2008 data = (caddr_t) (copy_end - arg_size); 2009 size = arg_size; 2010 } 2011 2012 if (argc_yes) { 2013 /* Put processes argc as the first word in the copyout buffer */ 2014 suword(where, p->p_argc); 2015 error = copyout(data, (where + sizeof(int)), size); 2016 size += sizeof(int); 2017 } else { 2018 error = copyout(data, where, size); 2019 2020 /* 2021 * Make the old PROCARGS work to return the executable's path 2022 * But, only if there is enough space in the provided buffer 2023 * 2024 * on entry: data [possibily] points to the beginning of the path 2025 * 2026 * Note: we keep all pointers&sizes aligned to word boundries 2027 */ 2028 if ( (! error) && (buflen > 0 && (u_int)buflen > argslen) ) 2029 { 2030 int binPath_sz, alignedBinPath_sz = 0; 2031 int extraSpaceNeeded, addThis; 2032 user_addr_t placeHere; 2033 char * str = (char *) data; 2034 int max_len = size; 2035 2036 /* Some apps are really bad about messing up their stacks 2037 So, we have to be extra careful about getting the length 2038 of the executing binary. If we encounter an error, we bail. 2039 */ 2040 2041 /* Limit ourselves to PATH_MAX paths */ 2042 if ( max_len > PATH_MAX ) max_len = PATH_MAX; 2043 2044 binPath_sz = 0; 2045 2046 while ( (binPath_sz < max_len-1) && (*str++ != 0) ) 2047 binPath_sz++; 2048 2049 /* If we have a NUL terminator, copy it, too */ 2050 if (binPath_sz < max_len-1) binPath_sz += 1; 2051 2052 /* Pre-Flight the space requiremnts */ 2053 2054 /* Account for the padding that fills out binPath to the next word */ 2055 alignedBinPath_sz += (binPath_sz & (sizeof(int)-1)) ? (sizeof(int)-(binPath_sz & (sizeof(int)-1))) : 0; 2056 2057 placeHere = where + size; 2058 2059 /* Account for the bytes needed to keep placeHere word aligned */ 2060 addThis = (placeHere & (sizeof(int)-1)) ? (sizeof(int)-(placeHere & (sizeof(int)-1))) : 0; 2061 2062 /* Add up all the space that is needed */ 2063 extraSpaceNeeded = alignedBinPath_sz + addThis + binPath_sz + (4 * sizeof(int)); 2064 2065 /* is there is room to tack on argv[0]? */ 2066 if ( (buflen & ~(sizeof(int)-1)) >= ( argslen + extraSpaceNeeded )) 2067 { 2068 placeHere += addThis; 2069 suword(placeHere, 0); 2070 placeHere += sizeof(int); 2071 suword(placeHere, 0xBFFF0000); 2072 placeHere += sizeof(int); 2073 suword(placeHere, 0); 2074 placeHere += sizeof(int); 2075 error = copyout(data, placeHere, binPath_sz); 2076 if ( ! error ) 2077 { 2078 placeHere += binPath_sz; 2079 suword(placeHere, 0); 2080 size += extraSpaceNeeded; 2081 } 2082 } 2083 } 2084 } 2085 2086 if (copy_start != (vm_offset_t) 0) { 2087 kmem_free(kernel_map, copy_start, copy_end - copy_start); 2088 } 2089 if (error) { 2090 return(error); 2091 } 2092 2093 if (where != USER_ADDR_NULL) 2094 *sizep = size; 2095 return (0); 2096} 2097 2098 2099/* 2100 * Max number of concurrent aio requests 2101 */ 2102STATIC int 2103sysctl_aiomax 2104(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2105{ 2106 int new_value, changed; 2107 int error = sysctl_io_number(req, aio_max_requests, sizeof(int), &new_value, &changed); 2108 if (changed) { 2109 /* make sure the system-wide limit is greater than the per process limit */ 2110 if (new_value >= aio_max_requests_per_process && new_value <= AIO_MAX_REQUESTS) 2111 aio_max_requests = new_value; 2112 else 2113 error = EINVAL; 2114 } 2115 return(error); 2116} 2117 2118 2119/* 2120 * Max number of concurrent aio requests per process 2121 */ 2122STATIC int 2123sysctl_aioprocmax 2124(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2125{ 2126 int new_value, changed; 2127 int error = sysctl_io_number(req, aio_max_requests_per_process, sizeof(int), &new_value, &changed); 2128 if (changed) { 2129 /* make sure per process limit is less than the system-wide limit */ 2130 if (new_value <= aio_max_requests && new_value >= AIO_LISTIO_MAX) 2131 aio_max_requests_per_process = new_value; 2132 else 2133 error = EINVAL; 2134 } 2135 return(error); 2136} 2137 2138 2139/* 2140 * Max number of async IO worker threads 2141 */ 2142STATIC int 2143sysctl_aiothreads 2144(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2145{ 2146 int new_value, changed; 2147 int error = sysctl_io_number(req, aio_worker_threads, sizeof(int), &new_value, &changed); 2148 if (changed) { 2149 /* we only allow an increase in the number of worker threads */ 2150 if (new_value > aio_worker_threads ) { 2151 _aio_create_worker_threads((new_value - aio_worker_threads)); 2152 aio_worker_threads = new_value; 2153 } 2154 else 2155 error = EINVAL; 2156 } 2157 return(error); 2158} 2159 2160 2161/* 2162 * System-wide limit on the max number of processes 2163 */ 2164STATIC int 2165sysctl_maxproc 2166(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2167{ 2168 int new_value, changed; 2169 int error = sysctl_io_number(req, maxproc, sizeof(int), &new_value, &changed); 2170 if (changed) { 2171 AUDIT_ARG(value32, new_value); 2172 /* make sure the system-wide limit is less than the configured hard 2173 limit set at kernel compilation */ 2174 if (new_value <= hard_maxproc && new_value > 0) 2175 maxproc = new_value; 2176 else 2177 error = EINVAL; 2178 } 2179 return(error); 2180} 2181 2182SYSCTL_STRING(_kern, KERN_OSTYPE, ostype, 2183 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 2184 ostype, 0, ""); 2185SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease, 2186 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 2187 osrelease, 0, ""); 2188SYSCTL_INT(_kern, KERN_OSREV, osrevision, 2189 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 2190 (int *)NULL, BSD, ""); 2191SYSCTL_STRING(_kern, KERN_VERSION, version, 2192 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 2193 version, 0, ""); 2194SYSCTL_STRING(_kern, OID_AUTO, uuid, 2195 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 2196 &kernel_uuid[0], 0, ""); 2197 2198#if DEBUG 2199int debug_kprint_syscall = 0; 2200char debug_kprint_syscall_process[MAXCOMLEN+1]; 2201 2202/* Thread safe: bits and string value are not used to reclaim state */ 2203SYSCTL_INT (_debug, OID_AUTO, kprint_syscall, 2204 CTLFLAG_RW | CTLFLAG_LOCKED, &debug_kprint_syscall, 0, "kprintf syscall tracing"); 2205SYSCTL_STRING(_debug, OID_AUTO, kprint_syscall_process, 2206 CTLFLAG_RW | CTLFLAG_LOCKED, debug_kprint_syscall_process, sizeof(debug_kprint_syscall_process), 2207 "name of process for kprintf syscall tracing"); 2208 2209int debug_kprint_current_process(const char **namep) 2210{ 2211 struct proc *p = current_proc(); 2212 2213 if (p == NULL) { 2214 return 0; 2215 } 2216 2217 if (debug_kprint_syscall_process[0]) { 2218 /* user asked to scope tracing to a particular process name */ 2219 if(0 == strncmp(debug_kprint_syscall_process, 2220 p->p_comm, sizeof(debug_kprint_syscall_process))) { 2221 /* no value in telling the user that we traced what they asked */ 2222 if(namep) *namep = NULL; 2223 2224 return 1; 2225 } else { 2226 return 0; 2227 } 2228 } 2229 2230 /* trace all processes. Tell user what we traced */ 2231 if (namep) { 2232 *namep = p->p_comm; 2233 } 2234 2235 return 1; 2236} 2237#endif 2238 2239/* PR-5293665: need to use a callback function for kern.osversion to set 2240 * osversion in IORegistry */ 2241 2242STATIC int 2243sysctl_osversion(__unused struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req) 2244{ 2245 int rval = 0; 2246 2247 rval = sysctl_handle_string(oidp, arg1, arg2, req); 2248 2249 if (req->newptr) { 2250 IORegistrySetOSBuildVersion((char *)arg1); 2251 } 2252 2253 return rval; 2254} 2255 2256SYSCTL_PROC(_kern, KERN_OSVERSION, osversion, 2257 CTLFLAG_RW | CTLFLAG_KERN | CTLTYPE_STRING | CTLFLAG_LOCKED, 2258 osversion, 256 /* OSVERSIZE*/, 2259 sysctl_osversion, "A", ""); 2260 2261STATIC int 2262sysctl_sysctl_bootargs 2263(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2264{ 2265 int error; 2266 char buf[256]; 2267 2268 strlcpy(buf, PE_boot_args(), 256); 2269 error = sysctl_io_string(req, buf, 256, 0, NULL); 2270 return(error); 2271} 2272 2273SYSCTL_PROC(_kern, OID_AUTO, bootargs, 2274 CTLFLAG_LOCKED | CTLFLAG_RD | CTLFLAG_KERN | CTLTYPE_STRING, 2275 NULL, 0, 2276 sysctl_sysctl_bootargs, "A", "bootargs"); 2277 2278SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, 2279 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2280 &maxfiles, 0, ""); 2281SYSCTL_INT(_kern, KERN_ARGMAX, argmax, 2282 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 2283 (int *)NULL, ARG_MAX, ""); 2284SYSCTL_INT(_kern, KERN_POSIX1, posix1version, 2285 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 2286 (int *)NULL, _POSIX_VERSION, ""); 2287SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, 2288 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 2289 (int *)NULL, NGROUPS_MAX, ""); 2290SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control, 2291 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 2292 (int *)NULL, 1, ""); 2293#if 1 /* _POSIX_SAVED_IDS from <unistd.h> */ 2294SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, 2295 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 2296 (int *)NULL, 1, ""); 2297#else 2298SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, 2299 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 2300 NULL, 0, ""); 2301#endif 2302SYSCTL_INT(_kern, OID_AUTO, num_files, 2303 CTLFLAG_RD | CTLFLAG_LOCKED, 2304 &nfiles, 0, ""); 2305SYSCTL_COMPAT_INT(_kern, OID_AUTO, num_vnodes, 2306 CTLFLAG_RD | CTLFLAG_LOCKED, 2307 &numvnodes, 0, ""); 2308SYSCTL_INT(_kern, OID_AUTO, num_tasks, 2309 CTLFLAG_RD | CTLFLAG_LOCKED, 2310 &task_max, 0, ""); 2311SYSCTL_INT(_kern, OID_AUTO, num_threads, 2312 CTLFLAG_RD | CTLFLAG_LOCKED, 2313 &thread_max, 0, ""); 2314SYSCTL_INT(_kern, OID_AUTO, num_taskthreads, 2315 CTLFLAG_RD | CTLFLAG_LOCKED, 2316 &task_threadmax, 0, ""); 2317 2318STATIC int 2319sysctl_maxvnodes (__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2320{ 2321 int oldval = desiredvnodes; 2322 int error = sysctl_io_number(req, desiredvnodes, sizeof(int), &desiredvnodes, NULL); 2323 2324 if (oldval != desiredvnodes) { 2325 reset_vmobjectcache(oldval, desiredvnodes); 2326 resize_namecache(desiredvnodes); 2327 } 2328 2329 return(error); 2330} 2331 2332SYSCTL_INT(_kern, OID_AUTO, namecache_disabled, 2333 CTLFLAG_RW | CTLFLAG_LOCKED, 2334 &nc_disabled, 0, ""); 2335 2336SYSCTL_PROC(_kern, KERN_MAXVNODES, maxvnodes, 2337 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 2338 0, 0, sysctl_maxvnodes, "I", ""); 2339 2340SYSCTL_PROC(_kern, KERN_MAXPROC, maxproc, 2341 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 2342 0, 0, sysctl_maxproc, "I", ""); 2343 2344SYSCTL_PROC(_kern, KERN_AIOMAX, aiomax, 2345 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 2346 0, 0, sysctl_aiomax, "I", ""); 2347 2348SYSCTL_PROC(_kern, KERN_AIOPROCMAX, aioprocmax, 2349 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 2350 0, 0, sysctl_aioprocmax, "I", ""); 2351 2352SYSCTL_PROC(_kern, KERN_AIOTHREADS, aiothreads, 2353 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 2354 0, 0, sysctl_aiothreads, "I", ""); 2355 2356STATIC int 2357sysctl_securelvl 2358(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2359{ 2360 int new_value, changed; 2361 int error = sysctl_io_number(req, securelevel, sizeof(int), &new_value, &changed); 2362 if (changed) { 2363 if (!(new_value < securelevel && req->p->p_pid != 1)) { 2364 proc_list_lock(); 2365 securelevel = new_value; 2366 proc_list_unlock(); 2367 } else { 2368 error = EPERM; 2369 } 2370 } 2371 return(error); 2372} 2373 2374SYSCTL_PROC(_kern, KERN_SECURELVL, securelevel, 2375 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 2376 0, 0, sysctl_securelvl, "I", ""); 2377 2378 2379STATIC int 2380sysctl_domainname 2381(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2382{ 2383 int error, changed; 2384 error = sysctl_io_string(req, domainname, sizeof(domainname), 0, &changed); 2385 if (changed) { 2386 domainnamelen = strlen(domainname); 2387 } 2388 return(error); 2389} 2390 2391SYSCTL_PROC(_kern, KERN_DOMAINNAME, nisdomainname, 2392 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED, 2393 0, 0, sysctl_domainname, "A", ""); 2394 2395SYSCTL_COMPAT_INT(_kern, KERN_HOSTID, hostid, 2396 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2397 &hostid, 0, ""); 2398 2399STATIC int 2400sysctl_hostname 2401(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2402{ 2403 int error, changed; 2404 error = sysctl_io_string(req, hostname, sizeof(hostname), 1, &changed); 2405 if (changed) { 2406 hostnamelen = req->newlen; 2407 } 2408 return(error); 2409} 2410 2411 2412SYSCTL_PROC(_kern, KERN_HOSTNAME, hostname, 2413 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED, 2414 0, 0, sysctl_hostname, "A", ""); 2415 2416STATIC int 2417sysctl_procname 2418(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2419{ 2420 /* Original code allowed writing, I'm copying this, although this all makes 2421 no sense to me. Besides, this sysctl is never used. */ 2422 return sysctl_io_string(req, &req->p->p_name[0], (2*MAXCOMLEN+1), 1, NULL); 2423} 2424 2425SYSCTL_PROC(_kern, KERN_PROCNAME, procname, 2426 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED, 2427 0, 0, sysctl_procname, "A", ""); 2428 2429SYSCTL_INT(_kern, KERN_SPECULATIVE_READS, speculative_reads_disabled, 2430 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2431 &speculative_reads_disabled, 0, ""); 2432 2433SYSCTL_INT(_kern, OID_AUTO, ignore_is_ssd, 2434 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2435 &ignore_is_ssd, 0, ""); 2436 2437SYSCTL_UINT(_kern, OID_AUTO, preheat_pages_max, 2438 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2439 &preheat_pages_max, 0, ""); 2440 2441SYSCTL_UINT(_kern, OID_AUTO, preheat_pages_min, 2442 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2443 &preheat_pages_min, 0, ""); 2444 2445SYSCTL_UINT(_kern, OID_AUTO, speculative_prefetch_max, 2446 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2447 &speculative_prefetch_max, 0, ""); 2448 2449SYSCTL_UINT(_kern, OID_AUTO, speculative_prefetch_max_iosize, 2450 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2451 &speculative_prefetch_max_iosize, 0, ""); 2452 2453SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_target, 2454 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2455 &vm_page_free_target, 0, ""); 2456 2457SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_min, 2458 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2459 &vm_page_free_min, 0, ""); 2460 2461SYSCTL_UINT(_kern, OID_AUTO, vm_page_free_reserved, 2462 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2463 &vm_page_free_reserved, 0, ""); 2464 2465SYSCTL_UINT(_kern, OID_AUTO, vm_page_speculative_percentage, 2466 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2467 &vm_page_speculative_percentage, 0, ""); 2468 2469SYSCTL_UINT(_kern, OID_AUTO, vm_page_speculative_q_age_ms, 2470 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2471 &vm_page_speculative_q_age_ms, 0, ""); 2472 2473SYSCTL_UINT(_kern, OID_AUTO, vm_max_delayed_work_limit, 2474 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2475 &vm_max_delayed_work_limit, 0, ""); 2476 2477SYSCTL_UINT(_kern, OID_AUTO, vm_max_batch, 2478 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2479 &vm_max_batch, 0, ""); 2480 2481 2482STATIC int 2483sysctl_boottime 2484(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2485{ 2486 time_t tv_sec = boottime_sec(); 2487 struct proc *p = req->p; 2488 2489 if (proc_is64bit(p)) { 2490 struct user64_timeval t; 2491 t.tv_sec = tv_sec; 2492 t.tv_usec = 0; 2493 return sysctl_io_opaque(req, &t, sizeof(t), NULL); 2494 } else { 2495 struct user32_timeval t; 2496 t.tv_sec = tv_sec; 2497 t.tv_usec = 0; 2498 return sysctl_io_opaque(req, &t, sizeof(t), NULL); 2499 } 2500} 2501 2502SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, 2503 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 2504 0, 0, sysctl_boottime, "S,timeval", ""); 2505 2506STATIC int 2507sysctl_symfile 2508(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2509{ 2510 char *str; 2511 int error = get_kernel_symfile(req->p, &str); 2512 if (error) 2513 return (error); 2514 return sysctl_io_string(req, str, 0, 0, NULL); 2515} 2516 2517 2518SYSCTL_PROC(_kern, KERN_SYMFILE, symfile, 2519 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_LOCKED, 2520 0, 0, sysctl_symfile, "A", ""); 2521 2522#if NFSCLIENT 2523STATIC int 2524sysctl_netboot 2525(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2526{ 2527 return sysctl_io_number(req, netboot_root(), sizeof(int), NULL, NULL); 2528} 2529 2530SYSCTL_PROC(_kern, KERN_NETBOOT, netboot, 2531 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, 2532 0, 0, sysctl_netboot, "I", ""); 2533#endif 2534 2535#ifdef CONFIG_IMGSRC_ACCESS 2536/* 2537 * Legacy--act as if only one layer of nesting is possible. 2538 */ 2539STATIC int 2540sysctl_imgsrcdev 2541(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2542{ 2543 vfs_context_t ctx = vfs_context_current(); 2544 vnode_t devvp; 2545 int result; 2546 2547 if (!vfs_context_issuser(ctx)) { 2548 return EPERM; 2549 } 2550 2551 if (imgsrc_rootvnodes[0] == NULL) { 2552 return ENOENT; 2553 } 2554 2555 result = vnode_getwithref(imgsrc_rootvnodes[0]); 2556 if (result != 0) { 2557 return result; 2558 } 2559 2560 devvp = vnode_mount(imgsrc_rootvnodes[0])->mnt_devvp; 2561 result = vnode_getwithref(devvp); 2562 if (result != 0) { 2563 goto out; 2564 } 2565 2566 result = sysctl_io_number(req, vnode_specrdev(devvp), sizeof(dev_t), NULL, NULL); 2567 2568 vnode_put(devvp); 2569out: 2570 vnode_put(imgsrc_rootvnodes[0]); 2571 return result; 2572} 2573 2574SYSCTL_PROC(_kern, OID_AUTO, imgsrcdev, 2575 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, 2576 0, 0, sysctl_imgsrcdev, "I", ""); 2577 2578STATIC int 2579sysctl_imgsrcinfo 2580(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2581{ 2582 int error; 2583 struct imgsrc_info info[MAX_IMAGEBOOT_NESTING]; /* 2 for now, no problem */ 2584 uint32_t i; 2585 vnode_t rvp, devvp; 2586 2587 if (imgsrc_rootvnodes[0] == NULLVP) { 2588 return ENXIO; 2589 } 2590 2591 for (i = 0; i < MAX_IMAGEBOOT_NESTING; i++) { 2592 /* 2593 * Go get the root vnode. 2594 */ 2595 rvp = imgsrc_rootvnodes[i]; 2596 if (rvp == NULLVP) { 2597 break; 2598 } 2599 2600 error = vnode_get(rvp); 2601 if (error != 0) { 2602 return error; 2603 } 2604 2605 /* 2606 * For now, no getting at a non-local volume. 2607 */ 2608 devvp = vnode_mount(rvp)->mnt_devvp; 2609 if (devvp == NULL) { 2610 vnode_put(rvp); 2611 return EINVAL; 2612 } 2613 2614 error = vnode_getwithref(devvp); 2615 if (error != 0) { 2616 vnode_put(rvp); 2617 return error; 2618 } 2619 2620 /* 2621 * Fill in info. 2622 */ 2623 info[i].ii_dev = vnode_specrdev(devvp); 2624 info[i].ii_flags = 0; 2625 info[i].ii_height = i; 2626 bzero(info[i].ii_reserved, sizeof(info[i].ii_reserved)); 2627 2628 vnode_put(devvp); 2629 vnode_put(rvp); 2630 } 2631 2632 return sysctl_io_opaque(req, info, i * sizeof(info[0]), NULL); 2633} 2634 2635SYSCTL_PROC(_kern, OID_AUTO, imgsrcinfo, 2636 CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_LOCKED, 2637 0, 0, sysctl_imgsrcinfo, "I", ""); 2638 2639#endif /* CONFIG_IMGSRC_ACCESS */ 2640 2641SYSCTL_INT(_kern, OID_AUTO, timer_coalescing_enabled, 2642 CTLFLAG_RW | CTLFLAG_LOCKED, 2643 &mach_timer_coalescing_enabled, 0, ""); 2644 2645STATIC int 2646sysctl_usrstack 2647(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2648{ 2649 return sysctl_io_number(req, (int)req->p->user_stack, sizeof(int), NULL, NULL); 2650} 2651 2652SYSCTL_PROC(_kern, KERN_USRSTACK32, usrstack, 2653 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, 2654 0, 0, sysctl_usrstack, "I", ""); 2655 2656STATIC int 2657sysctl_usrstack64 2658(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2659{ 2660 return sysctl_io_number(req, req->p->user_stack, sizeof(req->p->user_stack), NULL, NULL); 2661} 2662 2663SYSCTL_PROC(_kern, KERN_USRSTACK64, usrstack64, 2664 CTLTYPE_QUAD | CTLFLAG_RD | CTLFLAG_LOCKED, 2665 0, 0, sysctl_usrstack64, "Q", ""); 2666 2667SYSCTL_STRING(_kern, KERN_COREFILE, corefile, 2668 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2669 corefilename, sizeof(corefilename), ""); 2670 2671STATIC int 2672sysctl_coredump 2673(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2674{ 2675#ifdef SECURE_KERNEL 2676 return (ENOTSUP); 2677#endif 2678 int new_value, changed; 2679 int error = sysctl_io_number(req, do_coredump, sizeof(int), &new_value, &changed); 2680 if (changed) { 2681 if ((new_value == 0) || (new_value == 1)) 2682 do_coredump = new_value; 2683 else 2684 error = EINVAL; 2685 } 2686 return(error); 2687} 2688 2689SYSCTL_PROC(_kern, KERN_COREDUMP, coredump, 2690 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 2691 0, 0, sysctl_coredump, "I", ""); 2692 2693STATIC int 2694sysctl_suid_coredump 2695(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2696{ 2697#ifdef SECURE_KERNEL 2698 return (ENOTSUP); 2699#endif 2700 int new_value, changed; 2701 int error = sysctl_io_number(req, sugid_coredump, sizeof(int), &new_value, &changed); 2702 if (changed) { 2703 if ((new_value == 0) || (new_value == 1)) 2704 sugid_coredump = new_value; 2705 else 2706 error = EINVAL; 2707 } 2708 return(error); 2709} 2710 2711SYSCTL_PROC(_kern, KERN_SUGID_COREDUMP, sugid_coredump, 2712 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 2713 0, 0, sysctl_suid_coredump, "I", ""); 2714 2715STATIC int 2716sysctl_delayterm 2717(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2718{ 2719 struct proc *p = req->p; 2720 int new_value, changed; 2721 int error = sysctl_io_number(req, (req->p->p_lflag & P_LDELAYTERM)? 1: 0, sizeof(int), &new_value, &changed); 2722 if (changed) { 2723 proc_lock(p); 2724 if (new_value) 2725 req->p->p_lflag |= P_LDELAYTERM; 2726 else 2727 req->p->p_lflag &= ~P_LDELAYTERM; 2728 proc_unlock(p); 2729 } 2730 return(error); 2731} 2732 2733SYSCTL_PROC(_kern, KERN_PROCDELAYTERM, delayterm, 2734 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 2735 0, 0, sysctl_delayterm, "I", ""); 2736 2737 2738STATIC int 2739sysctl_rage_vnode 2740(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2741{ 2742 struct proc *p = req->p; 2743 struct uthread *ut; 2744 int new_value, old_value, changed; 2745 int error; 2746 2747 ut = get_bsdthread_info(current_thread()); 2748 2749 if (ut->uu_flag & UT_RAGE_VNODES) 2750 old_value = KERN_RAGE_THREAD; 2751 else if (p->p_lflag & P_LRAGE_VNODES) 2752 old_value = KERN_RAGE_PROC; 2753 else 2754 old_value = 0; 2755 2756 error = sysctl_io_number(req, old_value, sizeof(int), &new_value, &changed); 2757 2758 if (error == 0) { 2759 switch (new_value) { 2760 case KERN_RAGE_PROC: 2761 proc_lock(p); 2762 p->p_lflag |= P_LRAGE_VNODES; 2763 proc_unlock(p); 2764 break; 2765 case KERN_UNRAGE_PROC: 2766 proc_lock(p); 2767 p->p_lflag &= ~P_LRAGE_VNODES; 2768 proc_unlock(p); 2769 break; 2770 2771 case KERN_RAGE_THREAD: 2772 ut->uu_flag |= UT_RAGE_VNODES; 2773 break; 2774 case KERN_UNRAGE_THREAD: 2775 ut = get_bsdthread_info(current_thread()); 2776 ut->uu_flag &= ~UT_RAGE_VNODES; 2777 break; 2778 } 2779 } 2780 return(error); 2781} 2782 2783SYSCTL_PROC(_kern, KERN_RAGEVNODE, rage_vnode, 2784 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED, 2785 0, 0, sysctl_rage_vnode, "I", ""); 2786 2787/* XXX move this interface into libproc and remove this sysctl */ 2788STATIC int 2789sysctl_setthread_cpupercent 2790(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2791{ 2792 int new_value, old_value; 2793 int error = 0; 2794 kern_return_t kret = KERN_SUCCESS; 2795 uint8_t percent = 0; 2796 int ms_refill = 0; 2797 2798 old_value = 0; 2799 2800 if ((error = sysctl_io_number(req, old_value, sizeof(old_value), &new_value, NULL)) != 0) 2801 return (error); 2802 2803 percent = new_value & 0xff; /* low 8 bytes for perent */ 2804 ms_refill = (new_value >> 8) & 0xffffff; /* upper 24bytes represent ms refill value */ 2805 if (percent > 100) 2806 return (EINVAL); 2807 2808 /* 2809 * If the caller is specifying a percentage of 0, this will unset the CPU limit, if present. 2810 */ 2811 if ((kret = thread_set_cpulimit(THREAD_CPULIMIT_BLOCK, percent, ms_refill * NSEC_PER_MSEC)) != 0) 2812 return (EIO); 2813 2814 return (0); 2815} 2816 2817SYSCTL_PROC(_kern, OID_AUTO, setthread_cpupercent, 2818 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, 2819 0, 0, sysctl_setthread_cpupercent, "I", "set thread cpu percentage limit"); 2820 2821 2822STATIC int 2823sysctl_kern_check_openevt 2824(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2825{ 2826 struct proc *p = req->p; 2827 int new_value, old_value, changed; 2828 int error; 2829 2830 if (p->p_flag & P_CHECKOPENEVT) { 2831 old_value = KERN_OPENEVT_PROC; 2832 } else { 2833 old_value = 0; 2834 } 2835 2836 error = sysctl_io_number(req, old_value, sizeof(int), &new_value, &changed); 2837 2838 if (error == 0) { 2839 switch (new_value) { 2840 case KERN_OPENEVT_PROC: 2841 OSBitOrAtomic(P_CHECKOPENEVT, &p->p_flag); 2842 break; 2843 2844 case KERN_UNOPENEVT_PROC: 2845 OSBitAndAtomic(~((uint32_t)P_CHECKOPENEVT), &p->p_flag); 2846 break; 2847 2848 default: 2849 error = EINVAL; 2850 } 2851 } 2852 return(error); 2853} 2854 2855SYSCTL_PROC(_kern, KERN_CHECKOPENEVT, check_openevt, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_LOCKED, 2856 0, 0, sysctl_kern_check_openevt, "I", "set the per-process check-open-evt flag"); 2857 2858 2859 2860STATIC int 2861sysctl_nx 2862(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2863{ 2864#ifdef SECURE_KERNEL 2865 return ENOTSUP; 2866#endif 2867 int new_value, changed; 2868 int error; 2869 2870 error = sysctl_io_number(req, nx_enabled, sizeof(nx_enabled), &new_value, &changed); 2871 if (error) 2872 return error; 2873 2874 if (changed) { 2875#if defined(__i386__) || defined(__x86_64__) 2876 /* 2877 * Only allow setting if NX is supported on the chip 2878 */ 2879 if (!(cpuid_extfeatures() & CPUID_EXTFEATURE_XD)) 2880 return ENOTSUP; 2881#endif 2882 nx_enabled = new_value; 2883 } 2884 return(error); 2885} 2886 2887 2888 2889SYSCTL_PROC(_kern, KERN_NX_PROTECTION, nx, 2890 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 2891 0, 0, sysctl_nx, "I", ""); 2892 2893STATIC int 2894sysctl_loadavg 2895(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2896{ 2897 if (proc_is64bit(req->p)) { 2898 struct user64_loadavg loadinfo64; 2899 fill_loadavg64(&averunnable, &loadinfo64); 2900 return sysctl_io_opaque(req, &loadinfo64, sizeof(loadinfo64), NULL); 2901 } else { 2902 struct user32_loadavg loadinfo32; 2903 fill_loadavg32(&averunnable, &loadinfo32); 2904 return sysctl_io_opaque(req, &loadinfo32, sizeof(loadinfo32), NULL); 2905 } 2906} 2907 2908SYSCTL_PROC(_vm, VM_LOADAVG, loadavg, 2909 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 2910 0, 0, sysctl_loadavg, "S,loadavg", ""); 2911 2912/* 2913 * Note: Thread safe; vm_map_lock protects in vm_toggle_entry_reuse() 2914 */ 2915STATIC int 2916sysctl_vm_toggle_address_reuse(__unused struct sysctl_oid *oidp, __unused void *arg1, 2917 __unused int arg2, struct sysctl_req *req) 2918{ 2919 int old_value=0, new_value=0, error=0; 2920 2921 if(vm_toggle_entry_reuse( VM_TOGGLE_GETVALUE, &old_value )) 2922 return(error); 2923 error = sysctl_io_number(req, old_value, sizeof(int), &new_value, NULL); 2924 if (!error) { 2925 return (vm_toggle_entry_reuse(new_value, NULL)); 2926 } 2927 return(error); 2928} 2929 2930SYSCTL_PROC(_debug, OID_AUTO, toggle_address_reuse, CTLFLAG_ANYBODY | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0, sysctl_vm_toggle_address_reuse,"I",""); 2931 2932STATIC int 2933sysctl_swapusage 2934(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 2935{ 2936 int error; 2937 uint64_t swap_total; 2938 uint64_t swap_avail; 2939 vm_size_t swap_pagesize; 2940 boolean_t swap_encrypted; 2941 struct xsw_usage xsu; 2942 2943 error = macx_swapinfo(&swap_total, 2944 &swap_avail, 2945 &swap_pagesize, 2946 &swap_encrypted); 2947 if (error) 2948 return error; 2949 2950 xsu.xsu_total = swap_total; 2951 xsu.xsu_avail = swap_avail; 2952 xsu.xsu_used = swap_total - swap_avail; 2953 xsu.xsu_pagesize = swap_pagesize; 2954 xsu.xsu_encrypted = swap_encrypted; 2955 return sysctl_io_opaque(req, &xsu, sizeof(xsu), NULL); 2956} 2957 2958 2959 2960SYSCTL_PROC(_vm, VM_SWAPUSAGE, swapusage, 2961 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 2962 0, 0, sysctl_swapusage, "S,xsw_usage", ""); 2963 2964#if CONFIG_FREEZE 2965extern void vm_page_reactivate_all_throttled(void); 2966 2967static int 2968sysctl_freeze_enabled SYSCTL_HANDLER_ARGS 2969{ 2970#pragma unused(arg1, arg2) 2971 int error, val = memorystatus_freeze_enabled ? 1 : 0; 2972 boolean_t disabled; 2973 2974 error = sysctl_handle_int(oidp, &val, 0, req); 2975 if (error || !req->newptr) 2976 return (error); 2977 2978 /* 2979 * If freeze is being disabled, we need to move dirty pages out from the throttle to the active queue. 2980 */ 2981 disabled = (!val && memorystatus_freeze_enabled); 2982 2983 memorystatus_freeze_enabled = val ? TRUE : FALSE; 2984 2985 if (disabled) { 2986 vm_page_reactivate_all_throttled(); 2987 } 2988 2989 return (0); 2990} 2991 2992SYSCTL_PROC(_vm, OID_AUTO, freeze_enabled, CTLTYPE_INT|CTLFLAG_RW, &memorystatus_freeze_enabled, 0, sysctl_freeze_enabled, "I", ""); 2993#endif /* CONFIG_FREEZE */ 2994 2995/* this kernel does NOT implement shared_region_make_private_np() */ 2996SYSCTL_INT(_kern, KERN_SHREG_PRIVATIZABLE, shreg_private, 2997 CTLFLAG_RD | CTLFLAG_LOCKED, 2998 (int *)NULL, 0, ""); 2999 3000#if defined(__i386__) || defined(__x86_64__) 3001STATIC int 3002sysctl_sysctl_exec_affinity(__unused struct sysctl_oid *oidp, 3003 __unused void *arg1, __unused int arg2, 3004 struct sysctl_req *req) 3005{ 3006 proc_t cur_proc = req->p; 3007 int error; 3008 3009 if (req->oldptr != USER_ADDR_NULL) { 3010 cpu_type_t oldcputype = (cur_proc->p_flag & P_AFFINITY) ? CPU_TYPE_POWERPC : CPU_TYPE_I386; 3011 if ((error = SYSCTL_OUT(req, &oldcputype, sizeof(oldcputype)))) 3012 return error; 3013 } 3014 3015 if (req->newptr != USER_ADDR_NULL) { 3016 cpu_type_t newcputype; 3017 if ((error = SYSCTL_IN(req, &newcputype, sizeof(newcputype)))) 3018 return error; 3019 if (newcputype == CPU_TYPE_I386) 3020 OSBitAndAtomic(~((uint32_t)P_AFFINITY), &cur_proc->p_flag); 3021 else if (newcputype == CPU_TYPE_POWERPC) 3022 OSBitOrAtomic(P_AFFINITY, &cur_proc->p_flag); 3023 else 3024 return (EINVAL); 3025 } 3026 3027 return 0; 3028} 3029SYSCTL_PROC(_sysctl, OID_AUTO, proc_exec_affinity, CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY | CTLFLAG_LOCKED, 0, 0, sysctl_sysctl_exec_affinity ,"I","proc_exec_affinity"); 3030#endif 3031 3032STATIC int 3033fetch_process_cputype( 3034 proc_t cur_proc, 3035 int *name, 3036 u_int namelen, 3037 cpu_type_t *cputype) 3038{ 3039 proc_t p = PROC_NULL; 3040 int refheld = 0; 3041 cpu_type_t ret = 0; 3042 int error = 0; 3043 3044 if (namelen == 0) 3045 p = cur_proc; 3046 else if (namelen == 1) { 3047 p = proc_find(name[0]); 3048 if (p == NULL) 3049 return (EINVAL); 3050 refheld = 1; 3051 } else { 3052 error = EINVAL; 3053 goto out; 3054 } 3055 3056#if defined(__i386__) || defined(__x86_64__) 3057 if (p->p_flag & P_TRANSLATED) { 3058 ret = CPU_TYPE_POWERPC; 3059 } 3060 else 3061#endif 3062 { 3063 ret = cpu_type(); 3064 if (IS_64BIT_PROCESS(p)) 3065 ret |= CPU_ARCH_ABI64; 3066 } 3067 *cputype = ret; 3068 3069 if (refheld != 0) 3070 proc_rele(p); 3071out: 3072 return (error); 3073} 3074 3075STATIC int 3076sysctl_sysctl_native(__unused struct sysctl_oid *oidp, void *arg1, int arg2, 3077 struct sysctl_req *req) 3078{ 3079 int error; 3080 cpu_type_t proc_cputype = 0; 3081 if ((error = fetch_process_cputype(req->p, (int *)arg1, arg2, &proc_cputype)) != 0) 3082 return error; 3083 int res = 1; 3084 if ((proc_cputype & ~CPU_ARCH_MASK) != (cpu_type() & ~CPU_ARCH_MASK)) 3085 res = 0; 3086 return SYSCTL_OUT(req, &res, sizeof(res)); 3087} 3088SYSCTL_PROC(_sysctl, OID_AUTO, proc_native, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0, sysctl_sysctl_native ,"I","proc_native"); 3089 3090STATIC int 3091sysctl_sysctl_cputype(__unused struct sysctl_oid *oidp, void *arg1, int arg2, 3092 struct sysctl_req *req) 3093{ 3094 int error; 3095 cpu_type_t proc_cputype = 0; 3096 if ((error = fetch_process_cputype(req->p, (int *)arg1, arg2, &proc_cputype)) != 0) 3097 return error; 3098 return SYSCTL_OUT(req, &proc_cputype, sizeof(proc_cputype)); 3099} 3100SYSCTL_PROC(_sysctl, OID_AUTO, proc_cputype, CTLTYPE_NODE|CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0, sysctl_sysctl_cputype ,"I","proc_cputype"); 3101 3102STATIC int 3103sysctl_safeboot 3104(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 3105{ 3106 return sysctl_io_number(req, boothowto & RB_SAFEBOOT ? 1 : 0, sizeof(int), NULL, NULL); 3107} 3108 3109SYSCTL_PROC(_kern, KERN_SAFEBOOT, safeboot, 3110 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, 3111 0, 0, sysctl_safeboot, "I", ""); 3112 3113STATIC int 3114sysctl_singleuser 3115(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 3116{ 3117 return sysctl_io_number(req, boothowto & RB_SINGLE ? 1 : 0, sizeof(int), NULL, NULL); 3118} 3119 3120SYSCTL_PROC(_kern, OID_AUTO, singleuser, 3121 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, 3122 0, 0, sysctl_singleuser, "I", ""); 3123 3124/* 3125 * Controls for debugging affinity sets - see osfmk/kern/affinity.c 3126 */ 3127extern boolean_t affinity_sets_enabled; 3128extern int affinity_sets_mapping; 3129 3130SYSCTL_INT (_kern, OID_AUTO, affinity_sets_enabled, 3131 CTLFLAG_RW | CTLFLAG_LOCKED, (int *) &affinity_sets_enabled, 0, "hinting enabled"); 3132SYSCTL_INT (_kern, OID_AUTO, affinity_sets_mapping, 3133 CTLFLAG_RW | CTLFLAG_LOCKED, &affinity_sets_mapping, 0, "mapping policy"); 3134 3135/* 3136 * Boolean indicating if KASLR is active. 3137 */ 3138STATIC int 3139sysctl_slide 3140(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req) 3141{ 3142 uint32_t slide; 3143 3144 slide = vm_kernel_slide ? 1 : 0; 3145 3146 return sysctl_io_number( req, slide, sizeof(int), NULL, NULL); 3147} 3148 3149SYSCTL_PROC(_kern, OID_AUTO, slide, 3150 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_LOCKED, 3151 0, 0, sysctl_slide, "I", ""); 3152 3153/* 3154 * Limit on total memory users can wire. 3155 * 3156 * vm_global_user_wire_limit - system wide limit on wired memory from all processes combined. 3157 * 3158 * vm_user_wire_limit - per address space limit on wired memory. This puts a cap on the process's rlimit value. 3159 * 3160 * These values are initialized to reasonable defaults at boot time based on the available physical memory in 3161 * kmem_init(). 3162 * 3163 * All values are in bytes. 3164 */ 3165 3166vm_map_size_t vm_global_no_user_wire_amount; 3167vm_map_size_t vm_global_user_wire_limit; 3168vm_map_size_t vm_user_wire_limit; 3169 3170/* 3171 * There needs to be a more automatic/elegant way to do this 3172 */ 3173 3174extern int vm_map_copy_overwrite_aligned_src_not_internal; 3175extern int vm_map_copy_overwrite_aligned_src_not_symmetric; 3176extern int vm_map_copy_overwrite_aligned_src_large; 3177SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_not_internal, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_not_internal, 0, ""); 3178SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_not_symmetric, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_not_symmetric, 0, ""); 3179SYSCTL_INT(_vm, OID_AUTO, vm_copy_src_large, CTLFLAG_RD | CTLFLAG_LOCKED, &vm_map_copy_overwrite_aligned_src_large, 0, ""); 3180 3181 3182/* 3183 * enable back trace events for thread blocks 3184 */ 3185 3186extern uint32_t kdebug_thread_block; 3187 3188SYSCTL_INT (_kern, OID_AUTO, kdebug_thread_block, 3189 CTLFLAG_RW | CTLFLAG_LOCKED, &kdebug_thread_block, 0, "kdebug thread_block"); 3190 3191/* 3192 * Kernel stack size and depth 3193 */ 3194SYSCTL_INT (_kern, OID_AUTO, stack_size, 3195 CTLFLAG_RD | CTLFLAG_LOCKED, (int *) &kernel_stack_size, 0, "Kernel stack size"); 3196SYSCTL_INT (_kern, OID_AUTO, stack_depth_max, 3197 CTLFLAG_RD | CTLFLAG_LOCKED, (int *) &kernel_stack_depth_max, 0, "Max kernel stack depth at interrupt or context switch"); 3198 3199/* 3200 * enable back trace for port allocations 3201 */ 3202extern int ipc_portbt; 3203 3204SYSCTL_INT(_kern, OID_AUTO, ipc_portbt, 3205 CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED, 3206 &ipc_portbt, 0, ""); 3207 3208/* 3209 * Scheduler sysctls 3210 */ 3211 3212/* 3213 * See osfmk/kern/sched_prim.c for the corresponding definition 3214 * in osfmk/. If either version changes, update the other. 3215 */ 3216#define SCHED_STRING_MAX_LENGTH (48) 3217 3218extern char sched_string[SCHED_STRING_MAX_LENGTH]; 3219SYSCTL_STRING(_kern, OID_AUTO, sched, 3220 CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED, 3221 sched_string, sizeof(sched_string), 3222 "Timeshare scheduler implementation"); 3223 3224/* 3225 * Only support runtime modification on embedded platforms 3226 * with development config enabled 3227 */ 3228#if CONFIG_EMBEDDED 3229#if !SECURE_KERNEL 3230extern int precise_user_kernel_time; 3231SYSCTL_INT(_kern, OID_AUTO, precise_user_kernel_time, 3232 CTLFLAG_RW | CTLFLAG_LOCKED, 3233 &precise_user_kernel_time, 0, "Precise accounting of kernel vs. user time"); 3234#endif 3235#endif 3236