summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2016-01-11 16:14:17 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2016-01-11 16:14:17 +0000
commitb4ecda13c6234e99a85e70551be35a65dca7fb0e (patch)
tree63263b432bca11c7fbc7f4d017b2e4acb2fd8990 /sys
parent4bc3ac1547fb8ab0483d0580aa02792aea76766b (diff)
Handle zero lenght messages in the xs_parse by returning an empty string
Problem was reported and analyzed by reyk@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pv/xenstore.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/sys/dev/pv/xenstore.c b/sys/dev/pv/xenstore.c
index 5b02945004a..654602ff745 100644
--- a/sys/dev/pv/xenstore.c
+++ b/sys/dev/pv/xenstore.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xenstore.c,v 1.12 2016/01/04 16:06:50 mikeb Exp $ */
+/* $OpenBSD: xenstore.c,v 1.13 2016/01/11 16:14:16 mikeb Exp $ */
/*
* Copyright (c) 2015 Mike Belopuhov
@@ -633,10 +633,11 @@ int
xs_parse(struct xs_transaction *xst, struct xs_msg *xsm, struct iovec **iov,
int *iov_cnt)
{
- int dlen = xsm->xsm_hdr.xmh_len;
char *bp, *cp;
- int i, flags;
+ int i, dlen, flags;
+ /* If the response size is zero, we return an empty string */
+ dlen = MAX(xsm->xsm_hdr.xmh_len, 1);
flags = M_ZERO | (xst->xst_flags & XST_POLL ? M_NOWAIT : M_WAITOK);
*iov_cnt = 0;
@@ -650,13 +651,11 @@ xs_parse(struct xs_transaction *xst, struct xs_msg *xsm, struct iovec **iov,
xsm->xsm_data[dlen - 1] = '\0';
}
for (i = 0; i < dlen; i++)
- if (i > 0 && xsm->xsm_data[i] == '\0')
+ if (xsm->xsm_data[i] == '\0')
(*iov_cnt)++;
- if (!*iov_cnt)
- return (0);
*iov = mallocarray(*iov_cnt, sizeof(struct iovec), M_DEVBUF, flags);
if (*iov == NULL)
- return (-1);
+ goto cleanup;
bp = xsm->xsm_data;
for (i = 0; i < *iov_cnt; i++) {
cp = bp;
@@ -664,16 +663,18 @@ xs_parse(struct xs_transaction *xst, struct xs_msg *xsm, struct iovec **iov,
cp++;
(*iov)[i].iov_len = cp - bp + 1;
(*iov)[i].iov_base = malloc((*iov)[i].iov_len, M_DEVBUF, flags);
- if (!(*iov)[i].iov_base)
+ if (!(*iov)[i].iov_base) {
+ xs_resfree(xst, *iov, *iov_cnt);
goto cleanup;
+ }
memcpy((*iov)[i].iov_base, bp, (*iov)[i].iov_len);
bp = ++cp;
}
-
return (0);
cleanup:
- xs_resfree(xst, *iov, *iov_cnt);
+ *iov = NULL;
+ *iov_cnt = 0;
return (ENOMEM);
}