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