[PATCH v3 4/4] Reject NUL bytes in xenstore nodes

From: Demi Marie Obenour
Date: Sat Jun 10 2023 - 16:41:54 EST


This rejects bogus xenstore node values that include interior NUL
bytes. These would be truncated by functions that expect NUL-terminated
strings.

Signed-off-by: Demi Marie Obenour <demi@xxxxxxxxxxxxxxxxxxxxxx>
---
drivers/xen/xenbus/xenbus_xs.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index 12e02eb01f5991b31db451cc57037205359b347f..7cb2a22a7698ac40c81add23476594d9f27de8d0 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -569,16 +569,20 @@ int xenbus_scanf(struct xenbus_transaction t,
const char *dir, const char *node, const char *fmt, ...)
{
va_list ap;
- int ret;
+ int ret = 0;
+ unsigned int len;
char *val;

- val = xenbus_read(t, dir, node, NULL);
+ val = xenbus_read(t, dir, node, &len);
if (IS_ERR(val))
return PTR_ERR(val);
+ if (strlen(val) != len)
+ goto bad;

va_start(ap, fmt);
ret = vsscanf(val, fmt, ap);
va_end(ap);
+bad:
kfree(val);
/* Distinctive errno. */
if (ret == 0)
@@ -636,15 +640,18 @@ int xenbus_gather(struct xenbus_transaction t, const char *dir, ...)
while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
const char *fmt = va_arg(ap, char *);
void *result = va_arg(ap, void *);
+ unsigned len;
char *p;

- p = xenbus_read(t, dir, name, NULL);
+ p = xenbus_read(t, dir, name, &len);
if (IS_ERR(p)) {
ret = PTR_ERR(p);
break;
}
- if (fmt) {
- if (sscanf(p, fmt, result) == 0)
+ if (strlen(p) != len)
+ ret = -EINVAL;
+ else if (fmt) {
+ if (sscanf(p, fmt, result) <= 0)
ret = -EINVAL;
kfree(p);
} else
--
Sincerely,
Demi Marie Obenour (she/her/hers)
Invisible Things Lab