1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1982, 1986, 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Mike Karels at Berkeley Software Design, Inc. 9 * 10 * Quite extensively rewritten by Poul-Henning Kamp of the FreeBSD 11 * project, to make these variables more userfriendly. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94 38 */ 39 40 #include <sys/cdefs.h> 41 #include "opt_capsicum.h" 42 #include "opt_ddb.h" 43 #include "opt_ktrace.h" 44 #include "opt_sysctl.h" 45 46 #include <sys/param.h> 47 #include <sys/fail.h> 48 #include <sys/systm.h> 49 #include <sys/capsicum.h> 50 #include <sys/kernel.h> 51 #include <sys/limits.h> 52 #include <sys/sysctl.h> 53 #include <sys/malloc.h> 54 #include <sys/priv.h> 55 #include <sys/proc.h> 56 #include <sys/jail.h> 57 #include <sys/kdb.h> 58 #include <sys/lock.h> 59 #include <sys/mutex.h> 60 #include <sys/rmlock.h> 61 #include <sys/sbuf.h> 62 #include <sys/sx.h> 63 #include <sys/sysproto.h> 64 #include <sys/uio.h> 65 #ifdef KTRACE 66 #include <sys/ktrace.h> 67 #endif 68 69 #ifdef DDB 70 #include <ddb/ddb.h> 71 #include <ddb/db_lex.h> 72 #endif 73 74 #include <net/vnet.h> 75 76 #include <security/mac/mac_framework.h> 77 78 #include <vm/vm.h> 79 #include <vm/vm_extern.h> 80 81 static MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl internal magic"); 82 static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids"); 83 static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer"); 84 85 RB_GENERATE(sysctl_oid_list, sysctl_oid, oid_link, cmp_sysctl_oid); 86 87 /* 88 * The sysctllock protects the MIB tree. It also protects sysctl 89 * contexts used with dynamic sysctls. The sysctl_register_oid() and 90 * sysctl_unregister_oid() routines require the sysctllock to already 91 * be held, so the sysctl_wlock() and sysctl_wunlock() routines are 92 * provided for the few places in the kernel which need to use that 93 * API rather than using the dynamic API. Use of the dynamic API is 94 * strongly encouraged for most code. 95 * 96 * The sysctlmemlock is used to limit the amount of user memory wired for 97 * sysctl requests. This is implemented by serializing any userland 98 * sysctl requests larger than a single page via an exclusive lock. 99 * 100 * The sysctlstringlock is used to protect concurrent access to writable 101 * string nodes in sysctl_handle_string(). 102 */ 103 static struct rmlock sysctllock; 104 static struct sx __exclusive_cache_line sysctlmemlock; 105 static struct sx sysctlstringlock; 106 107 #define SYSCTL_WLOCK() rm_wlock(&sysctllock) 108 #define SYSCTL_WUNLOCK() rm_wunlock(&sysctllock) 109 #define SYSCTL_RLOCK(tracker) rm_rlock(&sysctllock, (tracker)) 110 #define SYSCTL_RUNLOCK(tracker) rm_runlock(&sysctllock, (tracker)) 111 #define SYSCTL_WLOCKED() rm_wowned(&sysctllock) 112 #define SYSCTL_ASSERT_LOCKED() rm_assert(&sysctllock, RA_LOCKED) 113 #define SYSCTL_ASSERT_WLOCKED() rm_assert(&sysctllock, RA_WLOCKED) 114 #define SYSCTL_ASSERT_RLOCKED() rm_assert(&sysctllock, RA_RLOCKED) 115 #define SYSCTL_INIT() rm_init_flags(&sysctllock, "sysctl lock", \ 116 RM_SLEEPABLE) 117 #define SYSCTL_SLEEP(ch, wmesg, timo) \ 118 rm_sleep(ch, &sysctllock, 0, wmesg, timo) 119 120 static int sysctl_root(SYSCTL_HANDLER_ARGS); 121 122 /* Root list */ 123 struct sysctl_oid_list sysctl__children = RB_INITIALIZER(&sysctl__children); 124 125 static char* sysctl_escape_name(const char*); 126 static int sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, 127 int recurse); 128 static int sysctl_old_kernel(struct sysctl_req *, const void *, size_t); 129 static int sysctl_new_kernel(struct sysctl_req *, void *, size_t); 130 static int name2oid(const char *, int *, int *, struct sysctl_oid **); 131 132 static struct sysctl_oid * 133 sysctl_find_oidname(const char *name, struct sysctl_oid_list *list) 134 { 135 struct sysctl_oid *oidp; 136 137 SYSCTL_ASSERT_LOCKED(); 138 SYSCTL_FOREACH(oidp, list) { 139 if (strcmp(oidp->oid_name, name) == 0) { 140 return (oidp); 141 } 142 } 143 return (NULL); 144 } 145 146 static struct sysctl_oid * 147 sysctl_find_oidnamelen(const char *name, size_t len, 148 struct sysctl_oid_list *list) 149 { 150 struct sysctl_oid *oidp; 151 152 SYSCTL_ASSERT_LOCKED(); 153 SYSCTL_FOREACH(oidp, list) { 154 if (strncmp(oidp->oid_name, name, len) == 0 && 155 oidp->oid_name[len] == '\0') 156 return (oidp); 157 } 158 return (NULL); 159 } 160 161 /* 162 * Initialization of the MIB tree. 163 * 164 * Order by number in each list. 165 */ 166 void 167 sysctl_wlock(void) 168 { 169 170 SYSCTL_WLOCK(); 171 } 172 173 void 174 sysctl_wunlock(void) 175 { 176 177 SYSCTL_WUNLOCK(); 178 } 179 180 static int 181 sysctl_root_handler_locked(struct sysctl_oid *oid, void *arg1, intmax_t arg2, 182 struct sysctl_req *req, struct rm_priotracker *tracker) 183 { 184 int error; 185 186 if (oid->oid_kind & CTLFLAG_DYN) 187 atomic_add_int(&oid->oid_running, 1); 188 189 if (tracker != NULL) 190 SYSCTL_RUNLOCK(tracker); 191 else 192 SYSCTL_WUNLOCK(); 193 194 /* 195 * Treat set CTLFLAG_NEEDGIANT and unset CTLFLAG_MPSAFE flags the same, 196 * untill we're ready to remove all traces of Giant from sysctl(9). 197 */ 198 if ((oid->oid_kind & CTLFLAG_NEEDGIANT) || 199 (!(oid->oid_kind & CTLFLAG_MPSAFE))) 200 mtx_lock(&Giant); 201 error = oid->oid_handler(oid, arg1, arg2, req); 202 if ((oid->oid_kind & CTLFLAG_NEEDGIANT) || 203 (!(oid->oid_kind & CTLFLAG_MPSAFE))) 204 mtx_unlock(&Giant); 205 206 KFAIL_POINT_ERROR(_debug_fail_point, sysctl_running, error); 207 208 if (tracker != NULL) 209 SYSCTL_RLOCK(tracker); 210 else 211 SYSCTL_WLOCK(); 212 213 if (oid->oid_kind & CTLFLAG_DYN) { 214 if (atomic_fetchadd_int(&oid->oid_running, -1) == 1 && 215 (oid->oid_kind & CTLFLAG_DYING) != 0) 216 wakeup(&oid->oid_running); 217 } 218 219 return (error); 220 } 221 222 static void 223 sysctl_load_tunable_by_oid_locked(struct sysctl_oid *oidp) 224 { 225 struct sysctl_req req; 226 struct sysctl_oid *curr; 227 char *penv = NULL; 228 char path[96]; 229 ssize_t rem = sizeof(path); 230 ssize_t len; 231 uint8_t data[512] __aligned(sizeof(uint64_t)); 232 int size; 233 int error; 234 235 path[--rem] = 0; 236 237 for (curr = oidp; curr != NULL; curr = SYSCTL_PARENT(curr)) { 238 len = strlen(curr->oid_name); 239 rem -= len; 240 if (curr != oidp) 241 rem -= 1; 242 if (rem < 0) { 243 printf("OID path exceeds %d bytes\n", (int)sizeof(path)); 244 return; 245 } 246 memcpy(path + rem, curr->oid_name, len); 247 if (curr != oidp) 248 path[rem + len] = '.'; 249 } 250 251 memset(&req, 0, sizeof(req)); 252 253 req.td = curthread; 254 req.oldfunc = sysctl_old_kernel; 255 req.newfunc = sysctl_new_kernel; 256 req.lock = REQ_UNWIRED; 257 258 switch (oidp->oid_kind & CTLTYPE) { 259 case CTLTYPE_INT: 260 if (getenv_array(path + rem, data, sizeof(data), &size, 261 sizeof(int), GETENV_SIGNED) == 0) 262 return; 263 req.newlen = size; 264 req.newptr = data; 265 break; 266 case CTLTYPE_UINT: 267 if (getenv_array(path + rem, data, sizeof(data), &size, 268 sizeof(int), GETENV_UNSIGNED) == 0) 269 return; 270 req.newlen = size; 271 req.newptr = data; 272 break; 273 case CTLTYPE_LONG: 274 if (getenv_array(path + rem, data, sizeof(data), &size, 275 sizeof(long), GETENV_SIGNED) == 0) 276 return; 277 req.newlen = size; 278 req.newptr = data; 279 break; 280 case CTLTYPE_ULONG: 281 if (getenv_array(path + rem, data, sizeof(data), &size, 282 sizeof(long), GETENV_UNSIGNED) == 0) 283 return; 284 req.newlen = size; 285 req.newptr = data; 286 break; 287 case CTLTYPE_S8: 288 if (getenv_array(path + rem, data, sizeof(data), &size, 289 sizeof(int8_t), GETENV_SIGNED) == 0) 290 return; 291 req.newlen = size; 292 req.newptr = data; 293 break; 294 case CTLTYPE_S16: 295 if (getenv_array(path + rem, data, sizeof(data), &size, 296 sizeof(int16_t), GETENV_SIGNED) == 0) 297 return; 298 req.newlen = size; 299 req.newptr = data; 300 break; 301 case CTLTYPE_S32: 302 if (getenv_array(path + rem, data, sizeof(data), &size, 303 sizeof(int32_t), GETENV_SIGNED) == 0) 304 return; 305 req.newlen = size; 306 req.newptr = data; 307 break; 308 case CTLTYPE_S64: 309 if (getenv_array(path + rem, data, sizeof(data), &size, 310 sizeof(int64_t), GETENV_SIGNED) == 0) 311 return; 312 req.newlen = size; 313 req.newptr = data; 314 break; 315 case CTLTYPE_U8: 316 if (getenv_array(path + rem, data, sizeof(data), &size, 317 sizeof(uint8_t), GETENV_UNSIGNED) == 0) 318 return; 319 req.newlen = size; 320 req.newptr = data; 321 break; 322 case CTLTYPE_U16: 323 if (getenv_array(path + rem, data, sizeof(data), &size, 324 sizeof(uint16_t), GETENV_UNSIGNED) == 0) 325 return; 326 req.newlen = size; 327 req.newptr = data; 328 break; 329 case CTLTYPE_U32: 330 if (getenv_array(path + rem, data, sizeof(data), &size, 331 sizeof(uint32_t), GETENV_UNSIGNED) == 0) 332 return; 333 req.newlen = size; 334 req.newptr = data; 335 break; 336 case CTLTYPE_U64: 337 if (getenv_array(path + rem, data, sizeof(data), &size, 338 sizeof(uint64_t), GETENV_UNSIGNED) == 0) 339 return; 340 req.newlen = size; 341 req.newptr = data; 342 break; 343 case CTLTYPE_STRING: 344 penv = kern_getenv(path + rem); 345 if (penv == NULL) 346 return; 347 req.newlen = strlen(penv); 348 req.newptr = penv; 349 break; 350 default: 351 return; 352 } 353 error = sysctl_root_handler_locked(oidp, oidp->oid_arg1, 354 oidp->oid_arg2, &req, NULL); 355 if (error != 0) 356 printf("Setting sysctl %s failed: %d\n", path + rem, error); 357 if (penv != NULL) 358 freeenv(penv); 359 } 360 361 /* 362 * Locate the path to a given oid. Returns the length of the resulting path, 363 * or -1 if the oid was not found. nodes must have room for CTL_MAXNAME 364 * elements. 365 */ 366 static int 367 sysctl_search_oid(struct sysctl_oid **nodes, struct sysctl_oid *needle) 368 { 369 int indx; 370 371 SYSCTL_ASSERT_LOCKED(); 372 indx = 0; 373 /* 374 * Do a depth-first search of the oid tree, looking for 'needle'. Start 375 * with the first child of the root. 376 */ 377 nodes[indx] = RB_MIN(sysctl_oid_list, &sysctl__children); 378 for (;;) { 379 if (nodes[indx] == needle) 380 return (indx + 1); 381 382 if (nodes[indx] == NULL) { 383 /* Node has no more siblings, so back up to parent. */ 384 if (indx-- == 0) { 385 /* Retreat to root, so give up. */ 386 break; 387 } 388 } else if ((nodes[indx]->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 389 /* Node has children. */ 390 if (++indx == CTL_MAXNAME) { 391 /* Max search depth reached, so give up. */ 392 break; 393 } 394 /* Start with the first child. */ 395 nodes[indx] = RB_MIN(sysctl_oid_list, 396 &nodes[indx - 1]->oid_children); 397 continue; 398 } 399 /* Consider next sibling. */ 400 nodes[indx] = RB_NEXT(sysctl_oid_list, NULL, nodes[indx]); 401 } 402 return (-1); 403 } 404 405 static void 406 sysctl_warn_reuse(const char *func, struct sysctl_oid *leaf) 407 { 408 struct sysctl_oid *nodes[CTL_MAXNAME]; 409 char buf[128]; 410 struct sbuf sb; 411 int rc, i; 412 413 (void)sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN | SBUF_INCLUDENUL); 414 sbuf_set_drain(&sb, sbuf_printf_drain, NULL); 415 416 sbuf_printf(&sb, "%s: can't re-use a leaf (", __func__); 417 418 rc = sysctl_search_oid(nodes, leaf); 419 if (rc > 0) { 420 for (i = 0; i < rc; i++) 421 sbuf_printf(&sb, "%s%.*s", nodes[i]->oid_name, 422 i != (rc - 1), "."); 423 } else { 424 sbuf_printf(&sb, "%s", leaf->oid_name); 425 } 426 sbuf_printf(&sb, ")!\n"); 427 428 (void)sbuf_finish(&sb); 429 } 430 431 #ifdef SYSCTL_DEBUG 432 static int 433 sysctl_reuse_test(SYSCTL_HANDLER_ARGS) 434 { 435 struct rm_priotracker tracker; 436 437 SYSCTL_RLOCK(&tracker); 438 sysctl_warn_reuse(__func__, oidp); 439 SYSCTL_RUNLOCK(&tracker); 440 return (0); 441 } 442 SYSCTL_PROC(_sysctl, OID_AUTO, reuse_test, 443 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 0, sysctl_reuse_test, "-", 444 ""); 445 #endif 446 447 void 448 sysctl_register_oid(struct sysctl_oid *oidp) 449 { 450 struct sysctl_oid_list *parent = oidp->oid_parent; 451 struct sysctl_oid *p, key; 452 int oid_number; 453 int timeout = 2; 454 455 /* 456 * First check if another oid with the same name already 457 * exists in the parent's list. 458 */ 459 SYSCTL_ASSERT_WLOCKED(); 460 p = sysctl_find_oidname(oidp->oid_name, parent); 461 if (p != NULL) { 462 if ((p->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 463 p->oid_refcnt++; 464 return; 465 } else { 466 sysctl_warn_reuse(__func__, p); 467 return; 468 } 469 } 470 /* get current OID number */ 471 oid_number = oidp->oid_number; 472 473 #if (OID_AUTO >= 0) 474 #error "OID_AUTO is expected to be a negative value" 475 #endif 476 /* 477 * Any negative OID number qualifies as OID_AUTO. Valid OID 478 * numbers should always be positive. 479 * 480 * NOTE: DO NOT change the starting value here, change it in 481 * <sys/sysctl.h>, and make sure it is at least 256 to 482 * accommodate e.g. net.inet.raw as a static sysctl node. 483 */ 484 if (oid_number < 0) { 485 static int newoid; 486 487 /* 488 * By decrementing the next OID number we spend less 489 * time inserting the OIDs into a sorted list. 490 */ 491 if (--newoid < CTL_AUTO_START) 492 newoid = 0x7fffffff; 493 494 oid_number = newoid; 495 } 496 497 /* 498 * Insert the OID into the parent's list sorted by OID number. 499 */ 500 key.oid_number = oid_number; 501 p = RB_NFIND(sysctl_oid_list, parent, &key); 502 while (p != NULL && oid_number == p->oid_number) { 503 /* get the next valid OID number */ 504 if (oid_number < CTL_AUTO_START || 505 oid_number == 0x7fffffff) { 506 /* wraparound - restart */ 507 oid_number = CTL_AUTO_START; 508 /* don't loop forever */ 509 if (!timeout--) 510 panic("sysctl: Out of OID numbers\n"); 511 key.oid_number = oid_number; 512 p = RB_NFIND(sysctl_oid_list, parent, &key); 513 continue; 514 } 515 p = RB_NEXT(sysctl_oid_list, NULL, p); 516 oid_number++; 517 } 518 /* check for non-auto OID number collision */ 519 if (oidp->oid_number >= 0 && oidp->oid_number < CTL_AUTO_START && 520 oid_number >= CTL_AUTO_START) { 521 printf("sysctl: OID number(%d) is already in use for '%s'\n", 522 oidp->oid_number, oidp->oid_name); 523 } 524 /* update the OID number, if any */ 525 oidp->oid_number = oid_number; 526 RB_INSERT(sysctl_oid_list, parent, oidp); 527 528 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE && 529 (oidp->oid_kind & CTLFLAG_TUN) != 0 && 530 (oidp->oid_kind & CTLFLAG_NOFETCH) == 0) { 531 #ifdef VIMAGE 532 /* 533 * Can fetch value multiple times for VNET loader tunables. 534 * Only fetch once for non-VNET loader tunables. 535 */ 536 if ((oidp->oid_kind & CTLFLAG_VNET) == 0) 537 #endif 538 oidp->oid_kind |= CTLFLAG_NOFETCH; 539 /* try to fetch value from kernel environment */ 540 sysctl_load_tunable_by_oid_locked(oidp); 541 } 542 } 543 544 void 545 sysctl_register_disabled_oid(struct sysctl_oid *oidp) 546 { 547 548 /* 549 * Mark the leaf as dormant if it's not to be immediately enabled. 550 * We do not disable nodes as they can be shared between modules 551 * and it is always safe to access a node. 552 */ 553 KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0, 554 ("internal flag is set in oid_kind")); 555 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 556 oidp->oid_kind |= CTLFLAG_DORMANT; 557 sysctl_register_oid(oidp); 558 } 559 560 void 561 sysctl_enable_oid(struct sysctl_oid *oidp) 562 { 563 564 SYSCTL_ASSERT_WLOCKED(); 565 if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 566 KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0, 567 ("sysctl node is marked as dormant")); 568 return; 569 } 570 KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) != 0, 571 ("enabling already enabled sysctl oid")); 572 oidp->oid_kind &= ~CTLFLAG_DORMANT; 573 } 574 575 void 576 sysctl_unregister_oid(struct sysctl_oid *oidp) 577 { 578 int error; 579 580 SYSCTL_ASSERT_WLOCKED(); 581 if (oidp->oid_number == OID_AUTO) { 582 error = EINVAL; 583 } else { 584 error = ENOENT; 585 if (RB_REMOVE(sysctl_oid_list, oidp->oid_parent, oidp)) 586 error = 0; 587 } 588 589 /* 590 * This can happen when a module fails to register and is 591 * being unloaded afterwards. It should not be a panic() 592 * for normal use. 593 */ 594 if (error) { 595 printf("%s: failed(%d) to unregister sysctl(%s)\n", 596 __func__, error, oidp->oid_name); 597 } 598 } 599 600 /* Initialize a new context to keep track of dynamically added sysctls. */ 601 int 602 sysctl_ctx_init(struct sysctl_ctx_list *c) 603 { 604 605 if (c == NULL) { 606 return (EINVAL); 607 } 608 609 /* 610 * No locking here, the caller is responsible for not adding 611 * new nodes to a context until after this function has 612 * returned. 613 */ 614 TAILQ_INIT(c); 615 return (0); 616 } 617 618 /* Free the context, and destroy all dynamic oids registered in this context */ 619 int 620 sysctl_ctx_free(struct sysctl_ctx_list *clist) 621 { 622 struct sysctl_ctx_entry *e, *e1; 623 int error; 624 625 error = 0; 626 /* 627 * First perform a "dry run" to check if it's ok to remove oids. 628 * XXX FIXME 629 * XXX This algorithm is a hack. But I don't know any 630 * XXX better solution for now... 631 */ 632 SYSCTL_WLOCK(); 633 TAILQ_FOREACH(e, clist, link) { 634 error = sysctl_remove_oid_locked(e->entry, 0, 0); 635 if (error) 636 break; 637 } 638 /* 639 * Restore deregistered entries, either from the end, 640 * or from the place where error occurred. 641 * e contains the entry that was not unregistered 642 */ 643 if (error) 644 e1 = TAILQ_PREV(e, sysctl_ctx_list, link); 645 else 646 e1 = TAILQ_LAST(clist, sysctl_ctx_list); 647 while (e1 != NULL) { 648 sysctl_register_oid(e1->entry); 649 e1 = TAILQ_PREV(e1, sysctl_ctx_list, link); 650 } 651 if (error) { 652 SYSCTL_WUNLOCK(); 653 return(EBUSY); 654 } 655 /* Now really delete the entries */ 656 e = TAILQ_FIRST(clist); 657 while (e != NULL) { 658 e1 = TAILQ_NEXT(e, link); 659 error = sysctl_remove_oid_locked(e->entry, 1, 0); 660 if (error) 661 panic("sysctl_remove_oid: corrupt tree, entry: %s", 662 e->entry->oid_name); 663 free(e, M_SYSCTLOID); 664 e = e1; 665 } 666 SYSCTL_WUNLOCK(); 667 return (error); 668 } 669 670 /* Add an entry to the context */ 671 struct sysctl_ctx_entry * 672 sysctl_ctx_entry_add(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) 673 { 674 struct sysctl_ctx_entry *e; 675 676 SYSCTL_ASSERT_WLOCKED(); 677 if (clist == NULL || oidp == NULL) 678 return(NULL); 679 e = malloc(sizeof(struct sysctl_ctx_entry), M_SYSCTLOID, M_WAITOK); 680 e->entry = oidp; 681 TAILQ_INSERT_HEAD(clist, e, link); 682 return (e); 683 } 684 685 /* Find an entry in the context */ 686 struct sysctl_ctx_entry * 687 sysctl_ctx_entry_find(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) 688 { 689 struct sysctl_ctx_entry *e; 690 691 SYSCTL_ASSERT_WLOCKED(); 692 if (clist == NULL || oidp == NULL) 693 return(NULL); 694 TAILQ_FOREACH(e, clist, link) { 695 if (e->entry == oidp) 696 return(e); 697 } 698 return (e); 699 } 700 701 /* 702 * Delete an entry from the context. 703 * NOTE: this function doesn't free oidp! You have to remove it 704 * with sysctl_remove_oid(). 705 */ 706 int 707 sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp) 708 { 709 struct sysctl_ctx_entry *e; 710 711 if (clist == NULL || oidp == NULL) 712 return (EINVAL); 713 SYSCTL_WLOCK(); 714 e = sysctl_ctx_entry_find(clist, oidp); 715 if (e != NULL) { 716 TAILQ_REMOVE(clist, e, link); 717 SYSCTL_WUNLOCK(); 718 free(e, M_SYSCTLOID); 719 return (0); 720 } else { 721 SYSCTL_WUNLOCK(); 722 return (ENOENT); 723 } 724 } 725 726 /* 727 * Remove dynamically created sysctl trees. 728 * oidp - top of the tree to be removed 729 * del - if 0 - just deregister, otherwise free up entries as well 730 * recurse - if != 0 traverse the subtree to be deleted 731 */ 732 int 733 sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse) 734 { 735 int error; 736 737 SYSCTL_WLOCK(); 738 error = sysctl_remove_oid_locked(oidp, del, recurse); 739 SYSCTL_WUNLOCK(); 740 return (error); 741 } 742 743 int 744 sysctl_remove_name(struct sysctl_oid *parent, const char *name, 745 int del, int recurse) 746 { 747 struct sysctl_oid *p; 748 int error; 749 750 error = ENOENT; 751 SYSCTL_WLOCK(); 752 p = sysctl_find_oidname(name, &parent->oid_children); 753 if (p) 754 error = sysctl_remove_oid_locked(p, del, recurse); 755 SYSCTL_WUNLOCK(); 756 757 return (error); 758 } 759 760 /* 761 * Duplicate the provided string, escaping any illegal characters. The result 762 * must be freed when no longer in use. 763 * 764 * The list of illegal characters is ".". 765 */ 766 static char* 767 sysctl_escape_name(const char* orig) 768 { 769 int i, s = 0, d = 0, nillegals = 0; 770 char *new; 771 772 /* First count the number of illegal characters */ 773 for (i = 0; orig[i] != '\0'; i++) { 774 if (orig[i] == '.') 775 nillegals++; 776 } 777 778 /* Allocate storage for new string */ 779 new = malloc(i + 2 * nillegals + 1, M_SYSCTLOID, M_WAITOK); 780 781 /* Copy the name, escaping characters as we go */ 782 while (orig[s] != '\0') { 783 if (orig[s] == '.') { 784 /* %25 is the hexadecimal representation of '.' */ 785 new[d++] = '%'; 786 new[d++] = '2'; 787 new[d++] = '5'; 788 s++; 789 } else { 790 new[d++] = orig[s++]; 791 } 792 } 793 794 /* Finally, nul-terminate */ 795 new[d] = '\0'; 796 797 return (new); 798 } 799 800 static int 801 sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse) 802 { 803 struct sysctl_oid *p, *tmp; 804 int error; 805 806 SYSCTL_ASSERT_WLOCKED(); 807 if (oidp == NULL) 808 return(EINVAL); 809 if ((oidp->oid_kind & CTLFLAG_DYN) == 0) { 810 printf("Warning: can't remove non-dynamic nodes (%s)!\n", 811 oidp->oid_name); 812 return (EINVAL); 813 } 814 /* 815 * WARNING: normal method to do this should be through 816 * sysctl_ctx_free(). Use recursing as the last resort 817 * method to purge your sysctl tree of leftovers... 818 * However, if some other code still references these nodes, 819 * it will panic. 820 */ 821 if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 822 if (oidp->oid_refcnt == 1) { 823 for(p = RB_MIN(sysctl_oid_list, &oidp->oid_children); 824 p != NULL; p = tmp) { 825 if (!recurse) { 826 printf("Warning: failed attempt to " 827 "remove oid %s with child %s\n", 828 oidp->oid_name, p->oid_name); 829 return (ENOTEMPTY); 830 } 831 tmp = RB_NEXT(sysctl_oid_list, 832 &oidp->oid_children, p); 833 error = sysctl_remove_oid_locked(p, del, 834 recurse); 835 if (error) 836 return (error); 837 } 838 } 839 } 840 if (oidp->oid_refcnt > 1 ) { 841 oidp->oid_refcnt--; 842 } else { 843 if (oidp->oid_refcnt == 0) { 844 printf("Warning: bad oid_refcnt=%u (%s)!\n", 845 oidp->oid_refcnt, oidp->oid_name); 846 return (EINVAL); 847 } 848 sysctl_unregister_oid(oidp); 849 if (del) { 850 /* 851 * Wait for all threads running the handler to drain. 852 * This preserves the previous behavior when the 853 * sysctl lock was held across a handler invocation, 854 * and is necessary for module unload correctness. 855 */ 856 while (oidp->oid_running > 0) { 857 oidp->oid_kind |= CTLFLAG_DYING; 858 SYSCTL_SLEEP(&oidp->oid_running, "oidrm", 0); 859 } 860 if (oidp->oid_descr) 861 free(__DECONST(char *, oidp->oid_descr), 862 M_SYSCTLOID); 863 if (oidp->oid_label) 864 free(__DECONST(char *, oidp->oid_label), 865 M_SYSCTLOID); 866 free(__DECONST(char *, oidp->oid_name), M_SYSCTLOID); 867 free(oidp, M_SYSCTLOID); 868 } 869 } 870 return (0); 871 } 872 /* 873 * Create new sysctls at run time. 874 * clist may point to a valid context initialized with sysctl_ctx_init(). 875 */ 876 struct sysctl_oid * 877 sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, 878 int number, const char *name, int kind, void *arg1, intmax_t arg2, 879 int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, const char *descr, 880 const char *label) 881 { 882 struct sysctl_oid *oidp; 883 char *escaped; 884 885 /* You have to hook up somewhere.. */ 886 if (parent == NULL) 887 return(NULL); 888 escaped = sysctl_escape_name(name); 889 /* Check if the node already exists, otherwise create it */ 890 SYSCTL_WLOCK(); 891 oidp = sysctl_find_oidname(escaped, parent); 892 if (oidp != NULL) { 893 free(escaped, M_SYSCTLOID); 894 if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 895 oidp->oid_refcnt++; 896 /* Update the context */ 897 if (clist != NULL) 898 sysctl_ctx_entry_add(clist, oidp); 899 SYSCTL_WUNLOCK(); 900 return (oidp); 901 } else { 902 sysctl_warn_reuse(__func__, oidp); 903 SYSCTL_WUNLOCK(); 904 return (NULL); 905 } 906 } 907 oidp = malloc(sizeof(struct sysctl_oid), M_SYSCTLOID, M_WAITOK|M_ZERO); 908 oidp->oid_parent = parent; 909 RB_INIT(&oidp->oid_children); 910 oidp->oid_number = number; 911 oidp->oid_refcnt = 1; 912 oidp->oid_name = escaped; 913 oidp->oid_handler = handler; 914 oidp->oid_kind = CTLFLAG_DYN | kind; 915 oidp->oid_arg1 = arg1; 916 oidp->oid_arg2 = arg2; 917 oidp->oid_fmt = fmt; 918 if (descr != NULL) 919 oidp->oid_descr = strdup(descr, M_SYSCTLOID); 920 if (label != NULL) 921 oidp->oid_label = strdup(label, M_SYSCTLOID); 922 /* Update the context, if used */ 923 if (clist != NULL) 924 sysctl_ctx_entry_add(clist, oidp); 925 /* Register this oid */ 926 sysctl_register_oid(oidp); 927 SYSCTL_WUNLOCK(); 928 return (oidp); 929 } 930 931 /* 932 * Rename an existing oid. 933 */ 934 void 935 sysctl_rename_oid(struct sysctl_oid *oidp, const char *name) 936 { 937 char *newname; 938 char *oldname; 939 940 newname = strdup(name, M_SYSCTLOID); 941 SYSCTL_WLOCK(); 942 oldname = __DECONST(char *, oidp->oid_name); 943 oidp->oid_name = newname; 944 SYSCTL_WUNLOCK(); 945 free(oldname, M_SYSCTLOID); 946 } 947 948 /* 949 * Reparent an existing oid. 950 */ 951 int 952 sysctl_move_oid(struct sysctl_oid *oid, struct sysctl_oid_list *parent) 953 { 954 struct sysctl_oid *oidp; 955 956 SYSCTL_WLOCK(); 957 if (oid->oid_parent == parent) { 958 SYSCTL_WUNLOCK(); 959 return (0); 960 } 961 oidp = sysctl_find_oidname(oid->oid_name, parent); 962 if (oidp != NULL) { 963 SYSCTL_WUNLOCK(); 964 return (EEXIST); 965 } 966 sysctl_unregister_oid(oid); 967 oid->oid_parent = parent; 968 oid->oid_number = OID_AUTO; 969 sysctl_register_oid(oid); 970 SYSCTL_WUNLOCK(); 971 return (0); 972 } 973 974 /* 975 * Register the kernel's oids on startup. 976 */ 977 SET_DECLARE(sysctl_set, struct sysctl_oid); 978 979 static void 980 sysctl_register_all(void *arg) 981 { 982 struct sysctl_oid **oidp; 983 984 sx_init(&sysctlmemlock, "sysctl mem"); 985 sx_init(&sysctlstringlock, "sysctl string handler"); 986 SYSCTL_INIT(); 987 SYSCTL_WLOCK(); 988 SET_FOREACH(oidp, sysctl_set) 989 sysctl_register_oid(*oidp); 990 SYSCTL_WUNLOCK(); 991 } 992 SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_FIRST, sysctl_register_all, NULL); 993 994 #ifdef VIMAGE 995 static void 996 sysctl_setenv_vnet(void *arg __unused, const char *name) 997 { 998 struct sysctl_oid *oidp; 999 int oid[CTL_MAXNAME]; 1000 int error, nlen; 1001 1002 SYSCTL_WLOCK(); 1003 error = name2oid(name, oid, &nlen, &oidp); 1004 if (error) 1005 goto out; 1006 1007 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE && 1008 (oidp->oid_kind & CTLFLAG_VNET) != 0 && 1009 (oidp->oid_kind & CTLFLAG_TUN) != 0 && 1010 (oidp->oid_kind & CTLFLAG_NOFETCH) == 0) { 1011 /* Update value from kernel environment */ 1012 sysctl_load_tunable_by_oid_locked(oidp); 1013 } 1014 out: 1015 SYSCTL_WUNLOCK(); 1016 } 1017 1018 static void 1019 sysctl_unsetenv_vnet(void *arg __unused, const char *name) 1020 { 1021 struct sysctl_oid *oidp; 1022 int oid[CTL_MAXNAME]; 1023 int error, nlen; 1024 1025 SYSCTL_WLOCK(); 1026 /* 1027 * The setenv / unsetenv event handlers are invoked by kern_setenv() / 1028 * kern_unsetenv() without exclusive locks. It is rare but still possible 1029 * that the invoke order of event handlers is different from that of 1030 * kern_setenv() and kern_unsetenv(). 1031 * Re-check environment variable string to make sure it is unset. 1032 */ 1033 if (testenv(name)) 1034 goto out; 1035 error = name2oid(name, oid, &nlen, &oidp); 1036 if (error) 1037 goto out; 1038 1039 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE && 1040 (oidp->oid_kind & CTLFLAG_VNET) != 0 && 1041 (oidp->oid_kind & CTLFLAG_TUN) != 0 && 1042 (oidp->oid_kind & CTLFLAG_NOFETCH) == 0) { 1043 size_t size; 1044 1045 switch (oidp->oid_kind & CTLTYPE) { 1046 case CTLTYPE_INT: 1047 case CTLTYPE_UINT: 1048 size = sizeof(int); 1049 break; 1050 case CTLTYPE_LONG: 1051 case CTLTYPE_ULONG: 1052 size = sizeof(long); 1053 break; 1054 case CTLTYPE_S8: 1055 case CTLTYPE_U8: 1056 size = sizeof(int8_t); 1057 break; 1058 case CTLTYPE_S16: 1059 case CTLTYPE_U16: 1060 size = sizeof(int16_t); 1061 break; 1062 case CTLTYPE_S32: 1063 case CTLTYPE_U32: 1064 size = sizeof(int32_t); 1065 break; 1066 case CTLTYPE_S64: 1067 case CTLTYPE_U64: 1068 size = sizeof(int64_t); 1069 break; 1070 case CTLTYPE_STRING: 1071 MPASS(oidp->oid_arg2 > 0); 1072 size = oidp->oid_arg2; 1073 break; 1074 default: 1075 goto out; 1076 } 1077 vnet_restore_init(oidp->oid_arg1, size); 1078 } 1079 out: 1080 SYSCTL_WUNLOCK(); 1081 } 1082 1083 /* 1084 * Register the kernel's setenv / unsetenv events. 1085 */ 1086 EVENTHANDLER_DEFINE(setenv, sysctl_setenv_vnet, NULL, EVENTHANDLER_PRI_ANY); 1087 EVENTHANDLER_DEFINE(unsetenv, sysctl_unsetenv_vnet, NULL, EVENTHANDLER_PRI_ANY); 1088 #endif 1089 1090 /* 1091 * "Staff-functions" 1092 * 1093 * These functions implement a presently undocumented interface 1094 * used by the sysctl program to walk the tree, and get the type 1095 * so it can print the value. 1096 * This interface is under work and consideration, and should probably 1097 * be killed with a big axe by the first person who can find the time. 1098 * (be aware though, that the proper interface isn't as obvious as it 1099 * may seem, there are various conflicting requirements. 1100 * 1101 * {CTL_SYSCTL, CTL_SYSCTL_DEBUG} printf the entire MIB-tree. 1102 * {CTL_SYSCTL, CTL_SYSCTL_NAME, ...} return the name of the "..." 1103 * OID. 1104 * {CTL_SYSCTL, CTL_SYSCTL_NEXT, ...} return the next OID, honoring 1105 * CTLFLAG_SKIP. 1106 * {CTL_SYSCTL, CTL_SYSCTL_NAME2OID} return the OID of the name in 1107 * "new" 1108 * {CTL_SYSCTL, CTL_SYSCTL_OIDFMT, ...} return the kind & format info 1109 * for the "..." OID. 1110 * {CTL_SYSCTL, CTL_SYSCTL_OIDDESCR, ...} return the description of the 1111 * "..." OID. 1112 * {CTL_SYSCTL, CTL_SYSCTL_OIDLABEL, ...} return the aggregation label of 1113 * the "..." OID. 1114 * {CTL_SYSCTL, CTL_SYSCTL_NEXTNOSKIP, ...} return the next OID, ignoring 1115 * CTLFLAG_SKIP. 1116 */ 1117 1118 #ifdef SYSCTL_DEBUG 1119 static void 1120 sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i) 1121 { 1122 int k; 1123 struct sysctl_oid *oidp; 1124 1125 SYSCTL_ASSERT_LOCKED(); 1126 SYSCTL_FOREACH(oidp, l) { 1127 for (k=0; k<i; k++) 1128 printf(" "); 1129 1130 printf("%d %s ", oidp->oid_number, oidp->oid_name); 1131 1132 printf("%c%c", 1133 oidp->oid_kind & CTLFLAG_RD ? 'R':' ', 1134 oidp->oid_kind & CTLFLAG_WR ? 'W':' '); 1135 1136 if (oidp->oid_handler) 1137 printf(" *Handler"); 1138 1139 switch (oidp->oid_kind & CTLTYPE) { 1140 case CTLTYPE_NODE: 1141 printf(" Node\n"); 1142 if (!oidp->oid_handler) { 1143 sysctl_sysctl_debug_dump_node( 1144 SYSCTL_CHILDREN(oidp), i + 2); 1145 } 1146 break; 1147 case CTLTYPE_INT: printf(" Int\n"); break; 1148 case CTLTYPE_UINT: printf(" u_int\n"); break; 1149 case CTLTYPE_LONG: printf(" Long\n"); break; 1150 case CTLTYPE_ULONG: printf(" u_long\n"); break; 1151 case CTLTYPE_STRING: printf(" String\n"); break; 1152 case CTLTYPE_S8: printf(" int8_t\n"); break; 1153 case CTLTYPE_S16: printf(" int16_t\n"); break; 1154 case CTLTYPE_S32: printf(" int32_t\n"); break; 1155 case CTLTYPE_S64: printf(" int64_t\n"); break; 1156 case CTLTYPE_U8: printf(" uint8_t\n"); break; 1157 case CTLTYPE_U16: printf(" uint16_t\n"); break; 1158 case CTLTYPE_U32: printf(" uint32_t\n"); break; 1159 case CTLTYPE_U64: printf(" uint64_t\n"); break; 1160 case CTLTYPE_OPAQUE: printf(" Opaque/struct\n"); break; 1161 default: printf("\n"); 1162 } 1163 } 1164 } 1165 1166 static int 1167 sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS) 1168 { 1169 struct rm_priotracker tracker; 1170 int error; 1171 1172 error = priv_check(req->td, PRIV_SYSCTL_DEBUG); 1173 if (error) 1174 return (error); 1175 SYSCTL_RLOCK(&tracker); 1176 sysctl_sysctl_debug_dump_node(&sysctl__children, 0); 1177 SYSCTL_RUNLOCK(&tracker); 1178 return (ENOENT); 1179 } 1180 1181 SYSCTL_PROC(_sysctl, CTL_SYSCTL_DEBUG, debug, CTLTYPE_STRING | CTLFLAG_RD | 1182 CTLFLAG_MPSAFE, 0, 0, sysctl_sysctl_debug, "-", ""); 1183 #endif 1184 1185 static int 1186 sysctl_sysctl_name(SYSCTL_HANDLER_ARGS) 1187 { 1188 int *name = (int *) arg1; 1189 u_int namelen = arg2; 1190 int error; 1191 struct sysctl_oid *oid, key; 1192 struct sysctl_oid_list *lsp = &sysctl__children, *lsp2; 1193 struct rm_priotracker tracker; 1194 char buf[10]; 1195 1196 error = sysctl_wire_old_buffer(req, 0); 1197 if (error) 1198 return (error); 1199 1200 SYSCTL_RLOCK(&tracker); 1201 while (namelen) { 1202 if (!lsp) { 1203 snprintf(buf,sizeof(buf),"%d",*name); 1204 if (req->oldidx) 1205 error = SYSCTL_OUT(req, ".", 1); 1206 if (!error) 1207 error = SYSCTL_OUT(req, buf, strlen(buf)); 1208 if (error) 1209 goto out; 1210 namelen--; 1211 name++; 1212 continue; 1213 } 1214 lsp2 = NULL; 1215 key.oid_number = *name; 1216 oid = RB_FIND(sysctl_oid_list, lsp, &key); 1217 if (oid) { 1218 if (req->oldidx) 1219 error = SYSCTL_OUT(req, ".", 1); 1220 if (!error) 1221 error = SYSCTL_OUT(req, oid->oid_name, 1222 strlen(oid->oid_name)); 1223 if (error) 1224 goto out; 1225 1226 namelen--; 1227 name++; 1228 1229 if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE && 1230 !oid->oid_handler) 1231 lsp2 = SYSCTL_CHILDREN(oid); 1232 } 1233 lsp = lsp2; 1234 } 1235 error = SYSCTL_OUT(req, "", 1); 1236 out: 1237 SYSCTL_RUNLOCK(&tracker); 1238 return (error); 1239 } 1240 1241 /* 1242 * XXXRW/JA: Shouldn't return name data for nodes that we don't permit in 1243 * capability mode. 1244 */ 1245 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NAME, name, CTLFLAG_RD | 1246 CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_name, ""); 1247 1248 enum sysctl_iter_action { 1249 ITER_SIBLINGS, /* Not matched, continue iterating siblings */ 1250 ITER_CHILDREN, /* Node has children we need to iterate over them */ 1251 ITER_FOUND, /* Matching node was found */ 1252 }; 1253 1254 /* 1255 * Tries to find the next node for @name and @namelen. 1256 * 1257 * Returns next action to take. 1258 */ 1259 static enum sysctl_iter_action 1260 sysctl_sysctl_next_node(struct sysctl_oid *oidp, int *name, unsigned int namelen, 1261 bool honor_skip) 1262 { 1263 1264 if ((oidp->oid_kind & CTLFLAG_DORMANT) != 0) 1265 return (ITER_SIBLINGS); 1266 1267 if (honor_skip && (oidp->oid_kind & CTLFLAG_SKIP) != 0) 1268 return (ITER_SIBLINGS); 1269 1270 if (namelen == 0) { 1271 /* 1272 * We have reached a node with a full name match and are 1273 * looking for the next oid in its children. 1274 * 1275 * For CTL_SYSCTL_NEXTNOSKIP we are done. 1276 * 1277 * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it 1278 * has a handler) and move on to the children. 1279 */ 1280 if (!honor_skip) 1281 return (ITER_FOUND); 1282 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 1283 return (ITER_FOUND); 1284 /* If node does not have an iterator, treat it as leaf */ 1285 if (oidp->oid_handler) 1286 return (ITER_FOUND); 1287 1288 /* Report oid as a node to iterate */ 1289 return (ITER_CHILDREN); 1290 } 1291 1292 /* 1293 * No match yet. Continue seeking the given name. 1294 * 1295 * We are iterating in order by oid_number, so skip oids lower 1296 * than the one we are looking for. 1297 * 1298 * When the current oid_number is higher than the one we seek, 1299 * that means we have reached the next oid in the sequence and 1300 * should return it. 1301 * 1302 * If the oid_number matches the name at this level then we 1303 * have to find a node to continue searching at the next level. 1304 */ 1305 if (oidp->oid_number < *name) 1306 return (ITER_SIBLINGS); 1307 if (oidp->oid_number > *name) { 1308 /* 1309 * We have reached the next oid. 1310 * 1311 * For CTL_SYSCTL_NEXTNOSKIP we are done. 1312 * 1313 * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it 1314 * has a handler) and move on to the children. 1315 */ 1316 if (!honor_skip) 1317 return (ITER_FOUND); 1318 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 1319 return (ITER_FOUND); 1320 /* If node does not have an iterator, treat it as leaf */ 1321 if (oidp->oid_handler) 1322 return (ITER_FOUND); 1323 return (ITER_CHILDREN); 1324 } 1325 1326 /* match at a current level */ 1327 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 1328 return (ITER_SIBLINGS); 1329 if (oidp->oid_handler) 1330 return (ITER_SIBLINGS); 1331 1332 return (ITER_CHILDREN); 1333 } 1334 1335 /* 1336 * Recursively walk the sysctl subtree at lsp until we find the given name. 1337 * Returns true and fills in next oid data in @next and @len if oid is found. 1338 */ 1339 static bool 1340 sysctl_sysctl_next_action(struct sysctl_oid_list *lsp, int *name, u_int namelen, 1341 int *next, int *len, int level, bool honor_skip) 1342 { 1343 struct sysctl_oid_list *next_lsp; 1344 struct sysctl_oid *oidp = NULL, key; 1345 bool success = false; 1346 enum sysctl_iter_action action; 1347 1348 SYSCTL_ASSERT_LOCKED(); 1349 /* 1350 * Start the search at the requested oid. But if not found, then scan 1351 * through all children. 1352 */ 1353 if (namelen > 0) { 1354 key.oid_number = *name; 1355 oidp = RB_FIND(sysctl_oid_list, lsp, &key); 1356 } 1357 if (!oidp) 1358 oidp = RB_MIN(sysctl_oid_list, lsp); 1359 for(; oidp != NULL; oidp = RB_NEXT(sysctl_oid_list, lsp, oidp)) { 1360 action = sysctl_sysctl_next_node(oidp, name, namelen, 1361 honor_skip); 1362 if (action == ITER_SIBLINGS) 1363 continue; 1364 if (action == ITER_FOUND) { 1365 success = true; 1366 break; 1367 } 1368 KASSERT((action== ITER_CHILDREN), ("ret(%d)!=ITER_CHILDREN", action)); 1369 1370 next_lsp = SYSCTL_CHILDREN(oidp); 1371 if (namelen == 0) { 1372 success = sysctl_sysctl_next_action(next_lsp, NULL, 0, 1373 next + 1, len, level + 1, honor_skip); 1374 } else { 1375 success = sysctl_sysctl_next_action(next_lsp, name + 1, 1376 namelen - 1, next + 1, len, level + 1, honor_skip); 1377 if (!success) { 1378 1379 /* 1380 * We maintain the invariant that current node oid 1381 * is >= the oid provided in @name. 1382 * As there are no usable children at this node, 1383 * current node oid is strictly > than the requested 1384 * oid. 1385 * Hence, reduce namelen to 0 to allow for picking first 1386 * nodes/leafs in the next node in list. 1387 */ 1388 namelen = 0; 1389 } 1390 } 1391 if (success) 1392 break; 1393 } 1394 1395 if (success) { 1396 *next = oidp->oid_number; 1397 if (level > *len) 1398 *len = level; 1399 } 1400 1401 return (success); 1402 } 1403 1404 static int 1405 sysctl_sysctl_next(SYSCTL_HANDLER_ARGS) 1406 { 1407 int *name = (int *) arg1; 1408 u_int namelen = arg2; 1409 int len, error; 1410 bool success; 1411 struct sysctl_oid_list *lsp = &sysctl__children; 1412 struct rm_priotracker tracker; 1413 int next[CTL_MAXNAME]; 1414 1415 len = 0; 1416 SYSCTL_RLOCK(&tracker); 1417 success = sysctl_sysctl_next_action(lsp, name, namelen, next, &len, 1, 1418 oidp->oid_number == CTL_SYSCTL_NEXT); 1419 SYSCTL_RUNLOCK(&tracker); 1420 if (!success) 1421 return (ENOENT); 1422 error = SYSCTL_OUT(req, next, len * sizeof (int)); 1423 return (error); 1424 } 1425 1426 /* 1427 * XXXRW/JA: Shouldn't return next data for nodes that we don't permit in 1428 * capability mode. 1429 */ 1430 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NEXT, next, CTLFLAG_RD | 1431 CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_next, ""); 1432 1433 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NEXTNOSKIP, nextnoskip, CTLFLAG_RD | 1434 CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_next, ""); 1435 1436 static int 1437 name2oid(const char *name, int *oid, int *len, struct sysctl_oid **oidpp) 1438 { 1439 struct sysctl_oid *oidp; 1440 struct sysctl_oid_list *lsp = &sysctl__children; 1441 const char *n; 1442 1443 SYSCTL_ASSERT_LOCKED(); 1444 1445 for (*len = 0; *len < CTL_MAXNAME;) { 1446 n = strchrnul(name, '.'); 1447 oidp = sysctl_find_oidnamelen(name, n - name, lsp); 1448 if (oidp == NULL) 1449 return (ENOENT); 1450 *oid++ = oidp->oid_number; 1451 (*len)++; 1452 1453 name = n; 1454 if (*name == '.') 1455 name++; 1456 if (*name == '\0') { 1457 if (oidpp) 1458 *oidpp = oidp; 1459 return (0); 1460 } 1461 1462 if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) 1463 break; 1464 1465 if (oidp->oid_handler) 1466 break; 1467 1468 lsp = SYSCTL_CHILDREN(oidp); 1469 } 1470 return (ENOENT); 1471 } 1472 1473 static int 1474 sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS) 1475 { 1476 char *p; 1477 int error, oid[CTL_MAXNAME], len = 0; 1478 struct sysctl_oid *op = NULL; 1479 struct rm_priotracker tracker; 1480 char buf[32]; 1481 1482 if (!req->newlen) 1483 return (ENOENT); 1484 if (req->newlen >= MAXPATHLEN) /* XXX arbitrary, undocumented */ 1485 return (ENAMETOOLONG); 1486 1487 p = buf; 1488 if (req->newlen >= sizeof(buf)) 1489 p = malloc(req->newlen+1, M_SYSCTL, M_WAITOK); 1490 1491 error = SYSCTL_IN(req, p, req->newlen); 1492 if (error) { 1493 if (p != buf) 1494 free(p, M_SYSCTL); 1495 return (error); 1496 } 1497 1498 p [req->newlen] = '\0'; 1499 1500 SYSCTL_RLOCK(&tracker); 1501 error = name2oid(p, oid, &len, &op); 1502 SYSCTL_RUNLOCK(&tracker); 1503 1504 if (p != buf) 1505 free(p, M_SYSCTL); 1506 1507 if (error) 1508 return (error); 1509 1510 error = SYSCTL_OUT(req, oid, len * sizeof *oid); 1511 return (error); 1512 } 1513 1514 /* 1515 * XXXRW/JA: Shouldn't return name2oid data for nodes that we don't permit in 1516 * capability mode. 1517 */ 1518 SYSCTL_PROC(_sysctl, CTL_SYSCTL_NAME2OID, name2oid, CTLTYPE_INT | CTLFLAG_RW | 1519 CTLFLAG_ANYBODY | CTLFLAG_MPSAFE | CTLFLAG_CAPRW, 0, 0, 1520 sysctl_sysctl_name2oid, "I", ""); 1521 1522 static int 1523 sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS) 1524 { 1525 struct sysctl_oid *oid; 1526 struct rm_priotracker tracker; 1527 int error; 1528 1529 error = sysctl_wire_old_buffer(req, 0); 1530 if (error) 1531 return (error); 1532 1533 SYSCTL_RLOCK(&tracker); 1534 error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); 1535 if (error) 1536 goto out; 1537 1538 if (oid->oid_fmt == NULL) { 1539 error = ENOENT; 1540 goto out; 1541 } 1542 error = SYSCTL_OUT(req, &oid->oid_kind, sizeof(oid->oid_kind)); 1543 if (error) 1544 goto out; 1545 error = SYSCTL_OUT(req, oid->oid_fmt, strlen(oid->oid_fmt) + 1); 1546 out: 1547 SYSCTL_RUNLOCK(&tracker); 1548 return (error); 1549 } 1550 1551 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDFMT, oidfmt, CTLFLAG_RD | 1552 CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidfmt, ""); 1553 1554 static int 1555 sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS) 1556 { 1557 struct sysctl_oid *oid; 1558 struct rm_priotracker tracker; 1559 int error; 1560 1561 error = sysctl_wire_old_buffer(req, 0); 1562 if (error) 1563 return (error); 1564 1565 SYSCTL_RLOCK(&tracker); 1566 error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); 1567 if (error) 1568 goto out; 1569 1570 if (oid->oid_descr == NULL) { 1571 error = ENOENT; 1572 goto out; 1573 } 1574 error = SYSCTL_OUT(req, oid->oid_descr, strlen(oid->oid_descr) + 1); 1575 out: 1576 SYSCTL_RUNLOCK(&tracker); 1577 return (error); 1578 } 1579 1580 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDDESCR, oiddescr, CTLFLAG_RD | 1581 CTLFLAG_MPSAFE|CTLFLAG_CAPRD, sysctl_sysctl_oiddescr, ""); 1582 1583 static int 1584 sysctl_sysctl_oidlabel(SYSCTL_HANDLER_ARGS) 1585 { 1586 struct sysctl_oid *oid; 1587 struct rm_priotracker tracker; 1588 int error; 1589 1590 error = sysctl_wire_old_buffer(req, 0); 1591 if (error) 1592 return (error); 1593 1594 SYSCTL_RLOCK(&tracker); 1595 error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); 1596 if (error) 1597 goto out; 1598 1599 if (oid->oid_label == NULL) { 1600 error = ENOENT; 1601 goto out; 1602 } 1603 error = SYSCTL_OUT(req, oid->oid_label, strlen(oid->oid_label) + 1); 1604 out: 1605 SYSCTL_RUNLOCK(&tracker); 1606 return (error); 1607 } 1608 1609 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDLABEL, oidlabel, CTLFLAG_RD | 1610 CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidlabel, ""); 1611 1612 /* 1613 * Default "handler" functions. 1614 */ 1615 1616 /* 1617 * Handle a bool. 1618 * Two cases: 1619 * a variable: point arg1 at it. 1620 * a constant: pass it in arg2. 1621 */ 1622 1623 int 1624 sysctl_handle_bool(SYSCTL_HANDLER_ARGS) 1625 { 1626 uint8_t temp; 1627 int error; 1628 1629 /* 1630 * Attempt to get a coherent snapshot by making a copy of the data. 1631 */ 1632 if (arg1) 1633 temp = *(bool *)arg1 ? 1 : 0; 1634 else 1635 temp = arg2 ? 1 : 0; 1636 1637 error = SYSCTL_OUT(req, &temp, sizeof(temp)); 1638 if (error || !req->newptr) 1639 return (error); 1640 1641 if (!arg1) 1642 error = EPERM; 1643 else { 1644 error = SYSCTL_IN(req, &temp, sizeof(temp)); 1645 if (!error) 1646 *(bool *)arg1 = temp ? 1 : 0; 1647 } 1648 return (error); 1649 } 1650 1651 /* 1652 * Handle an int8_t, signed or unsigned. 1653 * Two cases: 1654 * a variable: point arg1 at it. 1655 * a constant: pass it in arg2. 1656 */ 1657 1658 int 1659 sysctl_handle_8(SYSCTL_HANDLER_ARGS) 1660 { 1661 int8_t tmpout; 1662 int error = 0; 1663 1664 /* 1665 * Attempt to get a coherent snapshot by making a copy of the data. 1666 */ 1667 if (arg1) 1668 tmpout = *(int8_t *)arg1; 1669 else 1670 tmpout = arg2; 1671 error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout)); 1672 1673 if (error || !req->newptr) 1674 return (error); 1675 1676 if (!arg1) 1677 error = EPERM; 1678 else 1679 error = SYSCTL_IN(req, arg1, sizeof(tmpout)); 1680 return (error); 1681 } 1682 1683 /* 1684 * Handle an int16_t, signed or unsigned. 1685 * Two cases: 1686 * a variable: point arg1 at it. 1687 * a constant: pass it in arg2. 1688 */ 1689 1690 int 1691 sysctl_handle_16(SYSCTL_HANDLER_ARGS) 1692 { 1693 int16_t tmpout; 1694 int error = 0; 1695 1696 /* 1697 * Attempt to get a coherent snapshot by making a copy of the data. 1698 */ 1699 if (arg1) 1700 tmpout = *(int16_t *)arg1; 1701 else 1702 tmpout = arg2; 1703 error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout)); 1704 1705 if (error || !req->newptr) 1706 return (error); 1707 1708 if (!arg1) 1709 error = EPERM; 1710 else 1711 error = SYSCTL_IN(req, arg1, sizeof(tmpout)); 1712 return (error); 1713 } 1714 1715 /* 1716 * Handle an int32_t, signed or unsigned. 1717 * Two cases: 1718 * a variable: point arg1 at it. 1719 * a constant: pass it in arg2. 1720 */ 1721 1722 int 1723 sysctl_handle_32(SYSCTL_HANDLER_ARGS) 1724 { 1725 int32_t tmpout; 1726 int error = 0; 1727 1728 /* 1729 * Attempt to get a coherent snapshot by making a copy of the data. 1730 */ 1731 if (arg1) 1732 tmpout = *(int32_t *)arg1; 1733 else 1734 tmpout = arg2; 1735 error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout)); 1736 1737 if (error || !req->newptr) 1738 return (error); 1739 1740 if (!arg1) 1741 error = EPERM; 1742 else 1743 error = SYSCTL_IN(req, arg1, sizeof(tmpout)); 1744 return (error); 1745 } 1746 1747 /* 1748 * Handle an int, signed or unsigned. 1749 * Two cases: 1750 * a variable: point arg1 at it. 1751 * a constant: pass it in arg2. 1752 */ 1753 1754 int 1755 sysctl_handle_int(SYSCTL_HANDLER_ARGS) 1756 { 1757 int tmpout, error = 0; 1758 1759 /* 1760 * Attempt to get a coherent snapshot by making a copy of the data. 1761 */ 1762 if (arg1) 1763 tmpout = *(int *)arg1; 1764 else 1765 tmpout = arg2; 1766 error = SYSCTL_OUT(req, &tmpout, sizeof(int)); 1767 1768 if (error || !req->newptr) 1769 return (error); 1770 1771 if (!arg1) 1772 error = EPERM; 1773 else 1774 error = SYSCTL_IN(req, arg1, sizeof(int)); 1775 return (error); 1776 } 1777 1778 /* 1779 * Based on sysctl_handle_int() convert milliseconds into ticks. 1780 * Note: this is used by TCP. 1781 */ 1782 1783 int 1784 sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS) 1785 { 1786 int error, s, tt; 1787 1788 tt = *(int *)arg1; 1789 s = (int)((int64_t)tt * 1000 / hz); 1790 1791 error = sysctl_handle_int(oidp, &s, 0, req); 1792 if (error || !req->newptr) 1793 return (error); 1794 1795 tt = (int)((int64_t)s * hz / 1000); 1796 if (tt < 1) 1797 return (EINVAL); 1798 1799 *(int *)arg1 = tt; 1800 return (0); 1801 } 1802 1803 /* 1804 * Handle a long, signed or unsigned. 1805 * Two cases: 1806 * a variable: point arg1 at it. 1807 * a constant: pass it in arg2. 1808 */ 1809 1810 int 1811 sysctl_handle_long(SYSCTL_HANDLER_ARGS) 1812 { 1813 int error = 0; 1814 long tmplong; 1815 #ifdef SCTL_MASK32 1816 int tmpint; 1817 #endif 1818 1819 /* 1820 * Attempt to get a coherent snapshot by making a copy of the data. 1821 */ 1822 if (arg1) 1823 tmplong = *(long *)arg1; 1824 else 1825 tmplong = arg2; 1826 #ifdef SCTL_MASK32 1827 if (req->flags & SCTL_MASK32) { 1828 tmpint = tmplong; 1829 error = SYSCTL_OUT(req, &tmpint, sizeof(int)); 1830 } else 1831 #endif 1832 error = SYSCTL_OUT(req, &tmplong, sizeof(long)); 1833 1834 if (error || !req->newptr) 1835 return (error); 1836 1837 if (!arg1) 1838 error = EPERM; 1839 #ifdef SCTL_MASK32 1840 else if (req->flags & SCTL_MASK32) { 1841 error = SYSCTL_IN(req, &tmpint, sizeof(int)); 1842 *(long *)arg1 = (long)tmpint; 1843 } 1844 #endif 1845 else 1846 error = SYSCTL_IN(req, arg1, sizeof(long)); 1847 return (error); 1848 } 1849 1850 /* 1851 * Handle a 64 bit int, signed or unsigned. 1852 * Two cases: 1853 * a variable: point arg1 at it. 1854 * a constant: pass it in arg2. 1855 */ 1856 int 1857 sysctl_handle_64(SYSCTL_HANDLER_ARGS) 1858 { 1859 int error = 0; 1860 uint64_t tmpout; 1861 1862 /* 1863 * Attempt to get a coherent snapshot by making a copy of the data. 1864 */ 1865 if (arg1) 1866 tmpout = *(uint64_t *)arg1; 1867 else 1868 tmpout = arg2; 1869 error = SYSCTL_OUT(req, &tmpout, sizeof(uint64_t)); 1870 1871 if (error || !req->newptr) 1872 return (error); 1873 1874 if (!arg1) 1875 error = EPERM; 1876 else 1877 error = SYSCTL_IN(req, arg1, sizeof(uint64_t)); 1878 return (error); 1879 } 1880 1881 /* 1882 * Handle our generic '\0' terminated 'C' string. 1883 * Two cases: 1884 * a variable string: point arg1 at it, arg2 is max length. 1885 * a constant string: point arg1 at it, arg2 is zero. 1886 */ 1887 1888 int 1889 sysctl_handle_string(SYSCTL_HANDLER_ARGS) 1890 { 1891 char *tmparg; 1892 size_t outlen; 1893 int error = 0, ro_string = 0; 1894 1895 /* 1896 * If the sysctl isn't writable and isn't a preallocated tunable that 1897 * can be modified by kenv(2), microoptimise and treat it as a 1898 * read-only string. 1899 * A zero-length buffer indicates a fixed size read-only 1900 * string. In ddb, don't worry about trying to make a malloced 1901 * snapshot. 1902 */ 1903 if ((oidp->oid_kind & (CTLFLAG_WR | CTLFLAG_TUN)) == 0 || 1904 arg2 == 0 || kdb_active) { 1905 arg2 = strlen((char *)arg1) + 1; 1906 ro_string = 1; 1907 } 1908 1909 if (req->oldptr != NULL) { 1910 if (ro_string) { 1911 tmparg = arg1; 1912 outlen = strlen(tmparg) + 1; 1913 } else { 1914 tmparg = malloc(arg2, M_SYSCTLTMP, M_WAITOK); 1915 sx_slock(&sysctlstringlock); 1916 memcpy(tmparg, arg1, arg2); 1917 sx_sunlock(&sysctlstringlock); 1918 outlen = strlen(tmparg) + 1; 1919 } 1920 1921 error = SYSCTL_OUT(req, tmparg, outlen); 1922 1923 if (!ro_string) 1924 free(tmparg, M_SYSCTLTMP); 1925 } else { 1926 if (!ro_string) 1927 sx_slock(&sysctlstringlock); 1928 outlen = strlen((char *)arg1) + 1; 1929 if (!ro_string) 1930 sx_sunlock(&sysctlstringlock); 1931 error = SYSCTL_OUT(req, NULL, outlen); 1932 } 1933 if (error || !req->newptr) 1934 return (error); 1935 1936 if (req->newlen - req->newidx >= arg2 || 1937 req->newlen - req->newidx < 0) { 1938 error = EINVAL; 1939 } else if (req->newlen - req->newidx == 0) { 1940 sx_xlock(&sysctlstringlock); 1941 ((char *)arg1)[0] = '\0'; 1942 sx_xunlock(&sysctlstringlock); 1943 } else if (req->newfunc == sysctl_new_kernel) { 1944 arg2 = req->newlen - req->newidx; 1945 sx_xlock(&sysctlstringlock); 1946 error = SYSCTL_IN(req, arg1, arg2); 1947 if (error == 0) { 1948 ((char *)arg1)[arg2] = '\0'; 1949 req->newidx += arg2; 1950 } 1951 sx_xunlock(&sysctlstringlock); 1952 } else { 1953 arg2 = req->newlen - req->newidx; 1954 tmparg = malloc(arg2, M_SYSCTLTMP, M_WAITOK); 1955 1956 error = SYSCTL_IN(req, tmparg, arg2); 1957 if (error) { 1958 free(tmparg, M_SYSCTLTMP); 1959 return (error); 1960 } 1961 1962 sx_xlock(&sysctlstringlock); 1963 memcpy(arg1, tmparg, arg2); 1964 ((char *)arg1)[arg2] = '\0'; 1965 sx_xunlock(&sysctlstringlock); 1966 free(tmparg, M_SYSCTLTMP); 1967 req->newidx += arg2; 1968 } 1969 return (error); 1970 } 1971 1972 /* 1973 * Handle any kind of opaque data. 1974 * arg1 points to it, arg2 is the size. 1975 */ 1976 1977 int 1978 sysctl_handle_opaque(SYSCTL_HANDLER_ARGS) 1979 { 1980 int error, tries; 1981 u_int generation; 1982 struct sysctl_req req2; 1983 1984 /* 1985 * Attempt to get a coherent snapshot, by using the thread 1986 * pre-emption counter updated from within mi_switch() to 1987 * determine if we were pre-empted during a bcopy() or 1988 * copyout(). Make 3 attempts at doing this before giving up. 1989 * If we encounter an error, stop immediately. 1990 */ 1991 tries = 0; 1992 req2 = *req; 1993 retry: 1994 generation = curthread->td_generation; 1995 error = SYSCTL_OUT(req, arg1, arg2); 1996 if (error) 1997 return (error); 1998 tries++; 1999 if (generation != curthread->td_generation && tries < 3) { 2000 *req = req2; 2001 goto retry; 2002 } 2003 2004 error = SYSCTL_IN(req, arg1, arg2); 2005 2006 return (error); 2007 } 2008 2009 /* 2010 * Based on sysctl_handle_64() convert microseconds to a sbintime. 2011 */ 2012 int 2013 sysctl_usec_to_sbintime(SYSCTL_HANDLER_ARGS) 2014 { 2015 int error; 2016 int64_t usec; 2017 2018 usec = sbttous(*(sbintime_t *)arg1); 2019 2020 error = sysctl_handle_64(oidp, &usec, 0, req); 2021 if (error || !req->newptr) 2022 return (error); 2023 2024 *(sbintime_t *)arg1 = ustosbt(usec); 2025 2026 return (0); 2027 } 2028 2029 /* 2030 * Based on sysctl_handle_64() convert milliseconds to a sbintime. 2031 */ 2032 int 2033 sysctl_msec_to_sbintime(SYSCTL_HANDLER_ARGS) 2034 { 2035 int error; 2036 int64_t msec; 2037 2038 msec = sbttoms(*(sbintime_t *)arg1); 2039 2040 error = sysctl_handle_64(oidp, &msec, 0, req); 2041 if (error || !req->newptr) 2042 return (error); 2043 2044 *(sbintime_t *)arg1 = mstosbt(msec); 2045 2046 return (0); 2047 } 2048 2049 /* 2050 * Convert seconds to a struct timeval. Intended for use with 2051 * intervals and thus does not permit negative seconds. 2052 */ 2053 int 2054 sysctl_sec_to_timeval(SYSCTL_HANDLER_ARGS) 2055 { 2056 struct timeval *tv; 2057 int error, secs; 2058 2059 tv = arg1; 2060 secs = tv->tv_sec; 2061 2062 error = sysctl_handle_int(oidp, &secs, 0, req); 2063 if (error || req->newptr == NULL) 2064 return (error); 2065 2066 if (secs < 0) 2067 return (EINVAL); 2068 tv->tv_sec = secs; 2069 2070 return (0); 2071 } 2072 2073 /* 2074 * Transfer functions to/from kernel space. 2075 * XXX: rather untested at this point 2076 */ 2077 static int 2078 sysctl_old_kernel(struct sysctl_req *req, const void *p, size_t l) 2079 { 2080 size_t i = 0; 2081 2082 if (req->oldptr) { 2083 i = l; 2084 if (req->oldlen <= req->oldidx) 2085 i = 0; 2086 else 2087 if (i > req->oldlen - req->oldidx) 2088 i = req->oldlen - req->oldidx; 2089 if (i > 0) 2090 bcopy(p, (char *)req->oldptr + req->oldidx, i); 2091 } 2092 req->oldidx += l; 2093 if (req->oldptr && i != l) 2094 return (ENOMEM); 2095 return (0); 2096 } 2097 2098 static int 2099 sysctl_new_kernel(struct sysctl_req *req, void *p, size_t l) 2100 { 2101 if (!req->newptr) 2102 return (0); 2103 if (req->newlen - req->newidx < l) 2104 return (EINVAL); 2105 bcopy((const char *)req->newptr + req->newidx, p, l); 2106 req->newidx += l; 2107 return (0); 2108 } 2109 2110 int 2111 kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old, 2112 size_t *oldlenp, void *new, size_t newlen, size_t *retval, int flags) 2113 { 2114 int error = 0; 2115 struct sysctl_req req; 2116 2117 bzero(&req, sizeof req); 2118 2119 req.td = td; 2120 req.flags = flags; 2121 2122 if (oldlenp) { 2123 req.oldlen = *oldlenp; 2124 } 2125 req.validlen = req.oldlen; 2126 2127 if (old) { 2128 req.oldptr= old; 2129 } 2130 2131 if (new != NULL) { 2132 req.newlen = newlen; 2133 req.newptr = new; 2134 } 2135 2136 req.oldfunc = sysctl_old_kernel; 2137 req.newfunc = sysctl_new_kernel; 2138 req.lock = REQ_UNWIRED; 2139 2140 error = sysctl_root(0, name, namelen, &req); 2141 2142 if (req.lock == REQ_WIRED && req.validlen > 0) 2143 vsunlock(req.oldptr, req.validlen); 2144 2145 if (error && error != ENOMEM) 2146 return (error); 2147 2148 if (retval) { 2149 if (req.oldptr && req.oldidx > req.validlen) 2150 *retval = req.validlen; 2151 else 2152 *retval = req.oldidx; 2153 } 2154 return (error); 2155 } 2156 2157 int 2158 kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp, 2159 void *new, size_t newlen, size_t *retval, int flags) 2160 { 2161 int oid[CTL_MAXNAME]; 2162 size_t oidlen, plen; 2163 int error; 2164 2165 oid[0] = CTL_SYSCTL; 2166 oid[1] = CTL_SYSCTL_NAME2OID; 2167 oidlen = sizeof(oid); 2168 2169 error = kernel_sysctl(td, oid, 2, oid, &oidlen, 2170 (void *)name, strlen(name), &plen, flags); 2171 if (error) 2172 return (error); 2173 2174 error = kernel_sysctl(td, oid, plen / sizeof(int), old, oldlenp, 2175 new, newlen, retval, flags); 2176 return (error); 2177 } 2178 2179 /* 2180 * Transfer function to/from user space. 2181 */ 2182 static int 2183 sysctl_old_user(struct sysctl_req *req, const void *p, size_t l) 2184 { 2185 size_t i, len, origidx; 2186 int error; 2187 2188 origidx = req->oldidx; 2189 req->oldidx += l; 2190 if (req->oldptr == NULL) 2191 return (0); 2192 /* 2193 * If we have not wired the user supplied buffer and we are currently 2194 * holding locks, drop a witness warning, as it's possible that 2195 * write operations to the user page can sleep. 2196 */ 2197 if (req->lock != REQ_WIRED) 2198 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, 2199 "sysctl_old_user()"); 2200 i = l; 2201 len = req->validlen; 2202 if (len <= origidx) 2203 i = 0; 2204 else { 2205 if (i > len - origidx) 2206 i = len - origidx; 2207 if (req->lock == REQ_WIRED) { 2208 error = copyout_nofault(p, (char *)req->oldptr + 2209 origidx, i); 2210 } else 2211 error = copyout(p, (char *)req->oldptr + origidx, i); 2212 if (error != 0) 2213 return (error); 2214 } 2215 if (i < l) 2216 return (ENOMEM); 2217 return (0); 2218 } 2219 2220 static int 2221 sysctl_new_user(struct sysctl_req *req, void *p, size_t l) 2222 { 2223 int error; 2224 2225 if (!req->newptr) 2226 return (0); 2227 if (req->newlen - req->newidx < l) 2228 return (EINVAL); 2229 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, 2230 "sysctl_new_user()"); 2231 error = copyin((const char *)req->newptr + req->newidx, p, l); 2232 req->newidx += l; 2233 return (error); 2234 } 2235 2236 /* 2237 * Wire the user space destination buffer. If set to a value greater than 2238 * zero, the len parameter limits the maximum amount of wired memory. 2239 */ 2240 int 2241 sysctl_wire_old_buffer(struct sysctl_req *req, size_t len) 2242 { 2243 int ret; 2244 size_t wiredlen; 2245 2246 wiredlen = (len > 0 && len < req->oldlen) ? len : req->oldlen; 2247 ret = 0; 2248 if (req->lock != REQ_WIRED && req->oldptr && 2249 req->oldfunc == sysctl_old_user) { 2250 if (wiredlen != 0) { 2251 ret = vslock(req->oldptr, wiredlen); 2252 if (ret != 0) { 2253 if (ret != ENOMEM) 2254 return (ret); 2255 wiredlen = 0; 2256 } 2257 } 2258 req->lock = REQ_WIRED; 2259 req->validlen = wiredlen; 2260 } 2261 return (0); 2262 } 2263 2264 int 2265 sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid, 2266 int *nindx, struct sysctl_req *req) 2267 { 2268 struct sysctl_oid_list *lsp; 2269 struct sysctl_oid *oid; 2270 struct sysctl_oid key; 2271 int indx; 2272 2273 SYSCTL_ASSERT_LOCKED(); 2274 lsp = &sysctl__children; 2275 indx = 0; 2276 while (indx < CTL_MAXNAME) { 2277 key.oid_number = name[indx]; 2278 oid = RB_FIND(sysctl_oid_list, lsp, &key); 2279 if (oid == NULL) 2280 return (ENOENT); 2281 2282 indx++; 2283 if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 2284 if (oid->oid_handler != NULL || indx == namelen) { 2285 *noid = oid; 2286 if (nindx != NULL) 2287 *nindx = indx; 2288 KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0, 2289 ("%s found DYING node %p", __func__, oid)); 2290 return (0); 2291 } 2292 lsp = SYSCTL_CHILDREN(oid); 2293 } else if (indx == namelen) { 2294 if ((oid->oid_kind & CTLFLAG_DORMANT) != 0) 2295 return (ENOENT); 2296 *noid = oid; 2297 if (nindx != NULL) 2298 *nindx = indx; 2299 KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0, 2300 ("%s found DYING node %p", __func__, oid)); 2301 return (0); 2302 } else { 2303 return (ENOTDIR); 2304 } 2305 } 2306 return (ENOENT); 2307 } 2308 2309 /* 2310 * Traverse our tree, and find the right node, execute whatever it points 2311 * to, and return the resulting error code. 2312 */ 2313 2314 static int 2315 sysctl_root(SYSCTL_HANDLER_ARGS) 2316 { 2317 struct sysctl_oid *oid; 2318 struct rm_priotracker tracker; 2319 int error, indx, lvl; 2320 2321 SYSCTL_RLOCK(&tracker); 2322 2323 error = sysctl_find_oid(arg1, arg2, &oid, &indx, req); 2324 if (error) 2325 goto out; 2326 2327 if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 2328 /* 2329 * You can't call a sysctl when it's a node, but has 2330 * no handler. Inform the user that it's a node. 2331 * The indx may or may not be the same as namelen. 2332 */ 2333 if (oid->oid_handler == NULL) { 2334 error = EISDIR; 2335 goto out; 2336 } 2337 } 2338 2339 /* Is this sysctl writable? */ 2340 if (req->newptr && !(oid->oid_kind & CTLFLAG_WR)) { 2341 error = EPERM; 2342 goto out; 2343 } 2344 2345 KASSERT(req->td != NULL, ("sysctl_root(): req->td == NULL")); 2346 2347 #ifdef CAPABILITY_MODE 2348 /* 2349 * If the process is in capability mode, then don't permit reading or 2350 * writing unless specifically granted for the node. 2351 */ 2352 if (IN_CAPABILITY_MODE(req->td)) { 2353 if ((req->oldptr && !(oid->oid_kind & CTLFLAG_CAPRD)) || 2354 (req->newptr && !(oid->oid_kind & CTLFLAG_CAPWR))) { 2355 error = EPERM; 2356 goto out; 2357 } 2358 } 2359 #endif 2360 2361 /* Is this sysctl sensitive to securelevels? */ 2362 if (req->newptr && (oid->oid_kind & CTLFLAG_SECURE)) { 2363 lvl = (oid->oid_kind & CTLMASK_SECURE) >> CTLSHIFT_SECURE; 2364 error = securelevel_gt(req->td->td_ucred, lvl); 2365 if (error) 2366 goto out; 2367 } 2368 2369 /* Is this sysctl writable by only privileged users? */ 2370 if (req->newptr && !(oid->oid_kind & CTLFLAG_ANYBODY)) { 2371 int priv; 2372 2373 if (oid->oid_kind & CTLFLAG_PRISON) 2374 priv = PRIV_SYSCTL_WRITEJAIL; 2375 #ifdef VIMAGE 2376 else if ((oid->oid_kind & CTLFLAG_VNET) && 2377 prison_owns_vnet(req->td->td_ucred)) 2378 priv = PRIV_SYSCTL_WRITEJAIL; 2379 #endif 2380 else 2381 priv = PRIV_SYSCTL_WRITE; 2382 error = priv_check(req->td, priv); 2383 if (error) 2384 goto out; 2385 } 2386 2387 if (!oid->oid_handler) { 2388 error = EINVAL; 2389 goto out; 2390 } 2391 2392 if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 2393 arg1 = (int *)arg1 + indx; 2394 arg2 -= indx; 2395 } else { 2396 arg1 = oid->oid_arg1; 2397 arg2 = oid->oid_arg2; 2398 } 2399 #ifdef MAC 2400 error = mac_system_check_sysctl(req->td->td_ucred, oid, arg1, arg2, 2401 req); 2402 if (error != 0) 2403 goto out; 2404 #endif 2405 #ifdef VIMAGE 2406 if ((oid->oid_kind & CTLFLAG_VNET) && arg1 != NULL) 2407 arg1 = (void *)(curvnet->vnet_data_base + (uintptr_t)arg1); 2408 #endif 2409 error = sysctl_root_handler_locked(oid, arg1, arg2, req, &tracker); 2410 2411 out: 2412 SYSCTL_RUNLOCK(&tracker); 2413 return (error); 2414 } 2415 2416 #ifndef _SYS_SYSPROTO_H_ 2417 struct __sysctl_args { 2418 int *name; 2419 u_int namelen; 2420 void *old; 2421 size_t *oldlenp; 2422 void *new; 2423 size_t newlen; 2424 }; 2425 #endif 2426 int 2427 sys___sysctl(struct thread *td, struct __sysctl_args *uap) 2428 { 2429 int error, i, name[CTL_MAXNAME]; 2430 size_t j; 2431 2432 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 2433 return (EINVAL); 2434 2435 error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 2436 if (error) 2437 return (error); 2438 2439 error = userland_sysctl(td, name, uap->namelen, 2440 uap->old, uap->oldlenp, 0, 2441 uap->new, uap->newlen, &j, 0); 2442 if (error && error != ENOMEM) 2443 return (error); 2444 if (uap->oldlenp) { 2445 i = copyout(&j, uap->oldlenp, sizeof(j)); 2446 if (i) 2447 return (i); 2448 } 2449 return (error); 2450 } 2451 2452 int 2453 kern___sysctlbyname(struct thread *td, const char *oname, size_t namelen, 2454 void *old, size_t *oldlenp, void *new, size_t newlen, size_t *retval, 2455 int flags, bool inkernel) 2456 { 2457 int oid[CTL_MAXNAME]; 2458 char namebuf[16]; 2459 char *name; 2460 size_t oidlen; 2461 int error; 2462 2463 if (namelen > MAXPATHLEN || namelen == 0) 2464 return (EINVAL); 2465 name = namebuf; 2466 if (namelen > sizeof(namebuf)) 2467 name = malloc(namelen, M_SYSCTL, M_WAITOK); 2468 error = copyin(oname, name, namelen); 2469 if (error != 0) 2470 goto out; 2471 2472 oid[0] = CTL_SYSCTL; 2473 oid[1] = CTL_SYSCTL_NAME2OID; 2474 oidlen = sizeof(oid); 2475 error = kernel_sysctl(td, oid, 2, oid, &oidlen, (void *)name, namelen, 2476 retval, flags); 2477 if (error != 0) 2478 goto out; 2479 error = userland_sysctl(td, oid, *retval / sizeof(int), old, oldlenp, 2480 inkernel, new, newlen, retval, flags); 2481 2482 out: 2483 if (namelen > sizeof(namebuf)) 2484 free(name, M_SYSCTL); 2485 return (error); 2486 } 2487 2488 #ifndef _SYS_SYSPROTO_H_ 2489 struct __sysctlbyname_args { 2490 const char *name; 2491 size_t namelen; 2492 void *old; 2493 size_t *oldlenp; 2494 void *new; 2495 size_t newlen; 2496 }; 2497 #endif 2498 int 2499 sys___sysctlbyname(struct thread *td, struct __sysctlbyname_args *uap) 2500 { 2501 size_t rv; 2502 int error; 2503 2504 error = kern___sysctlbyname(td, uap->name, uap->namelen, uap->old, 2505 uap->oldlenp, uap->new, uap->newlen, &rv, 0, 0); 2506 if (error != 0) 2507 return (error); 2508 if (uap->oldlenp != NULL) 2509 error = copyout(&rv, uap->oldlenp, sizeof(rv)); 2510 2511 return (error); 2512 } 2513 2514 /* 2515 * This is used from various compatibility syscalls too. That's why name 2516 * must be in kernel space. 2517 */ 2518 int 2519 userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, 2520 size_t *oldlenp, int inkernel, const void *new, size_t newlen, 2521 size_t *retval, int flags) 2522 { 2523 int error = 0, memlocked; 2524 struct sysctl_req req; 2525 2526 bzero(&req, sizeof req); 2527 2528 req.td = td; 2529 req.flags = flags; 2530 2531 if (oldlenp) { 2532 if (inkernel) { 2533 req.oldlen = *oldlenp; 2534 } else { 2535 error = copyin(oldlenp, &req.oldlen, sizeof(*oldlenp)); 2536 if (error) 2537 return (error); 2538 } 2539 } 2540 req.validlen = req.oldlen; 2541 req.oldptr = old; 2542 2543 if (new != NULL) { 2544 req.newlen = newlen; 2545 req.newptr = new; 2546 } 2547 2548 req.oldfunc = sysctl_old_user; 2549 req.newfunc = sysctl_new_user; 2550 req.lock = REQ_UNWIRED; 2551 2552 #ifdef KTRACE 2553 if (KTRPOINT(curthread, KTR_SYSCTL)) 2554 ktrsysctl(name, namelen); 2555 #endif 2556 memlocked = 0; 2557 if (req.oldptr && req.oldlen > 4 * PAGE_SIZE) { 2558 memlocked = 1; 2559 sx_xlock(&sysctlmemlock); 2560 } 2561 CURVNET_SET(TD_TO_VNET(td)); 2562 2563 for (;;) { 2564 req.oldidx = 0; 2565 req.newidx = 0; 2566 error = sysctl_root(0, name, namelen, &req); 2567 if (error != EAGAIN) 2568 break; 2569 kern_yield(PRI_USER); 2570 } 2571 2572 CURVNET_RESTORE(); 2573 2574 if (req.lock == REQ_WIRED && req.validlen > 0) 2575 vsunlock(req.oldptr, req.validlen); 2576 if (memlocked) 2577 sx_xunlock(&sysctlmemlock); 2578 2579 if (error && error != ENOMEM) 2580 return (error); 2581 2582 if (retval) { 2583 if (req.oldptr && req.oldidx > req.validlen) 2584 *retval = req.validlen; 2585 else 2586 *retval = req.oldidx; 2587 } 2588 return (error); 2589 } 2590 2591 /* 2592 * Drain into a sysctl struct. The user buffer should be wired if a page 2593 * fault would cause issue. 2594 */ 2595 static int 2596 sbuf_sysctl_drain(void *arg, const char *data, int len) 2597 { 2598 struct sysctl_req *req = arg; 2599 int error; 2600 2601 error = SYSCTL_OUT(req, data, len); 2602 KASSERT(error >= 0, ("Got unexpected negative value %d", error)); 2603 return (error == 0 ? len : -error); 2604 } 2605 2606 struct sbuf * 2607 sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length, 2608 struct sysctl_req *req) 2609 { 2610 2611 /* Supply a default buffer size if none given. */ 2612 if (buf == NULL && length == 0) 2613 length = 64; 2614 s = sbuf_new(s, buf, length, SBUF_FIXEDLEN | SBUF_INCLUDENUL); 2615 sbuf_set_drain(s, sbuf_sysctl_drain, req); 2616 return (s); 2617 } 2618 2619 #ifdef DDB 2620 2621 /* The current OID the debugger is working with */ 2622 static struct sysctl_oid *g_ddb_oid; 2623 2624 /* The current flags specified by the user */ 2625 static int g_ddb_sysctl_flags; 2626 2627 /* Check to see if the last sysctl printed */ 2628 static int g_ddb_sysctl_printed; 2629 2630 static const int ctl_sign[CTLTYPE+1] = { 2631 [CTLTYPE_INT] = 1, 2632 [CTLTYPE_LONG] = 1, 2633 [CTLTYPE_S8] = 1, 2634 [CTLTYPE_S16] = 1, 2635 [CTLTYPE_S32] = 1, 2636 [CTLTYPE_S64] = 1, 2637 }; 2638 2639 static const int ctl_size[CTLTYPE+1] = { 2640 [CTLTYPE_INT] = sizeof(int), 2641 [CTLTYPE_UINT] = sizeof(u_int), 2642 [CTLTYPE_LONG] = sizeof(long), 2643 [CTLTYPE_ULONG] = sizeof(u_long), 2644 [CTLTYPE_S8] = sizeof(int8_t), 2645 [CTLTYPE_S16] = sizeof(int16_t), 2646 [CTLTYPE_S32] = sizeof(int32_t), 2647 [CTLTYPE_S64] = sizeof(int64_t), 2648 [CTLTYPE_U8] = sizeof(uint8_t), 2649 [CTLTYPE_U16] = sizeof(uint16_t), 2650 [CTLTYPE_U32] = sizeof(uint32_t), 2651 [CTLTYPE_U64] = sizeof(uint64_t), 2652 }; 2653 2654 #define DB_SYSCTL_NAME_ONLY 0x001 /* Compare with -N */ 2655 #define DB_SYSCTL_VALUE_ONLY 0x002 /* Compare with -n */ 2656 #define DB_SYSCTL_OPAQUE 0x004 /* Compare with -o */ 2657 #define DB_SYSCTL_HEX 0x008 /* Compare with -x */ 2658 2659 #define DB_SYSCTL_SAFE_ONLY 0x100 /* Only simple types */ 2660 2661 static const char db_sysctl_modifs[] = { 2662 'N', 'n', 'o', 'x', 2663 }; 2664 2665 static const int db_sysctl_modif_values[] = { 2666 DB_SYSCTL_NAME_ONLY, DB_SYSCTL_VALUE_ONLY, 2667 DB_SYSCTL_OPAQUE, DB_SYSCTL_HEX, 2668 }; 2669 2670 /* Handlers considered safe to print while recursing */ 2671 static int (* const db_safe_handlers[])(SYSCTL_HANDLER_ARGS) = { 2672 sysctl_handle_bool, 2673 sysctl_handle_8, 2674 sysctl_handle_16, 2675 sysctl_handle_32, 2676 sysctl_handle_64, 2677 sysctl_handle_int, 2678 sysctl_handle_long, 2679 sysctl_handle_string, 2680 sysctl_handle_opaque, 2681 }; 2682 2683 /* 2684 * Use in place of sysctl_old_kernel to print sysctl values. 2685 * 2686 * Compare to the output handling in show_var from sbin/sysctl/sysctl.c 2687 */ 2688 static int 2689 sysctl_old_ddb(struct sysctl_req *req, const void *ptr, size_t len) 2690 { 2691 const u_char *val, *p; 2692 const char *sep1; 2693 size_t intlen, slen; 2694 uintmax_t umv; 2695 intmax_t mv; 2696 int sign, ctltype, hexlen, xflag, error; 2697 2698 /* Suppress false-positive GCC uninitialized variable warnings */ 2699 mv = 0; 2700 umv = 0; 2701 2702 slen = len; 2703 val = p = ptr; 2704 2705 if (ptr == NULL) { 2706 error = 0; 2707 goto out; 2708 } 2709 2710 /* We are going to print */ 2711 g_ddb_sysctl_printed = 1; 2712 2713 xflag = g_ddb_sysctl_flags & DB_SYSCTL_HEX; 2714 2715 ctltype = (g_ddb_oid->oid_kind & CTLTYPE); 2716 sign = ctl_sign[ctltype]; 2717 intlen = ctl_size[ctltype]; 2718 2719 switch (ctltype) { 2720 case CTLTYPE_NODE: 2721 case CTLTYPE_STRING: 2722 db_printf("%.*s", (int) len, (const char *) p); 2723 error = 0; 2724 goto out; 2725 2726 case CTLTYPE_INT: 2727 case CTLTYPE_UINT: 2728 case CTLTYPE_LONG: 2729 case CTLTYPE_ULONG: 2730 case CTLTYPE_S8: 2731 case CTLTYPE_S16: 2732 case CTLTYPE_S32: 2733 case CTLTYPE_S64: 2734 case CTLTYPE_U8: 2735 case CTLTYPE_U16: 2736 case CTLTYPE_U32: 2737 case CTLTYPE_U64: 2738 hexlen = 2 + (intlen * CHAR_BIT + 3) / 4; 2739 sep1 = ""; 2740 while (len >= intlen) { 2741 switch (ctltype) { 2742 case CTLTYPE_INT: 2743 case CTLTYPE_UINT: 2744 umv = *(const u_int *)p; 2745 mv = *(const int *)p; 2746 break; 2747 case CTLTYPE_LONG: 2748 case CTLTYPE_ULONG: 2749 umv = *(const u_long *)p; 2750 mv = *(const long *)p; 2751 break; 2752 case CTLTYPE_S8: 2753 case CTLTYPE_U8: 2754 umv = *(const uint8_t *)p; 2755 mv = *(const int8_t *)p; 2756 break; 2757 case CTLTYPE_S16: 2758 case CTLTYPE_U16: 2759 umv = *(const uint16_t *)p; 2760 mv = *(const int16_t *)p; 2761 break; 2762 case CTLTYPE_S32: 2763 case CTLTYPE_U32: 2764 umv = *(const uint32_t *)p; 2765 mv = *(const int32_t *)p; 2766 break; 2767 case CTLTYPE_S64: 2768 case CTLTYPE_U64: 2769 umv = *(const uint64_t *)p; 2770 mv = *(const int64_t *)p; 2771 break; 2772 } 2773 2774 db_printf("%s", sep1); 2775 if (xflag) 2776 db_printf("%#0*jx", hexlen, umv); 2777 else if (!sign) 2778 db_printf("%ju", umv); 2779 else if (g_ddb_oid->oid_fmt[1] == 'K') { 2780 /* Kelvins are currently unsupported. */ 2781 error = EOPNOTSUPP; 2782 goto out; 2783 } else 2784 db_printf("%jd", mv); 2785 2786 sep1 = " "; 2787 len -= intlen; 2788 p += intlen; 2789 } 2790 error = 0; 2791 goto out; 2792 2793 case CTLTYPE_OPAQUE: 2794 /* TODO: Support struct functions. */ 2795 2796 /* FALLTHROUGH */ 2797 default: 2798 db_printf("Format:%s Length:%zu Dump:0x", 2799 g_ddb_oid->oid_fmt, len); 2800 while (len-- && (xflag || p < val + 16)) 2801 db_printf("%02x", *p++); 2802 if (!xflag && len > 16) 2803 db_printf("..."); 2804 error = 0; 2805 goto out; 2806 } 2807 2808 out: 2809 req->oldidx += slen; 2810 return (error); 2811 } 2812 2813 /* 2814 * Avoid setting new sysctl values from the debugger 2815 */ 2816 static int 2817 sysctl_new_ddb(struct sysctl_req *req, void *p, size_t l) 2818 { 2819 2820 if (!req->newptr) 2821 return (0); 2822 2823 /* Changing sysctls from the debugger is currently unsupported */ 2824 return (EPERM); 2825 } 2826 2827 /* 2828 * Run a sysctl handler with the DDB oldfunc and newfunc attached. 2829 * Instead of copying any output to a buffer we'll dump it right to 2830 * the console. 2831 */ 2832 static int 2833 db_sysctl(struct sysctl_oid *oidp, int *name, u_int namelen, 2834 void *old, size_t *oldlenp, size_t *retval, int flags) 2835 { 2836 struct sysctl_req req; 2837 int error; 2838 2839 /* Setup the request */ 2840 bzero(&req, sizeof req); 2841 req.td = kdb_thread; 2842 req.oldfunc = sysctl_old_ddb; 2843 req.newfunc = sysctl_new_ddb; 2844 req.lock = REQ_UNWIRED; 2845 if (oldlenp) { 2846 req.oldlen = *oldlenp; 2847 } 2848 req.validlen = req.oldlen; 2849 if (old) { 2850 req.oldptr = old; 2851 } 2852 2853 /* Setup our globals for sysctl_old_ddb */ 2854 g_ddb_oid = oidp; 2855 g_ddb_sysctl_flags = flags; 2856 g_ddb_sysctl_printed = 0; 2857 2858 error = sysctl_root(0, name, namelen, &req); 2859 2860 /* Reset globals */ 2861 g_ddb_oid = NULL; 2862 g_ddb_sysctl_flags = 0; 2863 2864 if (retval) { 2865 if (req.oldptr && req.oldidx > req.validlen) 2866 *retval = req.validlen; 2867 else 2868 *retval = req.oldidx; 2869 } 2870 return (error); 2871 } 2872 2873 /* 2874 * Show a sysctl's name 2875 */ 2876 static void 2877 db_show_oid_name(int *oid, size_t nlen) 2878 { 2879 struct sysctl_oid *oidp; 2880 int qoid[CTL_MAXNAME + 2]; 2881 int error; 2882 2883 qoid[0] = CTL_SYSCTL; 2884 qoid[1] = CTL_SYSCTL_NAME; 2885 memcpy(qoid + 2, oid, nlen * sizeof(int)); 2886 2887 error = sysctl_find_oid(qoid, nlen + 2, &oidp, NULL, NULL); 2888 if (error) 2889 db_error("sysctl name oid"); 2890 2891 error = db_sysctl(oidp, qoid, nlen + 2, NULL, NULL, NULL, 0); 2892 if (error) 2893 db_error("sysctl name"); 2894 } 2895 2896 /* 2897 * Check to see if an OID is safe to print from ddb. 2898 */ 2899 static bool 2900 db_oid_safe(const struct sysctl_oid *oidp) 2901 { 2902 for (unsigned int i = 0; i < nitems(db_safe_handlers); ++i) { 2903 if (oidp->oid_handler == db_safe_handlers[i]) 2904 return (true); 2905 } 2906 2907 return (false); 2908 } 2909 2910 /* 2911 * Show a sysctl at a specific OID 2912 * Compare to the input handling in show_var from sbin/sysctl/sysctl.c 2913 */ 2914 static int 2915 db_show_oid(struct sysctl_oid *oidp, int *oid, size_t nlen, int flags) 2916 { 2917 int error, xflag, oflag, Nflag, nflag; 2918 size_t len; 2919 2920 xflag = flags & DB_SYSCTL_HEX; 2921 oflag = flags & DB_SYSCTL_OPAQUE; 2922 nflag = flags & DB_SYSCTL_VALUE_ONLY; 2923 Nflag = flags & DB_SYSCTL_NAME_ONLY; 2924 2925 if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_OPAQUE && 2926 (!xflag && !oflag)) 2927 return (0); 2928 2929 if (Nflag) { 2930 db_show_oid_name(oid, nlen); 2931 error = 0; 2932 goto out; 2933 } 2934 2935 if (!nflag) { 2936 db_show_oid_name(oid, nlen); 2937 db_printf(": "); 2938 } 2939 2940 if ((flags & DB_SYSCTL_SAFE_ONLY) && !db_oid_safe(oidp)) { 2941 db_printf("Skipping, unsafe to print while recursing."); 2942 error = 0; 2943 goto out; 2944 } 2945 2946 /* Try once, and ask about the size */ 2947 len = 0; 2948 error = db_sysctl(oidp, oid, nlen, 2949 NULL, NULL, &len, flags); 2950 if (error) 2951 goto out; 2952 2953 if (!g_ddb_sysctl_printed) 2954 /* Lie about the size */ 2955 error = db_sysctl(oidp, oid, nlen, 2956 (void *) 1, &len, NULL, flags); 2957 2958 out: 2959 db_printf("\n"); 2960 return (error); 2961 } 2962 2963 /* 2964 * Show all sysctls under a specific OID 2965 * Compare to sysctl_all from sbin/sysctl/sysctl.c 2966 */ 2967 static int 2968 db_show_sysctl_all(int *oid, size_t len, int flags) 2969 { 2970 struct sysctl_oid *oidp; 2971 int qoid[CTL_MAXNAME + 2], next[CTL_MAXNAME]; 2972 size_t nlen; 2973 2974 qoid[0] = CTL_SYSCTL; 2975 qoid[1] = CTL_SYSCTL_NEXT; 2976 if (len) { 2977 nlen = len; 2978 memcpy(&qoid[2], oid, nlen * sizeof(int)); 2979 } else { 2980 nlen = 1; 2981 qoid[2] = CTL_KERN; 2982 } 2983 for (;;) { 2984 int error; 2985 size_t nextsize = sizeof(next); 2986 2987 error = kernel_sysctl(kdb_thread, qoid, nlen + 2, 2988 next, &nextsize, NULL, 0, &nlen, 0); 2989 if (error != 0) { 2990 if (error == ENOENT) 2991 return (0); 2992 else 2993 db_error("sysctl(next)"); 2994 } 2995 2996 nlen /= sizeof(int); 2997 2998 if (nlen < (unsigned int)len) 2999 return (0); 3000 3001 if (memcmp(&oid[0], &next[0], len * sizeof(int)) != 0) 3002 return (0); 3003 3004 /* Find the OID in question */ 3005 error = sysctl_find_oid(next, nlen, &oidp, NULL, NULL); 3006 if (error) 3007 return (error); 3008 3009 (void)db_show_oid(oidp, next, nlen, flags | DB_SYSCTL_SAFE_ONLY); 3010 3011 if (db_pager_quit) 3012 return (0); 3013 3014 memcpy(&qoid[2 + len], &next[len], (nlen - len) * sizeof(int)); 3015 } 3016 } 3017 3018 /* 3019 * Show a sysctl by its user facing string 3020 */ 3021 static int 3022 db_sysctlbyname(const char *name, int flags) 3023 { 3024 struct sysctl_oid *oidp; 3025 int oid[CTL_MAXNAME]; 3026 int error, nlen; 3027 3028 error = name2oid(name, oid, &nlen, &oidp); 3029 if (error) { 3030 return (error); 3031 } 3032 3033 if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 3034 db_show_sysctl_all(oid, nlen, flags); 3035 } else { 3036 error = db_show_oid(oidp, oid, nlen, flags); 3037 } 3038 3039 return (error); 3040 } 3041 3042 static void 3043 db_sysctl_cmd_usage(void) 3044 { 3045 db_printf( 3046 " sysctl [/Nnox] <sysctl> \n" 3047 " \n" 3048 " <sysctl> The name of the sysctl to show. \n" 3049 " \n" 3050 " Show a sysctl by hooking into SYSCTL_IN and SYSCTL_OUT. \n" 3051 " This will work for most sysctls, but should not be used \n" 3052 " with sysctls that are known to malloc. \n" 3053 " \n" 3054 " While recursing any \"unsafe\" sysctls will be skipped. \n" 3055 " Call sysctl directly on the sysctl to try printing the \n" 3056 " skipped sysctl. This is unsafe and may make the ddb \n" 3057 " session unusable. \n" 3058 " \n" 3059 " Arguments: \n" 3060 " /N Display only the name of the sysctl. \n" 3061 " /n Display only the value of the sysctl. \n" 3062 " /o Display opaque values. \n" 3063 " /x Display the sysctl in hex. \n" 3064 " \n" 3065 "For example: \n" 3066 "sysctl vm.v_free_min \n" 3067 "vn.v_free_min: 12669 \n" 3068 ); 3069 } 3070 3071 /* 3072 * Show a specific sysctl similar to sysctl (8). 3073 */ 3074 DB_COMMAND_FLAGS(sysctl, db_sysctl_cmd, CS_OWN) 3075 { 3076 char name[TOK_STRING_SIZE]; 3077 int error, i, t, flags; 3078 3079 /* Parse the modifiers */ 3080 t = db_read_token(); 3081 if (t == tSLASH || t == tMINUS) { 3082 t = db_read_token(); 3083 if (t != tIDENT) { 3084 db_printf("Bad modifier\n"); 3085 error = EINVAL; 3086 goto out; 3087 } 3088 db_strcpy(modif, db_tok_string); 3089 } 3090 else { 3091 db_unread_token(t); 3092 modif[0] = '\0'; 3093 } 3094 3095 flags = 0; 3096 for (i = 0; i < nitems(db_sysctl_modifs); i++) { 3097 if (strchr(modif, db_sysctl_modifs[i])) { 3098 flags |= db_sysctl_modif_values[i]; 3099 } 3100 } 3101 3102 /* Parse the sysctl names */ 3103 t = db_read_token(); 3104 if (t != tIDENT) { 3105 db_printf("Need sysctl name\n"); 3106 error = EINVAL; 3107 goto out; 3108 } 3109 3110 /* Copy the name into a temporary buffer */ 3111 db_strcpy(name, db_tok_string); 3112 3113 /* Ensure there is no trailing cruft */ 3114 t = db_read_token(); 3115 if (t != tEOL) { 3116 db_printf("Unexpected sysctl argument\n"); 3117 error = EINVAL; 3118 goto out; 3119 } 3120 3121 error = db_sysctlbyname(name, flags); 3122 if (error == ENOENT) { 3123 db_printf("unknown oid: '%s'\n", db_tok_string); 3124 goto out; 3125 } else if (error) { 3126 db_printf("%s: error: %d\n", db_tok_string, error); 3127 goto out; 3128 } 3129 3130 out: 3131 /* Ensure we eat all of our text */ 3132 db_flush_lex(); 3133 3134 if (error == EINVAL) { 3135 db_sysctl_cmd_usage(); 3136 } 3137 } 3138 3139 #endif /* DDB */ 3140