aboutsummaryrefslogtreecommitdiff
path: root/nbd
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2023-06-08 08:56:30 -0500
committerEric Blake <eblake@redhat.com>2023-07-19 15:25:27 -0500
commitf47b6eab8372fef45cdc711c5a904df82de3aecf (patch)
treee63e14d38d41ca118eb8a4073809d3fa8600d396 /nbd
parent414c0cf0e88b8cba1d4f5a6bc32f9796a66b5c26 (diff)
downloadqemu-f47b6eab8372fef45cdc711c5a904df82de3aecf.zip
qemu-f47b6eab8372fef45cdc711c5a904df82de3aecf.tar.gz
qemu-f47b6eab8372fef45cdc711c5a904df82de3aecf.tar.bz2
nbd/client: Use smarter assert
Assigning strlen() to a uint32_t and then asserting that it isn't too large doesn't catch the case of an input string 4G in length. Thankfully, the incoming strings can never be that large: if the export name or query is reflecting a string the client got from the server, we already guarantee that we dropped the NBD connection if the server sent more than 32M in a single reply to our NBD_OPT_* request; if the export name is coming from qemu, nbd_receive_negotiate() asserted that strlen(info->name) <= NBD_MAX_STRING_SIZE; and similarly, a query string via x->dirty_bitmap coming from the user was bounds-checked in either qemu-nbd or by the limitations of QMP. Still, it doesn't hurt to be more explicit in how we write our assertions to not have to analyze whether inadvertent wraparound is possible. Fixes: 93676c88 ("nbd: Don't send oversize strings", v4.2.0) Reported-by: Dr. David Alan Gilbert <dave@treblig.org> Signed-off-by: Eric Blake <eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Message-ID: <20230608135653.2918540-2-eblake@redhat.com>
Diffstat (limited to 'nbd')
-rw-r--r--nbd/client.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/nbd/client.c b/nbd/client.c
index 30d5383..ff75722 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -650,19 +650,20 @@ static int nbd_send_meta_query(QIOChannel *ioc, uint32_t opt,
Error **errp)
{
int ret;
- uint32_t export_len = strlen(export);
+ uint32_t export_len;
uint32_t queries = !!query;
uint32_t query_len = 0;
uint32_t data_len;
char *data;
char *p;
+ assert(strnlen(export, NBD_MAX_STRING_SIZE + 1) <= NBD_MAX_STRING_SIZE);
+ export_len = strlen(export);
data_len = sizeof(export_len) + export_len + sizeof(queries);
- assert(export_len <= NBD_MAX_STRING_SIZE);
if (query) {
+ assert(strnlen(query, NBD_MAX_STRING_SIZE + 1) <= NBD_MAX_STRING_SIZE);
query_len = strlen(query);
data_len += sizeof(query_len) + query_len;
- assert(query_len <= NBD_MAX_STRING_SIZE);
} else {
assert(opt == NBD_OPT_LIST_META_CONTEXT);
}