1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2007 Robert N. M. Watson 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /*- 30 * Simple DDB scripting mechanism. Each script consists of a named list of 31 * DDB commands to execute sequentially. A more sophisticated scripting 32 * language might be desirable, but would be significantly more complex to 33 * implement. A more interesting syntax might allow general use of variables 34 * and extracting of useful values, such as a thread's process identifier, 35 * for passing into further DDB commands. Certain scripts are run 36 * automatically at kdb_enter(), if defined, based on how the debugger is 37 * entered, allowing scripted responses to panics, break signals, etc. 38 * 39 * Scripts may be managed from within DDB using the script, scripts, and 40 * unscript commands. They may also be managed from userspace using ddb(8), 41 * which operates using a set of sysctls. 42 * 43 * TODO: 44 * - Allow scripts to be defined using tunables so that they can be defined 45 * before boot and be present in single-user mode without boot scripts 46 * running. 47 * - Memory allocation is not possible from within DDB, so we use a set of 48 * statically allocated buffers to hold defined scripts. However, when 49 * scripts are being defined from userspace via sysctl, we could in fact be 50 * using malloc(9) and therefore not impose a static limit, giving greater 51 * flexibility and avoiding hard-defined buffer limits. 52 * - When scripts run automatically on entrance to DDB, placing "continue" at 53 * the end still results in being in the debugger, as we unconditionally 54 * run db_command_loop() after the script. There should be a way to avoid 55 * this. 56 */ 57 58 #include <sys/param.h> 59 #include <sys/kdb.h> 60 #include <sys/kernel.h> 61 #include <sys/libkern.h> 62 #include <sys/lock.h> 63 #include <sys/malloc.h> 64 #include <sys/mutex.h> 65 #include <sys/sbuf.h> 66 #include <sys/sysctl.h> 67 #include <sys/systm.h> 68 69 #include <ddb/ddb.h> 70 #include <ddb/db_command.h> 71 #include <ddb/db_lex.h> 72 73 #include <machine/setjmp.h> 74 75 /* 76 * struct ddb_script describes an individual script. 77 */ 78 struct ddb_script { 79 char ds_scriptname[DB_MAXSCRIPTNAME]; 80 char ds_script[DB_MAXSCRIPTLEN]; 81 }; 82 83 /* 84 * Global list of scripts -- defined scripts have non-empty name fields. 85 */ 86 static struct ddb_script db_script_table[DB_MAXSCRIPTS]; 87 88 /* 89 * While executing a script, we parse it using strsep(), so require a 90 * temporary buffer that may be used destructively. Since we support weak 91 * recursion of scripts (one may reference another), we need one buffer for 92 * each concurrently executing script. 93 */ 94 static struct db_recursion_data { 95 char drd_buffer[DB_MAXSCRIPTLEN]; 96 } db_recursion_data[DB_MAXSCRIPTRECURSION]; 97 static int db_recursion = -1; 98 99 /* 100 * We use a separate static buffer for script validation so that it is safe 101 * to validate scripts from within a script. This is used only in 102 * db_script_valid(), which should never be called reentrantly. 103 */ 104 static char db_static_buffer[DB_MAXSCRIPTLEN]; 105 106 /* 107 * Synchronization is not required from within the debugger, as it is 108 * singe-threaded (although reentrance must be carefully considered). 109 * However, it is required when interacting with scripts from user space 110 * processes. Sysctl procedures acquire db_script_mtx before accessing the 111 * global script data structures. 112 */ 113 static struct mtx db_script_mtx; 114 MTX_SYSINIT(db_script_mtx, &db_script_mtx, "db_script_mtx", MTX_DEF); 115 116 /* 117 * Some script names have special meaning, such as those executed 118 * automatically when KDB is entered. 119 */ 120 #define DB_SCRIPT_KDBENTER_PREFIX "kdb.enter" /* KDB has entered. */ 121 #define DB_SCRIPT_KDBENTER_DEFAULT "kdb.enter.default" 122 123 /* 124 * Find the existing script slot for a named script, if any. 125 */ 126 static struct ddb_script * 127 db_script_lookup(const char *scriptname) 128 { 129 int i; 130 131 for (i = 0; i < DB_MAXSCRIPTS; i++) { 132 if (strcmp(db_script_table[i].ds_scriptname, scriptname) == 133 0) 134 return (&db_script_table[i]); 135 } 136 return (NULL); 137 } 138 139 /* 140 * Find a new slot for a script, if available. Does not mark as allocated in 141 * any way--this must be done by the caller. 142 */ 143 static struct ddb_script * 144 db_script_new(void) 145 { 146 int i; 147 148 for (i = 0; i < DB_MAXSCRIPTS; i++) { 149 if (strlen(db_script_table[i].ds_scriptname) == 0) 150 return (&db_script_table[i]); 151 } 152 return (NULL); 153 } 154 155 /* 156 * Perform very rudimentary validation of a proposed script. It would be 157 * easy to imagine something more comprehensive. The script string is 158 * validated in a static buffer. 159 */ 160 static int 161 db_script_valid(const char *scriptname, const char *script) 162 { 163 char *buffer, *command; 164 165 if (strlen(scriptname) == 0) 166 return (EINVAL); 167 if (strlen(scriptname) >= DB_MAXSCRIPTNAME) 168 return (EINVAL); 169 if (strlen(script) >= DB_MAXSCRIPTLEN) 170 return (EINVAL); 171 buffer = db_static_buffer; 172 strcpy(buffer, script); 173 while ((command = strsep(&buffer, ";")) != NULL) { 174 if (strlen(command) >= DB_MAXLINE) 175 return (EINVAL); 176 } 177 return (0); 178 } 179 180 /* 181 * Modify an existing script or add a new script with the specified script 182 * name and contents. If there are no script slots available, an error will 183 * be returned. 184 */ 185 static int 186 db_script_set(const char *scriptname, const char *script) 187 { 188 struct ddb_script *dsp; 189 int error; 190 191 error = db_script_valid(scriptname, script); 192 if (error) 193 return (error); 194 dsp = db_script_lookup(scriptname); 195 if (dsp == NULL) { 196 dsp = db_script_new(); 197 if (dsp == NULL) 198 return (ENOSPC); 199 strlcpy(dsp->ds_scriptname, scriptname, 200 sizeof(dsp->ds_scriptname)); 201 } 202 strlcpy(dsp->ds_script, script, sizeof(dsp->ds_script)); 203 return (0); 204 } 205 206 /* 207 * Delete an existing script by name, if found. 208 */ 209 static int 210 db_script_unset(const char *scriptname) 211 { 212 struct ddb_script *dsp; 213 214 dsp = db_script_lookup(scriptname); 215 if (dsp == NULL) 216 return (ENOENT); 217 strcpy(dsp->ds_scriptname, ""); 218 strcpy(dsp->ds_script, ""); 219 return (0); 220 } 221 222 /* 223 * Trim leading/trailing white space in a command so that we don't pass 224 * carriage returns, etc, into DDB command parser. 225 */ 226 static int 227 db_command_trimmable(char ch) 228 { 229 230 switch (ch) { 231 case ' ': 232 case '\t': 233 case '\n': 234 case '\r': 235 return (1); 236 237 default: 238 return (0); 239 } 240 } 241 242 static void 243 db_command_trim(char **commandp) 244 { 245 char *command; 246 247 command = *commandp; 248 while (db_command_trimmable(*command)) 249 command++; 250 while ((strlen(command) > 0) && 251 db_command_trimmable(command[strlen(command) - 1])) 252 command[strlen(command) - 1] = 0; 253 *commandp = command; 254 } 255 256 /* 257 * Execute a script, breaking it up into individual commands and passing them 258 * sequentially into DDB's input processing. Use the KDB jump buffer to 259 * restore control to the main script loop if things get too wonky when 260 * processing a command -- i.e., traps, etc. Also, make sure we don't exceed 261 * practical limits on recursion. 262 * 263 * XXXRW: If any individual command is too long, it will be truncated when 264 * injected into the input at a lower layer. We should validate the script 265 * before configuring it to avoid this scenario. 266 */ 267 static int 268 db_script_exec(const char *scriptname, int warnifnotfound) 269 { 270 struct db_recursion_data *drd; 271 struct ddb_script *dsp; 272 char *buffer, *command; 273 void *prev_jb; 274 jmp_buf jb; 275 276 dsp = db_script_lookup(scriptname); 277 if (dsp == NULL) { 278 if (warnifnotfound) 279 db_printf("script '%s' not found\n", scriptname); 280 return (ENOENT); 281 } 282 283 if (db_recursion >= DB_MAXSCRIPTRECURSION) { 284 db_printf("Script stack too deep\n"); 285 return (E2BIG); 286 } 287 db_recursion++; 288 drd = &db_recursion_data[db_recursion]; 289 290 /* 291 * Parse script in temporary buffer, since strsep() is destructive. 292 */ 293 buffer = drd->drd_buffer; 294 strcpy(buffer, dsp->ds_script); 295 while ((command = strsep(&buffer, ";")) != NULL) { 296 db_printf("db:%d:%s> %s\n", db_recursion, dsp->ds_scriptname, 297 command); 298 db_command_trim(&command); 299 prev_jb = kdb_jmpbuf(jb); 300 if (setjmp(jb) == 0) 301 db_command_script(command); 302 else 303 db_printf("Script command '%s' returned error\n", 304 command); 305 kdb_jmpbuf(prev_jb); 306 } 307 db_recursion--; 308 return (0); 309 } 310 311 /* 312 * Wrapper for exec path that is called on KDB enter. Map reason for KDB 313 * enter to a script name, and don't whine if the script doesn't exist. If 314 * there is no matching script, try the catch-all script. 315 */ 316 void 317 db_script_kdbenter(const char *eventname) 318 { 319 char scriptname[DB_MAXSCRIPTNAME]; 320 321 snprintf(scriptname, sizeof(scriptname), "%s.%s", 322 DB_SCRIPT_KDBENTER_PREFIX, eventname); 323 if (db_script_exec(scriptname, 0) == ENOENT) 324 (void)db_script_exec(DB_SCRIPT_KDBENTER_DEFAULT, 0); 325 } 326 327 /*- 328 * DDB commands for scripting, as reached via the DDB user interface: 329 * 330 * scripts - lists scripts 331 * run <scriptname> - run a script 332 * script <scriptname> - prints script 333 * script <scriptname> <script> - set a script 334 * unscript <scriptname> - remove a script 335 */ 336 337 /* 338 * List scripts and their contents. 339 */ 340 void 341 db_scripts_cmd(db_expr_t addr, bool have_addr, db_expr_t count, 342 char *modif) 343 { 344 int i; 345 346 for (i = 0; i < DB_MAXSCRIPTS; i++) { 347 if (strlen(db_script_table[i].ds_scriptname) != 0) { 348 db_printf("%s=%s\n", 349 db_script_table[i].ds_scriptname, 350 db_script_table[i].ds_script); 351 } 352 } 353 } 354 355 /* 356 * Execute a script. 357 */ 358 void 359 db_run_cmd(db_expr_t addr, bool have_addr, db_expr_t count, char *modif) 360 { 361 int t; 362 363 /* 364 * Right now, we accept exactly one argument. In the future, we 365 * might want to accept flags and arguments to the script itself. 366 */ 367 t = db_read_token(); 368 if (t != tIDENT) 369 db_error("?\n"); 370 371 if (db_read_token() != tEOL) 372 db_error("?\n"); 373 374 db_script_exec(db_tok_string, 1); 375 } 376 377 /* 378 * Print or set a named script, with the set portion broken out into its own 379 * function. We must directly access the remainder of the DDB line input as 380 * we do not wish to use db_lex's token processing. 381 */ 382 void 383 db_script_cmd(db_expr_t addr, bool have_addr, db_expr_t count, 384 char *modif) 385 { 386 char *buf, scriptname[DB_MAXSCRIPTNAME]; 387 struct ddb_script *dsp; 388 int error, t; 389 390 t = db_read_token(); 391 if (t != tIDENT) { 392 db_printf("usage: script scriptname=script\n"); 393 db_skip_to_eol(); 394 return; 395 } 396 397 if (strlcpy(scriptname, db_tok_string, sizeof(scriptname)) >= 398 sizeof(scriptname)) { 399 db_printf("scriptname too long\n"); 400 db_skip_to_eol(); 401 return; 402 } 403 404 t = db_read_token(); 405 if (t == tEOL) { 406 dsp = db_script_lookup(scriptname); 407 if (dsp == NULL) { 408 db_printf("script '%s' not found\n", scriptname); 409 db_skip_to_eol(); 410 return; 411 } 412 db_printf("%s=%s\n", scriptname, dsp->ds_script); 413 } else if (t == tEQ) { 414 buf = db_get_line(); 415 if (buf[strlen(buf)-1] == '\n') 416 buf[strlen(buf)-1] = '\0'; 417 error = db_script_set(scriptname, buf); 418 if (error != 0) 419 db_printf("Error: %d\n", error); 420 } else 421 db_printf("?\n"); 422 db_skip_to_eol(); 423 } 424 425 /* 426 * Remove a named script. 427 */ 428 void 429 db_unscript_cmd(db_expr_t addr, bool have_addr, db_expr_t count, 430 char *modif) 431 { 432 int error, t; 433 434 t = db_read_token(); 435 if (t != tIDENT) { 436 db_printf("?\n"); 437 db_skip_to_eol(); 438 return; 439 } 440 441 error = db_script_unset(db_tok_string); 442 if (error == ENOENT) { 443 db_printf("script '%s' not found\n", db_tok_string); 444 db_skip_to_eol(); 445 return; 446 } 447 db_skip_to_eol(); 448 } 449 450 /* 451 * Sysctls for managing DDB scripting: 452 * 453 * debug.ddb.scripting.script - Define a new script 454 * debug.ddb.scripting.scripts - List of names *and* scripts 455 * debug.ddb.scripting.unscript - Remove an existing script 456 * 457 * Since we don't want to try to manage arbitrary extensions to the sysctl 458 * name space from the debugger, the script/unscript sysctls are a bit more 459 * like RPCs and a bit less like normal get/set requests. The ddb(8) command 460 * line tool wraps them to make things a bit more user-friendly. 461 */ 462 static SYSCTL_NODE(_debug_ddb, OID_AUTO, scripting, 463 CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 464 "DDB script settings"); 465 466 static int 467 sysctl_debug_ddb_scripting_scripts(SYSCTL_HANDLER_ARGS) 468 { 469 struct sbuf sb; 470 int error, i, len; 471 char *buffer; 472 473 /* 474 * Make space to include a maximum-length name, = symbol, 475 * maximum-length script, and carriage return for every script that 476 * may be defined. 477 */ 478 len = DB_MAXSCRIPTS * (DB_MAXSCRIPTNAME + 1 + DB_MAXSCRIPTLEN + 1); 479 buffer = malloc(len, M_TEMP, M_WAITOK); 480 (void)sbuf_new(&sb, buffer, len, SBUF_FIXEDLEN); 481 mtx_lock(&db_script_mtx); 482 for (i = 0; i < DB_MAXSCRIPTS; i++) { 483 if (strlen(db_script_table[i].ds_scriptname) == 0) 484 continue; 485 (void)sbuf_printf(&sb, "%s=%s\n", 486 db_script_table[i].ds_scriptname, 487 db_script_table[i].ds_script); 488 } 489 mtx_unlock(&db_script_mtx); 490 sbuf_finish(&sb); 491 error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb) + 1); 492 sbuf_delete(&sb); 493 free(buffer, M_TEMP); 494 return (error); 495 } 496 SYSCTL_PROC(_debug_ddb_scripting, OID_AUTO, scripts, 497 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 0, 498 sysctl_debug_ddb_scripting_scripts, "A", 499 "List of defined scripts"); 500 501 static int 502 sysctl_debug_ddb_scripting_script(SYSCTL_HANDLER_ARGS) 503 { 504 char *buffer, *script, *scriptname; 505 int error, len; 506 507 /* 508 * Maximum length for an input string is DB_MAXSCRIPTNAME + '=' 509 * symbol + DB_MAXSCRIPT. 510 */ 511 len = DB_MAXSCRIPTNAME + DB_MAXSCRIPTLEN + 1; 512 buffer = malloc(len, M_TEMP, M_WAITOK | M_ZERO); 513 error = sysctl_handle_string(oidp, buffer, len, req); 514 if (error) 515 goto out; 516 517 /* 518 * Argument will be in form scriptname=script, so split into the 519 * scriptname and script. 520 */ 521 script = buffer; 522 scriptname = strsep(&script, "="); 523 if (script == NULL) { 524 error = EINVAL; 525 goto out; 526 } 527 mtx_lock(&db_script_mtx); 528 error = db_script_set(scriptname, script); 529 mtx_unlock(&db_script_mtx); 530 out: 531 free(buffer, M_TEMP); 532 return (error); 533 } 534 SYSCTL_PROC(_debug_ddb_scripting, OID_AUTO, script, 535 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0, 536 sysctl_debug_ddb_scripting_script, "A", 537 "Set a script"); 538 539 /* 540 * debug.ddb.scripting.unscript has somewhat unusual sysctl semantics -- set 541 * the name of the script that you want to delete. 542 */ 543 static int 544 sysctl_debug_ddb_scripting_unscript(SYSCTL_HANDLER_ARGS) 545 { 546 char name[DB_MAXSCRIPTNAME]; 547 int error; 548 549 bzero(name, sizeof(name)); 550 error = sysctl_handle_string(oidp, name, sizeof(name), req); 551 if (error) 552 return (error); 553 if (req->newptr == NULL) 554 return (0); 555 mtx_lock(&db_script_mtx); 556 error = db_script_unset(name); 557 mtx_unlock(&db_script_mtx); 558 if (error == ENOENT) 559 return (EINVAL); /* Don't confuse sysctl consumers. */ 560 return (0); 561 } 562 SYSCTL_PROC(_debug_ddb_scripting, OID_AUTO, unscript, 563 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0, 564 sysctl_debug_ddb_scripting_unscript, "A", 565 "Unset a script"); 566