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