Index | Thread | Search

From:
Nick Owens <mischief@offblast.org>
Subject:
vmd: rewind ibuf on forward
To:
tech@openbsd.org
Cc:
dv@sisu.io
Date:
Fri, 28 Aug 2026 15:00:30 -0700

Download raw body.

Thread
  • Nick Owens:

    vmd: rewind ibuf on forward

unlike libutil's imsg, vmd's proc_forward_imsg does not rewind. if a
caller consumed it, then the forwarded message will appear to be empty.

for me, this fixes

	vmd: control: vmop_result_read: Bad message

which happens during IMSG_VMDOP_TERMINATE_VM_RESPONSE handling on vm
shutdown, when doing lots of concurrent vm starts/stops, in the
particular case of where a vm might have exited itself before vmd has
seen it.

i don't think imsg_forward can be used here because proc_forward_imsg
can change the peer, which control.c uses, and it forwards the fd, which
imsg_forward drops.

diff --git a/usr.sbin/vmd/proc.c b/usr.sbin/vmd/proc.c
index bcc85ac4630..9e123306624 100644
--- a/usr.sbin/vmd/proc.c
+++ b/usr.sbin/vmd/proc.c
@@ -632,6 +632,14 @@ proc_forward_imsg(struct privsep *ps, struct imsg *imsg, enum privsep_procid id,
 	void		*data = NULL;
 
 	fd = imsg_get_fd(imsg);
+
+	/* rewind before forwarding, as imsg_forward(3) does: a getter
+	 * may already have consumed this imsg.
+	 */
+	ibuf_rewind(imsg->buf);
+	if (ibuf_skip(imsg->buf, sizeof(imsg->hdr)) == -1)
+		return (EINVAL);
+
 	sz = imsg_get_len(imsg);
 	type = imsg_get_type(imsg);