From c03c9a78664b0f3e27bba21167e621d5068feb0b Mon Sep 17 00:00:00 2001 From: John Snow Date: Mon, 6 May 2019 17:56:20 +0200 Subject: [PATCH 10/53] nbd/client: Reject inaccessible tail of inconsistent server RH-Author: John Snow Message-id: <20190506175629.11079-11-jsnow@redhat.com> Patchwork-id: 87183 O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 10/19] nbd/client: Reject inaccessible tail of inconsistent server Bugzilla: 1692018 RH-Acked-by: Max Reitz RH-Acked-by: Stefano Garzarella RH-Acked-by: Thomas Huth 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: John Snow Signed-off-by: Miroslav Rezanina --- nbd/client.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/nbd/client.c b/nbd/client.c index 10a52ad..4309569 100644 --- a/nbd/client.c +++ b/nbd/client.c @@ -426,6 +426,14 @@ static int nbd_opt_info_or_go(QIOChannel *ioc, uint32_t opt, 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; + } trace_nbd_receive_negotiate_size_flags(info->size, info->flags); break; -- 1.8.3.1