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