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