Index: sys/kern/kern_shutdown.c =================================================================== --- sys/kern/kern_shutdown.c +++ sys/kern/kern_shutdown.c @@ -1488,7 +1488,7 @@ #ifdef EKCD struct kerneldumpcrypto *kdc; #endif - void *buf, *key; + void *buf; size_t hdrsz; uint64_t extent; uint32_t keysize; @@ -1500,10 +1500,8 @@ #ifdef EKCD kdc = di->kdcrypto; - key = kdc->kdc_dumpkey; keysize = kerneldumpcrypto_dumpkeysize(kdc); #else - key = NULL; keysize = 0; #endif @@ -1512,7 +1510,7 @@ * of writing them out. */ if (di->dumper_hdr != NULL) - return (di->dumper_hdr(di, kdh, key, keysize)); + return (di->dumper_hdr(di, kdh)); if (hdrsz == di->blocksize) buf = kdh; @@ -1571,22 +1569,30 @@ int dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh) { +#ifdef EKCD + struct kerneldumpcrypto *kdc; +#endif + void *key; uint64_t dumpextent, span; uint32_t keysize; int error; #ifdef EKCD - error = kerneldumpcrypto_init(di->kdcrypto); + /* Send the key before the dump so a partial dump is still usable. */ + kdc = di->kdcrypto; + error = kerneldumpcrypto_init(kdc); if (error != 0) return (error); - keysize = kerneldumpcrypto_dumpkeysize(di->kdcrypto); + keysize = kerneldumpcrypto_dumpkeysize(kdc); + key = keysize > 0 ? kdc->kdc_dumpkey : NULL; #else error = 0; keysize = 0; + key = NULL; #endif if (di->dumper_start != NULL) { - error = di->dumper_start(di); + error = di->dumper_start(di, key, keysize); } else { dumpextent = dtoh64(kdh->dumpextent); span = SIZEOF_METADATA + dumpextent + 2 * di->blocksize + Index: sys/netinet/netdump/netdump_client.c =================================================================== --- sys/netinet/netdump/netdump_client.c +++ sys/netinet/netdump/netdump_client.c @@ -95,7 +95,8 @@ static int netdump_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t addr, int flags __unused, struct thread *td); static int netdump_modevent(module_t mod, int type, void *priv); -static int netdump_start(struct dumperinfo *di); +static int netdump_start(struct dumperinfo *di, void *key, + uint32_t keysize); static void netdump_unconfigure(void); /* Must be at least as big as the chunks dumpsys() gives us. */ @@ -285,7 +286,7 @@ * Perform any initialization needed prior to transmitting the kernel core. */ static int -netdump_start(struct dumperinfo *di) +netdump_start(struct dumperinfo *di, void *key, uint32_t keysize) { struct debugnet_conn_params dcp; struct debugnet_pcb *pcb; @@ -336,12 +337,34 @@ printf("netdumping to %s (%6D)\n", inet_ntoa_r(nd_server, buf), debugnet_get_gw_mac(pcb), ":"); nd_conf.nd_pcb = pcb; - return (0); + + /* Send the key before the dump so a partial dump is still usable. */ + if (keysize > 0) { + if (keysize > sizeof(nd_buf)) { + printf("crypto key is too large (%u)\n", keysize); + error = EINVAL; + goto out; + } + memcpy(nd_buf, key, keysize); + error = debugnet_send(pcb, NETDUMP_EKCD_KEY, nd_buf, keysize, + NULL); + if (error != 0) { + printf("error %d sending crypto key\n", error); + goto out; + } + } + +out: + if (error != 0) { + /* As above, squash errors. */ + error = EINVAL; + netdump_cleanup(); + } + return (error); } static int -netdump_write_headers(struct dumperinfo *di, struct kerneldumpheader *kdh, - void *key, uint32_t keysize) +netdump_write_headers(struct dumperinfo *di, struct kerneldumpheader *kdh) { int error; @@ -351,15 +374,6 @@ memcpy(nd_buf, kdh, sizeof(*kdh)); error = debugnet_send(nd_conf.nd_pcb, NETDUMP_KDH, nd_buf, sizeof(*kdh), NULL); - if (error == 0 && keysize > 0) { - if (keysize > sizeof(nd_buf)) { - error = EINVAL; - goto out; - } - memcpy(nd_buf, key, keysize); - error = debugnet_send(nd_conf.nd_pcb, NETDUMP_EKCD_KEY, nd_buf, - keysize, NULL); - } out: if (error != 0) netdump_cleanup(); Index: sys/sys/conf.h =================================================================== --- sys/sys/conf.h +++ sys/sys/conf.h @@ -133,9 +133,8 @@ vm_offset_t _physical, /* Physical address of virtual. */ off_t _offset, /* Byte-offset to write at. */ size_t _length); /* Number of bytes to dump. */ -typedef int dumper_start_t(struct dumperinfo *di); -typedef int dumper_hdr_t(struct dumperinfo *di, struct kerneldumpheader *kdh, - void *key, uint32_t keylen); +typedef int dumper_start_t(struct dumperinfo *di, void *key, uint32_t keysize); +typedef int dumper_hdr_t(struct dumperinfo *di, struct kerneldumpheader *kdh); #endif /* _KERNEL */