From nobody Tue Dec 16 08:06:36 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1527478947392842.559236718837; Sun, 27 May 2018 20:42:27 -0700 (PDT) Received: from localhost ([::1]:54034 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fN93C-0004nf-H6 for importer@patchew.org; Sun, 27 May 2018 23:42:26 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33474) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fN8yG-000187-MF for qemu-devel@nongnu.org; Sun, 27 May 2018 23:37:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fN8yF-0003sw-NR for qemu-devel@nongnu.org; Sun, 27 May 2018 23:37:20 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:43254 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fN8yB-0003qR-GL; Sun, 27 May 2018 23:37:15 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 14F1740203F4; Mon, 28 May 2018 03:37:15 +0000 (UTC) Received: from lemon.usersys.redhat.com (ovpn-12-114.pek2.redhat.com [10.72.12.114]) by smtp.corp.redhat.com (Postfix) with ESMTP id AE3DF1C677; Mon, 28 May 2018 03:37:10 +0000 (UTC) From: Fam Zheng To: qemu-devel@nongnu.org Date: Mon, 28 May 2018 11:36:35 +0800 Message-Id: <20180528033643.31380-3-famz@redhat.com> In-Reply-To: <20180528033643.31380-1-famz@redhat.com> References: <20180528033643.31380-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Mon, 28 May 2018 03:37:15 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Mon, 28 May 2018 03:37:15 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'famz@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v6 02/10] raw: Check byte range uniformly X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , Stefan Hajnoczi , qemu-block@nongnu.org, Peter Lieven , Max Reitz , Ronnie Sahlberg , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Eric Blake Signed-off-by: Fam Zheng --- 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 fe33693a2d..b69a0674b3 100644 --- a/block/raw-format.c +++ b/block/raw-format.c @@ -167,16 +167,37 @@ static void raw_reopen_abort(BDRVReopenState *state) state->opaque =3D NULL; } =20 +/* 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 =3D 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 +=3D s->offset; + + return 0; +} + static int coroutine_fn raw_co_preadv(BlockDriverState *bs, uint64_t offse= t, uint64_t bytes, QEMUIOVector *qiov, int flags) { - BDRVRawState *s =3D bs->opaque; + int ret; =20 - if (offset > UINT64_MAX - s->offset) { - return -EINVAL; + ret =3D raw_adjust_offset(bs, &offset, bytes, false); + if (ret) { + return ret; } - offset +=3D s->offset; =20 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(BlockDriverSta= te *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) { - BDRVRawState *s =3D bs->opaque; void *buf =3D NULL; BlockDriver *drv; QEMUIOVector local_qiov; int ret; =20 - 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 =3D -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(BlockDriverStat= e *bs, uint64_t offset, qiov =3D &local_qiov; } =20 - offset +=3D s->offset; + ret =3D raw_adjust_offset(bs, &offset, bytes, true); + if (ret) { + goto fail; + } =20 BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); ret =3D bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); @@ -267,22 +279,24 @@ static int coroutine_fn raw_co_pwrite_zeroes(BlockDri= verState *bs, int64_t offset, int bytes, BdrvRequestFlags flags) { - BDRVRawState *s =3D bs->opaque; - if (offset > UINT64_MAX - s->offset) { - return -EINVAL; + int ret; + + ret =3D raw_adjust_offset(bs, (uint64_t *)&offset, bytes, true); + if (ret) { + return ret; } - offset +=3D s->offset; return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags); } =20 static int coroutine_fn raw_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes) { - BDRVRawState *s =3D bs->opaque; - if (offset > UINT64_MAX - s->offset) { - return -EINVAL; + int ret; + + ret =3D raw_adjust_offset(bs, (uint64_t *)&offset, bytes, true); + if (ret) { + return ret; } - offset +=3D s->offset; return bdrv_co_pdiscard(bs->file->bs, offset, bytes); } =20 --=20 2.14.3