[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 18/99] raw: Check byte range uniformly
From: |
Michael Roth |
Subject: |
[Qemu-devel] [PATCH 18/99] raw: Check byte range uniformly |
Date: |
Mon, 23 Jul 2018 15:16:27 -0500 |
From: Fam Zheng <address@hidden>
We don't verify the request range against s->size in the I/O callbacks
except for raw_co_pwritev. This is inconsistent (especially for
raw_co_pwrite_zeroes and raw_co_pdiscard), so fix them, in the meanwhile
make the helper reusable by the coming new callbacks.
Note that in most cases the block layer already verifies the request
byte range against our reported image length, before invoking the driver
callbacks. The exception is during image creating, after
blk_set_allow_write_beyond_eof(blk, true) is called. But in that case,
the requests are not directly from the user or guest. So there is no
visible behavior change in adding the check code.
The int64_t -> uint64_t inconsistency, as shown by the type casting, is
pre-existing due to the interface.
Reviewed-by: Stefan Hajnoczi <address@hidden>
Reviewed-by: Eric Blake <address@hidden>
Signed-off-by: Fam Zheng <address@hidden>
Message-id: address@hidden
Signed-off-by: Stefan Hajnoczi <address@hidden>
(cherry picked from commit 384455385248762e74a080978f18f0c8f74757fe)
Signed-off-by: Michael Roth <address@hidden>
---
block/raw-format.c | 64 ++++++++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 25 deletions(-)
diff --git a/block/raw-format.c b/block/raw-format.c
index a378547c99..17b9d4e052 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -167,16 +167,37 @@ static void raw_reopen_abort(BDRVReopenState *state)
state->opaque = NULL;
}
+/* Check and adjust the offset, against 'offset' and 'size' options. */
+static inline int raw_adjust_offset(BlockDriverState *bs, uint64_t *offset,
+ uint64_t bytes, bool is_write)
+{
+ BDRVRawState *s = bs->opaque;
+
+ if (s->has_size && (*offset > s->size || bytes > (s->size - *offset))) {
+ /* There's not enough space for the write, or the read request is
+ * out-of-range. Don't read/write anything to prevent leaking out of
+ * the size specified in options. */
+ return is_write ? -ENOSPC : -EINVAL;;
+ }
+
+ if (*offset > INT64_MAX - s->offset) {
+ return -EINVAL;
+ }
+ *offset += s->offset;
+
+ return 0;
+}
+
static int coroutine_fn raw_co_preadv(BlockDriverState *bs, uint64_t offset,
uint64_t bytes, QEMUIOVector *qiov,
int flags)
{
- BDRVRawState *s = bs->opaque;
+ int ret;
- if (offset > UINT64_MAX - s->offset) {
- return -EINVAL;
+ ret = raw_adjust_offset(bs, &offset, bytes, false);
+ if (ret) {
+ return ret;
}
- offset += s->offset;
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
@@ -186,23 +207,11 @@ static int coroutine_fn raw_co_pwritev(BlockDriverState
*bs, uint64_t offset,
uint64_t bytes, QEMUIOVector *qiov,
int flags)
{
- BDRVRawState *s = bs->opaque;
void *buf = NULL;
BlockDriver *drv;
QEMUIOVector local_qiov;
int ret;
- if (s->has_size && (offset > s->size || bytes > (s->size - offset))) {
- /* There's not enough space for the data. Don't write anything and just
- * fail to prevent leaking out of the size specified in options. */
- return -ENOSPC;
- }
-
- if (offset > UINT64_MAX - s->offset) {
- ret = -EINVAL;
- goto fail;
- }
-
if (bs->probed && offset < BLOCK_PROBE_BUF_SIZE && bytes) {
/* Handling partial writes would be a pain - so we just
* require that guests have 512-byte request alignment if
@@ -237,7 +246,10 @@ static int coroutine_fn raw_co_pwritev(BlockDriverState
*bs, uint64_t offset,
qiov = &local_qiov;
}
- offset += s->offset;
+ ret = raw_adjust_offset(bs, &offset, bytes, true);
+ if (ret) {
+ goto fail;
+ }
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
@@ -267,22 +279,24 @@ static int coroutine_fn
raw_co_pwrite_zeroes(BlockDriverState *bs,
int64_t offset, int bytes,
BdrvRequestFlags flags)
{
- BDRVRawState *s = bs->opaque;
- if (offset > UINT64_MAX - s->offset) {
- return -EINVAL;
+ int ret;
+
+ ret = raw_adjust_offset(bs, (uint64_t *)&offset, bytes, true);
+ if (ret) {
+ return ret;
}
- offset += s->offset;
return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
}
static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs,
int64_t offset, int bytes)
{
- BDRVRawState *s = bs->opaque;
- if (offset > UINT64_MAX - s->offset) {
- return -EINVAL;
+ int ret;
+
+ ret = raw_adjust_offset(bs, (uint64_t *)&offset, bytes, true);
+ if (ret) {
+ return ret;
}
- offset += s->offset;
return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
}
--
2.17.1
- [Qemu-devel] [PATCH 99/99] tcg/i386: Mark xmm registers call-clobbered, (continued)
- [Qemu-devel] [PATCH 99/99] tcg/i386: Mark xmm registers call-clobbered, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 09/99] spapr: don't advertise radix GTSE if max-compat-cpu < power9, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 10/99] qxl: fix local renderer crash, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 11/99] configure: recognize more rpmbuild macros, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 13/99] iotests: Add test for rebasing with relative paths, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 12/99] qemu-img: Resolve relative backing paths in rebase, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 14/99] qemu-io: Use purely string blockdev options, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 15/99] qemu-img: Use only string options in img_open_opts, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 17/99] lm32: take BQL before writing IP/IM register, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 16/99] iotests: Add test for -U/force-share conflicts, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 18/99] raw: Check byte range uniformly,
Michael Roth <=
- [Qemu-devel] [PATCH 19/99] s390x/css: disabled subchannels cannot be status pending, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 01/99] tests: fix tpm-crb tpm-tis tests race, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 20/99] pc-bios/s390-ccw: struct tpi_info must be declared as aligned(4), Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 21/99] virtio-ccw: common reset handler, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 22/99] s390x/ccw: make sure all ccw devices are properly reset, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 24/99] hw/intc/arm_gicv3: Fix APxR<n> register dispatching, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 23/99] console: Avoid segfault in screendump, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 27/99] intel-iommu: add iommu lock, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 26/99] intel-iommu: remove IntelIOMMUNotifierNode, Michael Roth, 2018/07/23
- [Qemu-devel] [PATCH 25/99] intel-iommu: send PSI always even if across PDEs, Michael Roth, 2018/07/23