Date: Wed, 11 Aug 2021 20:55:04 GMT From: Eric van Gyzen <vangyzen@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 13a58148de17 - main - netdump: send key before dump, in case dump fails Message-ID: <202108112055.17BKt4At006745@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by vangyzen: URL: https://cgit.FreeBSD.org/src/commit/?id=13a58148de1730f851d37513913fae547e53a512 commit 13a58148de1730f851d37513913fae547e53a512 Author: Eric van Gyzen <vangyzen@FreeBSD.org> AuthorDate: 2021-08-06 15:38:51 +0000 Commit: Eric van Gyzen <vangyzen@FreeBSD.org> CommitDate: 2021-08-11 15:54:56 +0000 netdump: send key before dump, in case dump fails Previously, if an encrypted netdump failed, such as due to a timeout or network failure, the key was not saved, so a partial dump was completely useless. Send the key first, so the partial dump can be decrypted, because even a partial dump can be useful. Reviewed by: bdrewery, markj MFC after: 1 week Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D31453 --- sys/kern/kern_shutdown.c | 20 +++++++++++------ sys/netinet/netdump/netdump_client.c | 42 ++++++++++++++++++++++++------------ sys/sys/conf.h | 5 ++--- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index fb2a69401801..3cc51fd31956 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -1488,7 +1488,7 @@ dump_write_headers(struct dumperinfo *di, struct kerneldumpheader *kdh) #ifdef EKCD struct kerneldumpcrypto *kdc; #endif - void *buf, *key; + void *buf; size_t hdrsz; uint64_t extent; uint32_t keysize; @@ -1500,10 +1500,8 @@ dump_write_headers(struct dumperinfo *di, struct kerneldumpheader *kdh) #ifdef EKCD kdc = di->kdcrypto; - key = kdc->kdc_dumpkey; keysize = kerneldumpcrypto_dumpkeysize(kdc); #else - key = NULL; keysize = 0; #endif @@ -1512,7 +1510,7 @@ dump_write_headers(struct dumperinfo *di, struct kerneldumpheader *kdh) * 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 @@ dump_write_headers(struct dumperinfo *di, struct kerneldumpheader *kdh) 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 + diff --git a/sys/netinet/netdump/netdump_client.c b/sys/netinet/netdump/netdump_client.c index 2669ec879d75..d6fd7db364b8 100644 --- a/sys/netinet/netdump/netdump_client.c +++ b/sys/netinet/netdump/netdump_client.c @@ -95,7 +95,8 @@ static int netdump_enabled_sysctl(SYSCTL_HANDLER_ARGS); 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 @@ netdump_dumper(void *priv __unused, void *virtual, * 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 @@ netdump_start(struct dumperinfo *di) 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 @@ netdump_write_headers(struct dumperinfo *di, struct kerneldumpheader *kdh, 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(); diff --git a/sys/sys/conf.h b/sys/sys/conf.h index 123bf91cf952..053cf6ddb016 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -133,9 +133,8 @@ typedef int dumper_t( 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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108112055.17BKt4At006745>