vmd: rewind ibuf on forward

Nick Owens <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
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);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.