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