From e49b010d5f866b3ee7efbf40398f0a0832ce8801 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Tue, 23 Jul 2019 14:45:43 +0100 Subject: [PATCH 05/14] nbd/client: Reject inaccessible tail of inconsistent server RH-Author: Max Reitz Message-id: <20190723144546.23701-5-mreitz@redhat.com> Patchwork-id: 89649 O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 4/7] nbd/client: Reject inaccessible tail of inconsistent server Bugzilla: 1678979 RH-Acked-by: Kevin Wolf RH-Acked-by: Stefano Garzarella RH-Acked-by: John Snow From: Eric Blake The NBD spec suggests that a server should never advertise a size inconsistent with its minimum block alignment, as that tail is effectively inaccessible to a compliant client obeying those block constraints. Since we have a habit of rounding up rather than truncating, to avoid losing the last few bytes of user input, and we cannot access the tail when the server advertises bogus block sizing, abort the connection to alert the server to fix their bug. And rejecting such servers matches what we already did for a min_block that was not a power of 2 or which was larger than max_block. Does not impact either qemu (which always sends properly aligned sizes) or nbdkit (which does not send minimum block requirements yet); so this is mostly aimed at new NBD server implementations, and ensures that the rest of our code can assume the size is aligned. Signed-off-by: Eric Blake Message-Id: <20190330155704.24191-1-eblake@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy (cherry picked from commit 3add3ab78247fd347fd6f377a4b951022ac35d35) Signed-off-by: Max Reitz Signed-off-by: Danilo C. L. de Paula --- nbd/client.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nbd/client.c b/nbd/client.c index 25603f2..c828faf 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -416,6 +416,14 @@ static int nbd_opt_go(QIOChannel *ioc, const char *wantname, nbd_send_opt_abort(ioc); return -1; } + if (info->min_block && + !QEMU_IS_ALIGNED(info->size, info->min_block)) { + error_setg(errp, "export size %" PRIu64 "is not multiple of " + "minimum block size %" PRIu32, info->size, + info->min_block); + nbd_send_opt_abort(ioc); + return -1; + } be16_to_cpus(&info->flags); trace_nbd_receive_negotiate_size_flags(info->size, info->flags); break; -- 1.8.3.1