From nobody Mon Feb 9 19:25:41 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1611975585; cv=none; d=zohomail.com; s=zohoarc; b=JVdtB3xNGbKx+YmdDYZZnw9VzZFo4COR0vt/w//IG8bPuYArjF8sj/luL4Cil+rndwGwtXrftiKUHX1j67q+dosI8rmsT2y0INLUuEOlykmvCPA5OfOt33DLvxabT33k/1Nin1OBodTjZkSWp4VAR4y5w2cYiTDt2Vn+gT5D7WY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1611975585; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=9hCI1o4i3i0e2af/TYOxd0kpT2irsCc9jbLiicol+MM=; b=PJ8ef7S1lZi8fNQashbge8wnMWRo6COdEkzj29CPtArdGIy3sT43FrzV/ZpLFprz01CAcWVM8TuAdX1ryyqDvvQ5NNZqQ40AC0SM/zYKLE239wU2Z3IWj3UL7jiwKh1l3UeA3+LXmb4AvvHDXt52lgOwPuB2qJJV5MjQevtX9BU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) header.from= Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1611975585906467.34683414058895; Fri, 29 Jan 2021 18:59:45 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.78639.143202 (Exim 4.92) (envelope-from ) id 1l5gTw-0000pn-GG; Sat, 30 Jan 2021 02:59:28 +0000 Received: by outflank-mailman (output) from mailman id 78639.143202; Sat, 30 Jan 2021 02:59:28 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1l5gTw-0000pX-BC; Sat, 30 Jan 2021 02:59:28 +0000 Received: by outflank-mailman (input) for mailman id 78639; Sat, 30 Jan 2021 02:59:27 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1l5gTv-0000YD-QJ for xen-devel@lists.xenproject.org; Sat, 30 Jan 2021 02:59:27 +0000 Received: from esa4.hc3370-68.iphmx.com (unknown [216.71.155.144]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 90dd9708-3c52-4a16-8f98-bf6113781a2e; Sat, 30 Jan 2021 02:59:12 +0000 (UTC) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 90dd9708-3c52-4a16-8f98-bf6113781a2e DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1611975552; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TFUeOvHFx2gnEVFRi1+gHwqBqIzxUVzebfveWMaPxFo=; b=YEaMJQsEpV/piOFRXT3ButIQtIQQJqxLsMa/JID2A78i05Bama2JjkON fY2piX3S3gWHbCqBJDdhQj+xvbbTZ1WXOo5L8daID+bZhct+yOzmUOFmQ uyBJF/50wj1gB8l9MRyO2u7idkWMs0KdVnR8U/a59ja91PB3QOBaS6nXZ U=; Authentication-Results: esa4.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none IronPort-SDR: LshTWpJRRTcuKP+ZTeLGY/JqdgFbzmMFQwh2hopnEgq5BO6RfcNBvrJ/TV7ZrcbLeal0aojM3d W+AZVWxPvxV4Y+cphexg2wLqOK6faAqXTAEMyq1NPs2K+N0/NJYRwB8dz8+3PKlk+gem4TBmm/ N86gRDTwuXKMKV+6Zbv2KPt4OQLlyoL8JQpX+pOYeeYhWsZkvFuzEE6EeY+raAKBK3PVMnEyLX WYK1mV2UANiEqf4JbRMH/8M2s7AQ//txVUZrxZc4mjqgFXbIzKpKJng8feV7e8FuFJCHTlC7VD Swg= X-SBRS: 5.1 X-MesageID: 37525491 X-Ironport-Server: esa4.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.79,387,1602561600"; d="scan'208";a="37525491" From: Andrew Cooper To: Xen-devel CC: Andrew Cooper , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Wei Liu , Stefano Stabellini , Julien Grall , Volodymyr Babchuk , Paul Durrant , "Oleksandr Tyshchenko" Subject: [PATCH v8 01/16] xen/memory: Reject out-of-range resource 'frame' values Date: Sat, 30 Jan 2021 02:58:37 +0000 Message-ID: <20210130025852.12430-2-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20210130025852.12430-1-andrew.cooper3@citrix.com> References: <20210130025852.12430-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) The ABI is unfortunate, and frame being 64 bits leads to all kinds of probl= ems performing correct overflow checks. Reject out-of-range values, and combinations which overflow, and use unsign= ed int consistently elsewhere. This fixes several truncation bugs in the grant call tree, as the underlying limits are expressed with unsigned int to begin with. Signed-off-by: Andrew Cooper Reviewed-by: Paul Durrant Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Roger Pau Monn=C3=A9 CC: Wei Liu CC: Stefano Stabellini CC: Julien Grall CC: Volodymyr Babchuk CC: Paul Durrant CC: Oleksandr Tyshchenko v8: * Push long=3D>int conversion all the way down into gnttab/ioreq * Rebase over ARM/IOREQ series v7.5: * New --- xen/common/grant_table.c | 14 +++++++------- xen/common/ioreq.c | 2 +- xen/common/memory.c | 17 +++++++++++++++-- xen/include/xen/grant_table.h | 8 ++++---- xen/include/xen/ioreq.h | 2 +- 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index f6f5acd300..4ecec35f28 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -3918,7 +3918,7 @@ int mem_sharing_gref_to_gfn(struct grant_table *gt, g= rant_ref_t ref, =20 /* caller must hold write lock */ static int gnttab_get_status_frame_mfn(struct domain *d, - unsigned long idx, mfn_t *mfn) + unsigned int idx, mfn_t *mfn) { const struct grant_table *gt =3D d->grant_table; =20 @@ -3929,8 +3929,8 @@ static int gnttab_get_status_frame_mfn(struct domain = *d, =20 if ( idx >=3D nr_status_frames(gt) ) { - unsigned long nr_status; - unsigned long nr_grant; + unsigned int nr_status; + unsigned int nr_grant; =20 nr_status =3D idx + 1; /* sufficient frames to make idx valid */ =20 @@ -3958,7 +3958,7 @@ static int gnttab_get_status_frame_mfn(struct domain = *d, =20 /* caller must hold write lock */ static int gnttab_get_shared_frame_mfn(struct domain *d, - unsigned long idx, mfn_t *mfn) + unsigned int idx, mfn_t *mfn) { const struct grant_table *gt =3D d->grant_table; =20 @@ -3966,7 +3966,7 @@ static int gnttab_get_shared_frame_mfn(struct domain = *d, =20 if ( idx >=3D nr_grant_frames(gt) ) { - unsigned long nr_grant; + unsigned int nr_grant; =20 nr_grant =3D idx + 1; /* sufficient frames to make idx valid */ =20 @@ -4021,7 +4021,7 @@ int gnttab_map_frame(struct domain *d, unsigned long = idx, gfn_t gfn, mfn_t *mfn) return rc; } =20 -int gnttab_get_shared_frame(struct domain *d, unsigned long idx, +int gnttab_get_shared_frame(struct domain *d, unsigned int idx, mfn_t *mfn) { struct grant_table *gt =3D d->grant_table; @@ -4034,7 +4034,7 @@ int gnttab_get_shared_frame(struct domain *d, unsigne= d long idx, return rc; } =20 -int gnttab_get_status_frame(struct domain *d, unsigned long idx, +int gnttab_get_status_frame(struct domain *d, unsigned int idx, mfn_t *mfn) { struct grant_table *gt =3D d->grant_table; diff --git a/xen/common/ioreq.c b/xen/common/ioreq.c index a36137d41d..90ed2e0302 100644 --- a/xen/common/ioreq.c +++ b/xen/common/ioreq.c @@ -771,7 +771,7 @@ static int ioreq_server_get_info(struct domain *d, iose= rvid_t id, } =20 int ioreq_server_get_frame(struct domain *d, ioservid_t id, - unsigned long idx, mfn_t *mfn) + unsigned int idx, mfn_t *mfn) { struct ioreq_server *s; int rc; diff --git a/xen/common/memory.c b/xen/common/memory.c index 33296e65cb..4d681597a5 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -1055,7 +1055,7 @@ static long xatp_permission_check(struct domain *d, u= nsigned int space) } =20 static int acquire_grant_table(struct domain *d, unsigned int id, - unsigned long frame, + unsigned int frame, unsigned int nr_frames, xen_pfn_t mfn_list[]) { @@ -1094,7 +1094,7 @@ static int acquire_grant_table(struct domain *d, unsi= gned int id, =20 static int acquire_ioreq_server(struct domain *d, unsigned int id, - unsigned long frame, + unsigned int frame, unsigned int nr_frames, xen_pfn_t mfn_list[]) { @@ -1164,6 +1164,19 @@ static int acquire_resource( if ( xmar.nr_frames > ARRAY_SIZE(mfn_list) ) return -E2BIG; =20 + /* + * The ABI is rather unfortunate. nr_frames (and therefore the total = size + * of the resource) is 32bit, while frame (the offset within the resou= rce + * we'd like to start at) is 64bit. + * + * Reject values oustide the of the range of nr_frames, as well as + * combinations of frame and nr_frame which overflow, to simplify the = rest + * of the logic. + */ + if ( (xmar.frame >> 32) || + ((xmar.frame + xmar.nr_frames) >> 32) ) + return -EINVAL; + rc =3D rcu_lock_remote_domain_by_id(xmar.domid, &d); if ( rc ) return rc; diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h index 8876f1f28e..6d14fe2526 100644 --- a/xen/include/xen/grant_table.h +++ b/xen/include/xen/grant_table.h @@ -55,9 +55,9 @@ int mem_sharing_gref_to_gfn(struct grant_table *gt, grant= _ref_t ref, =20 int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn, mfn_t *mfn); -int gnttab_get_shared_frame(struct domain *d, unsigned long idx, +int gnttab_get_shared_frame(struct domain *d, unsigned int idx, mfn_t *mfn); -int gnttab_get_status_frame(struct domain *d, unsigned long idx, +int gnttab_get_status_frame(struct domain *d, unsigned int idx, mfn_t *mfn); =20 #else @@ -92,13 +92,13 @@ static inline int gnttab_map_frame(struct domain *d, un= signed long idx, return -EINVAL; } =20 -static inline int gnttab_get_shared_frame(struct domain *d, unsigned long = idx, +static inline int gnttab_get_shared_frame(struct domain *d, unsigned int i= dx, mfn_t *mfn) { return -EINVAL; } =20 -static inline int gnttab_get_status_frame(struct domain *d, unsigned long = idx, +static inline int gnttab_get_status_frame(struct domain *d, unsigned int i= dx, mfn_t *mfn) { return -EINVAL; diff --git a/xen/include/xen/ioreq.h b/xen/include/xen/ioreq.h index 2d635e9432..a54a637bef 100644 --- a/xen/include/xen/ioreq.h +++ b/xen/include/xen/ioreq.h @@ -90,7 +90,7 @@ bool vcpu_ioreq_handle_completion(struct vcpu *v); bool is_ioreq_server_page(struct domain *d, const struct page_info *page); =20 int ioreq_server_get_frame(struct domain *d, ioservid_t id, - unsigned long idx, mfn_t *mfn); + unsigned int idx, mfn_t *mfn); int ioreq_server_map_mem_type(struct domain *d, ioservid_t id, uint32_t type, uint32_t flags); =20 --=20 2.11.0