From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794591609; b=LFuPTKOcFlwYu+/1m4OKfUBPX0437K/SaOoSLzvbWILq37ECA+pa/nlLAQuQM5m7Ktb+ gNcFi37wwC16PiRAPFaKu/AuQE2OHeurKBjYUC7ZUw3CX5Cgi94j5qMWdxUvZ9IccItXQ M3SrcNyptheqN4R5S/s9APnMPCXmwNg/G/HvGvHGs/s/GeQncci2A8kTEziEc++1YKI54 rmPQvH5XqYgs52Bn65Z+jow7DwXCxJy9g4/z/StDP0RBGHl1P+dCM9B68gM06Dtr0KV/w wDao7hDVSNqGt3zYzeBkIxz3XY5WtMFCCuTYxOSe26tFzBvFYVM8vNSp92Iutdgg/pQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794591609; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=r0mxg3SlzxphU3ZsEgQzeH5JDswcGLwXFAcYpwVcdAw=; b=14UzRrByjcRsHKxOedkPi4DSb9VuNalqIdVRDaKX5Gp6msJKcAbcY4D8DWc9fsPzKHiM iDE7ksJ/nx5Fr6kcnwtoRUe5sAoJUGNAKFNN21nI3wTrO6BMKb5lUlCTbbykKpBUHJDp9 gowUwuG7WW6ZcrVwJI1iQlB1I4RYyrqyXxFrjNVUyXFL5i3EKrT+WfDSHQvzwwWJu7lsE r7rmKHqfDPLFDCW3GcVJeBnyTVz/obkctC/oh87DRP+94y4MH1Gi1PP+vA21l7I+thV0f wrmMb4qfQ0NevdEvAQqWsygAA7zUTkuX26jYiLOAGXiqOldiPKNIF8opT2qgUfH6JxA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=xRLVyFxB; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E1FD606B45B; Fri, 13 Nov 2026 17:40:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=xRLVyFxB Received: by smtp.kernel.org (Postfix) with ESMTPSA id 194881F000C7; Fri, 13 Nov 2026 17:40:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794591609; bh=r0mxg3SlzxphU3ZsEgQzeH5JDswcGLwXFAcYpwVcdAw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=xRLVyFxBFf3bKtwt7uQ1mgi8FE9Zv5kjphao98TBqHNlXoZSIgPflOKEoZ4QKTfXP 7cKaD/jgZUVoNGEmPdgEp3pV9ljIk5ukJybMEMT3GtgjWrrwdyzaiSKyP93rjYew93 AO+wSOXfGhh9ksQHJTWHi+TTNV21/S9VGnRVbyDg= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Andrea Parri , Jason Gunthorpe , Sasha Levin Subject: [PATCH 6.12 649/670] iommufd/iova_bitmap: Ensure that iova_bitmap_set() handles the full IOVA Date: Fri, 13 Nov 2026 10:53:33 -0500 Message-ID: <20261113153833.837726688@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261113153811.177190860@linuxfoundation.org> References: <20261113153811.177190860@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Andrea Parri [ Upstream commit e21952d72b4740f08a272d694cca223b6b0099ca ] Generally userspace is going to step the dirty bitmap through the IOVA space. However if the bitmap ends in the middle of a large PTE this is problematic. The first step will clear the dirty bit and report dirty to the end of its bitmap while the second step will see the clear'd dirty and report clean for the start of the bitmap. If it happens this ends up losing dirties. Further this function is missing bounds checking so if this does happen ther is a good chance it will write memory beyond what the userspace was expecting. Return an error code if this illegal condition happens. Fixes: 58ccf0190d19 ("vfio: Add an IOVA bitmap support") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Andrea Parri Link: https://patch.msgid.link/20260925161142.189813-2-parri.andrea@gmail.com Signed-off-by: Jason Gunthorpe [ sashal: Added missing bitmap error-propagation infrastructure connecting the stored error field to the iterator and ioctl caller. ] Signed-off-by: Sasha Levin --- drivers/iommu/iommufd/io_pagetable.c | 2 +- drivers/iommu/iommufd/iova_bitmap.c | 19 ++++++++++++++++++- include/uapi/linux/iommufd.h | 6 ++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c index 177e8e12f189f..382150147f4d1 100644 --- a/drivers/iommu/iommufd/io_pagetable.c +++ b/drivers/iommu/iommufd/io_pagetable.c @@ -505,7 +505,7 @@ iommu_read_and_clear_dirty(struct iommu_domain *domain, arg.iopt = iopt; arg.domain = domain; arg.dirty = &dirty; - iova_bitmap_for_each(iter, &arg, __iommu_read_and_clear_dirty); + ret = iova_bitmap_for_each(iter, &arg, __iommu_read_and_clear_dirty); if (!(flags & IOMMU_DIRTY_NO_CLEAR)) iommu_iotlb_sync(domain, &gather); diff --git a/drivers/iommu/iommufd/iova_bitmap.c b/drivers/iommu/iommufd/iova_bitmap.c index 0943a351fb917..e12a36bf6aed5 100644 --- a/drivers/iommu/iommufd/iova_bitmap.c +++ b/drivers/iommu/iommufd/iova_bitmap.c @@ -116,6 +116,9 @@ struct iova_bitmap { /* length of the IOVA range for the whole bitmap */ size_t length; + + /* first error encountered while recording dirty IOVAs */ + int err; }; /* @@ -384,7 +387,9 @@ static int iova_bitmap_advance_to(struct iova_bitmap *bitmap, int iova_bitmap_for_each(struct iova_bitmap *bitmap, void *opaque, iova_bitmap_fn_t fn) { - return fn(bitmap, bitmap->iova, bitmap->length, opaque); + int ret = fn(bitmap, bitmap->iova, bitmap->length, opaque); + + return ret ? ret : bitmap->err; } EXPORT_SYMBOL_NS_GPL(iova_bitmap_for_each, IOMMUFD); @@ -404,6 +409,18 @@ void iova_bitmap_set(struct iova_bitmap *bitmap, struct iova_bitmap_map *mapped = &bitmap->mapped; unsigned long cur_bit, last_bit, last_page_idx; + /* + * If the range cannot be recorded then the system call returns failure. + * This is to prevent loosing dirties if userspace is expecting to step + * the bitmap through the IOVA space. + */ + if (!length || length > bitmap->length || iova < bitmap->iova || + iova - bitmap->iova > bitmap->length - length) { + if (!bitmap->err) + bitmap->err = -EPROTO; + return; + } + update_indexes: if (unlikely(!iova_bitmap_mapped_range(mapped, iova, length))) { diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h index 41048271a0667..e245fa295662a 100644 --- a/include/uapi/linux/iommufd.h +++ b/include/uapi/linux/iommufd.h @@ -621,6 +621,12 @@ enum iommufd_hwpt_get_dirty_bitmap_flags { * Walk the IOMMU pagetables for a given IOVA range to return a bitmap * with the dirty IOVAs. In doing so it will also by default clear any * dirty bit metadata set in the IOPTE. + * + * The IOVA range given must fully enclose any IOPTE. If the range starts or + * ends inside a dirty IOPTE then the ioctl will fail. This avoids partially + * reporting a dirty range. + * + * On failure the dirty state becomes unknown and the userspace must restart. */ struct iommu_hwpt_get_dirty_bitmap { __u32 size; -- 2.53.0