1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2019 Isilon Systems, LLC. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 /* 29 * netgdb.c 30 * FreeBSD subsystem supporting debugging the FreeBSD kernel over the network. 31 * 32 * There are three pieces necessary to use NetGDB. 33 * 34 * First, a dedicated proxy server must be running to accept connections from 35 * both NetGDB and gdb(1), and pass bidirectional traffic between the two 36 * protocols. 37 * 38 * Second, The NetGDB client is activated much like ordinary 'gdb' and 39 * similarly to 'netdump' in ddb(4). Like other debugnet(4) clients 40 * (netdump(4)), the network interface on the route to the proxy server must be 41 * online and support debugnet(4). 42 * 43 * Finally, the remote (k)gdb(1) uses 'target remote <proxy>:<port>' to connect 44 * to the proxy server. 45 * 46 * NetGDBv1 speaks the literal GDB remote serial protocol, and uses a 1:1 47 * relationship between GDB packets and plain debugnet packets. There is no 48 * encryption utilized to keep debugging sessions private, so this is only 49 * appropriate for local segments or trusted networks. 50 */ 51 52 #include <sys/cdefs.h> 53 __FBSDID("$FreeBSD$"); 54 55 #include "opt_ddb.h" 56 #ifndef DDB 57 #error "NetGDB cannot be used without DDB at this time" 58 #endif 59 60 #include <sys/errno.h> 61 #include <sys/param.h> 62 #include <sys/kdb.h> 63 #include <sys/sbuf.h> 64 #include <sys/socket.h> 65 #include <sys/sysctl.h> 66 #include <sys/ttydefaults.h> 67 68 #include <machine/gdb_machdep.h> 69 70 #ifdef DDB 71 #include <ddb/ddb.h> 72 #include <ddb/db_command.h> 73 #include <ddb/db_lex.h> 74 #endif 75 76 #include <net/debugnet.h> 77 #include <net/if.h> 78 #include <net/if_var.h> 79 #include <net/route.h> 80 81 #include <gdb/gdb.h> 82 #include <gdb/gdb_int.h> 83 #include <gdb/netgdb.h> 84 85 FEATURE(netgdb, "NetGDB support"); 86 SYSCTL_NODE(_debug_gdb, OID_AUTO, netgdb, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 87 "NetGDB parameters"); 88 89 static unsigned netgdb_debug; 90 SYSCTL_UINT(_debug_gdb_netgdb, OID_AUTO, debug, CTLFLAG_RWTUN, 91 &netgdb_debug, 0, 92 "Debug message verbosity (0: off; 1: on)"); 93 94 #define NETGDB_DEBUG(f, ...) do { \ 95 if (netgdb_debug > 0) \ 96 printf(("%s [%s:%d]: " f), __func__, __FILE__, __LINE__, ## \ 97 __VA_ARGS__); \ 98 } while (false) 99 100 static void netgdb_fini(void); 101 102 /* Runtime state. */ 103 static char netgdb_rxbuf[GDB_BUFSZ + 16]; /* Some overhead for framing. */ 104 static struct sbuf netgdb_rxsb; 105 static ssize_t netgdb_rx_off; 106 107 static struct debugnet_pcb *netgdb_conn; 108 static struct gdb_dbgport *netgdb_prev_dbgport; 109 static int *netgdb_prev_kdb_inactive; 110 111 /* TODO(CEM) disable ack mode */ 112 113 /* 114 * Attempt to accept the incoming packet. If we run into ENOBUFS or another 115 * error, return it. 116 * 117 * The mbuf chain will have all framing headers removed (ethernet, inet, udp, 118 * debugnet). 119 */ 120 static int 121 netgdb_rx(struct mbuf *m) 122 { 123 uint32_t rlen, count; 124 125 rlen = m->m_pkthdr.len; 126 #define _SBUF_FREESPACE(s) ((s)->s_size - ((s)->s_len + 1)) 127 if (_SBUF_FREESPACE(&netgdb_rxsb) < rlen) { 128 NETGDB_DEBUG("Backpressure: Not ACKing RX of packet that " 129 "would overflow our buffer (%zd/%zd used).\n", 130 netgdb_rxsb.s_len, netgdb_rxsb.s_size); 131 return (ENOBUFS); 132 } 133 #undef _SBUF_FREESPACE 134 135 /* 136 * Inlined m_apply -- why isn't there a macro or inline function 137 * version? 138 */ 139 while (m != NULL && m->m_len == 0) 140 m = m->m_next; 141 while (rlen > 0) { 142 MPASS(m != NULL && m->m_len >= 0); 143 count = min((uint32_t)m->m_len, rlen); 144 (void)sbuf_bcat(&netgdb_rxsb, mtod(m, const void *), count); 145 rlen -= count; 146 m = m->m_next; 147 } 148 return (0); 149 } 150 151 static void 152 netgdb_finish(void) 153 { 154 sbuf_putc(&netgdb_rxsb, CTRL('C')); 155 } 156 157 /* 158 * The following routines implement a pseudo GDB debugport (an emulated serial 159 * driver that the MI gdb(4) code does I/O with). 160 */ 161 162 static int 163 netgdb_dbg_getc(void) 164 { 165 int c; 166 167 while (true) { 168 /* Pull bytes off any currently cached packet first. */ 169 if (netgdb_rx_off < sbuf_len(&netgdb_rxsb)) { 170 c = netgdb_rxsb.s_buf[netgdb_rx_off]; 171 netgdb_rx_off++; 172 break; 173 } 174 175 /* Reached EOF? Reuse buffer. */ 176 sbuf_clear(&netgdb_rxsb); 177 netgdb_rx_off = 0; 178 179 /* Check for CTRL-C on console/serial, if any. */ 180 if (netgdb_prev_dbgport != NULL) { 181 c = netgdb_prev_dbgport->gdb_getc(); 182 if (c == CTRL('C')) 183 break; 184 } 185 186 debugnet_network_poll(netgdb_conn); 187 } 188 189 if (c == CTRL('C')) { 190 netgdb_fini(); 191 /* Caller gdb_getc() will print that we got ^C. */ 192 } 193 return (c); 194 } 195 196 static void 197 netgdb_dbg_sendpacket(const void *buf, size_t len) 198 { 199 struct debugnet_proto_aux aux; 200 int error; 201 202 MPASS(len <= UINT32_MAX); 203 204 /* 205 * GDB packet boundaries matter. debugnet_send() fragments a single 206 * request into many sequential debugnet messages. Mark full packet 207 * length and offset for potential reassembly by the proxy. 208 */ 209 aux = (struct debugnet_proto_aux) { 210 .dp_aux2 = len, 211 }; 212 213 error = debugnet_send(netgdb_conn, DEBUGNET_DATA, buf, len, &aux); 214 if (error != 0) { 215 printf("%s: Network error: %d; trying to switch back to ddb.\n", 216 __func__, error); 217 netgdb_fini(); 218 219 if (kdb_dbbe_select("ddb") != 0) 220 printf("The ddb backend could not be selected.\n"); 221 else { 222 printf("using longjmp, hope it works!\n"); 223 kdb_reenter(); 224 } 225 } 226 227 } 228 229 /* Just used for + / - GDB-level ACKs. */ 230 static void 231 netgdb_dbg_putc(int i) 232 { 233 char c; 234 235 c = i; 236 netgdb_dbg_sendpacket(&c, 1); 237 238 } 239 240 static struct gdb_dbgport netgdb_gdb_dbgport = { 241 .gdb_name = "netgdb", 242 .gdb_getc = netgdb_dbg_getc, 243 .gdb_putc = netgdb_dbg_putc, 244 .gdb_term = netgdb_fini, 245 .gdb_sendpacket = netgdb_dbg_sendpacket, 246 .gdb_dbfeatures = GDB_DBGP_FEAT_WANTTERM | GDB_DBGP_FEAT_RELIABLE, 247 }; 248 249 static void 250 netgdb_init(void) 251 { 252 struct kdb_dbbe *be, **iter; 253 254 /* 255 * Force enable GDB. (If no other debugports were registered at boot, 256 * KDB thinks it doesn't exist.) 257 */ 258 SET_FOREACH(iter, kdb_dbbe_set) { 259 be = *iter; 260 if (strcmp(be->dbbe_name, "gdb") != 0) 261 continue; 262 if (be->dbbe_active == -1) { 263 netgdb_prev_kdb_inactive = &be->dbbe_active; 264 be->dbbe_active = 0; 265 } 266 break; 267 } 268 269 /* Force netgdb debugport. */ 270 netgdb_prev_dbgport = gdb_cur; 271 gdb_cur = &netgdb_gdb_dbgport; 272 273 sbuf_new(&netgdb_rxsb, netgdb_rxbuf, sizeof(netgdb_rxbuf), 274 SBUF_FIXEDLEN); 275 netgdb_rx_off = 0; 276 } 277 278 static void 279 netgdb_fini(void) 280 { 281 282 /* TODO: tear down conn gracefully? */ 283 if (netgdb_conn != NULL) { 284 debugnet_free(netgdb_conn); 285 netgdb_conn = NULL; 286 } 287 288 sbuf_delete(&netgdb_rxsb); 289 290 gdb_cur = netgdb_prev_dbgport; 291 292 if (netgdb_prev_kdb_inactive != NULL) { 293 *netgdb_prev_kdb_inactive = -1; 294 netgdb_prev_kdb_inactive = NULL; 295 } 296 } 297 298 #ifdef DDB 299 /* 300 * Usage: netgdb -s <server> [-g <gateway -c <localip> -i <interface>] 301 * 302 * Order is not significant. 303 * 304 * Currently, this command does not support configuring encryption or 305 * compression. 306 */ 307 DB_COMMAND_FLAGS(netgdb, db_netgdb_cmd, CS_OWN) 308 { 309 struct debugnet_ddb_config params; 310 struct debugnet_conn_params dcp; 311 struct debugnet_pcb *pcb; 312 char proxy_buf[INET_ADDRSTRLEN]; 313 int error; 314 315 if (!KERNEL_PANICKED()) { 316 /* TODO: This limitation should be removed in future work. */ 317 printf("%s: netgdb is currently limited to use only after a " 318 "panic. Sorry.\n", __func__); 319 return; 320 } 321 322 error = debugnet_parse_ddb_cmd("netgdb", ¶ms); 323 if (error != 0) { 324 db_printf("Error configuring netgdb: %d\n", error); 325 return; 326 } 327 328 /* 329 * Must initialize netgdb_rxsb before debugnet_connect(), because we 330 * might be getting rx handler callbacks from the send->poll path 331 * during debugnet_connect(). 332 */ 333 netgdb_init(); 334 335 if (!params.dd_has_client) 336 params.dd_client = INADDR_ANY; 337 if (!params.dd_has_gateway) 338 params.dd_gateway = INADDR_ANY; 339 340 dcp = (struct debugnet_conn_params) { 341 .dc_ifp = params.dd_ifp, 342 .dc_client = params.dd_client, 343 .dc_server = params.dd_server, 344 .dc_gateway = params.dd_gateway, 345 .dc_herald_port = NETGDB_HERALDPORT, 346 .dc_client_port = NETGDB_CLIENTPORT, 347 .dc_herald_aux2 = NETGDB_PROTO_V1, 348 .dc_rx_handler = netgdb_rx, 349 .dc_finish_handler = netgdb_finish, 350 }; 351 352 error = debugnet_connect(&dcp, &pcb); 353 if (error != 0) { 354 printf("failed to contact netgdb server: %d\n", error); 355 netgdb_fini(); 356 return; 357 } 358 359 netgdb_conn = pcb; 360 361 if (kdb_dbbe_select("gdb") != 0) { 362 db_printf("The remote GDB backend could not be selected.\n"); 363 netgdb_fini(); 364 return; 365 } 366 367 /* 368 * Mark that we are done in ddb(4). Return -> kdb_trap() should 369 * re-enter with the new backend. 370 */ 371 db_cmd_loop_done = 1; 372 gdb_return_to_ddb = true; 373 db_printf("(detaching GDB will return control to DDB)\n"); 374 375 const in_addr_t *proxy_addr = debugnet_get_server_addr(netgdb_conn); 376 const uint16_t proxy_port = debugnet_get_server_port(netgdb_conn) + 1; 377 inet_ntop(AF_INET, proxy_addr, proxy_buf, sizeof(proxy_buf)); 378 if (inet_ntop(AF_INET, proxy_addr, proxy_buf, sizeof(proxy_buf)) == NULL) { 379 db_printf("Connected to proxy. " 380 "Use target remote <proxy address>:%hu to begin debugging.\n", 381 proxy_port); 382 } else { 383 db_printf("Connected to proxy. " 384 "Use target remote %s:%hu to begin debugging.\n", 385 proxy_buf, proxy_port); 386 } 387 #if 0 388 /* Aspirational, but does not work reliably. */ 389 db_printf("(ctrl-c will return control to ddb)\n"); 390 #endif 391 } 392 #endif /* DDB */ 393