summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2016-04-21 08:42:30 -0600
committerTimothy Pearson <tpearson@raptorengineering.com>2019-11-29 20:03:50 -0600
commit78bf17b51c2f66eb27645346b3a1dab56815bf72 (patch)
tree858b6509170e0e60a29bf6e574d00682a88097b8
parent31ead004a4798eadd3b6dc183ca7e85b051232e0 (diff)
downloadhqemu-78bf17b51c2f66eb27645346b3a1dab56815bf72.zip
hqemu-78bf17b51c2f66eb27645346b3a1dab56815bf72.tar.gz
nbd: Don't mishandle unaligned client requests
The NBD protocol does not (yet) force any alignment constraints on clients. Even though qemu NBD clients always send requests that are aligned to 512 bytes, we must be prepared for non-qemu clients that don't care about alignment (even if it means they are less efficient). Our use of blk_read() and blk_write() was silently operating on the wrong file offsets when the client made an unaligned request, corrupting the client's data (but as the client already has control over the file we are serving, I don't think it is a security hole, per se, just a data corruption bug). Note that in the case of NBD_CMD_READ, an unaligned length could cause us to return up to 511 bytes of uninitialized trailing garbage from blk_try_blockalign() - hopefully nothing sensitive from the heap's prior usage is ever leaked in that manner. Signed-off-by: Eric Blake <eblake@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Tested-by: Kevin Wolf <kwolf@redhat.com> Message-id: 1461249750-31928-1-git-send-email-eblake@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--nbd/server.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/nbd/server.c b/nbd/server.c
index a13a691..2184c64 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1091,9 +1091,8 @@ static void nbd_trip(void *opaque)
}
}
- ret = blk_read(exp->blk,
- (request.from + exp->dev_offset) / BDRV_SECTOR_SIZE,
- req->data, request.len / BDRV_SECTOR_SIZE);
+ ret = blk_pread(exp->blk, request.from + exp->dev_offset,
+ req->data, request.len);
if (ret < 0) {
LOG("reading from file failed");
reply.error = -ret;
@@ -1115,9 +1114,8 @@ static void nbd_trip(void *opaque)
TRACE("Writing to device");
- ret = blk_write(exp->blk,
- (request.from + exp->dev_offset) / BDRV_SECTOR_SIZE,
- req->data, request.len / BDRV_SECTOR_SIZE);
+ ret = blk_pwrite(exp->blk, request.from + exp->dev_offset,
+ req->data, request.len);
if (ret < 0) {
LOG("writing to file failed");
reply.error = -ret;
OpenPOWER on IntegriCloud