From nobody Thu Apr 2 19:00:20 2026 Received: from cae.in-ulm.de (cae.in-ulm.de [217.10.14.231]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0152B2FFFA4 for ; Thu, 26 Mar 2026 21:50:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.10.14.231 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774561804; cv=none; b=ptTwUyEd7h/CvCZoPI9dLOpYtWZNL40M/Hi5RnDKhsss1xR5KA7IBjF2XPAtipUquFdx0vQvIo/XSItoGl/Wj+ImBo25lwe5EQDA61jDm8SJqv6QvSx+6kaoTfpK0oaXLYqEdzB8WhJy6ZVdMcSA68+HLlI8GPnS8cswbnB4lCs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774561804; c=relaxed/simple; bh=nLxxNoQnD6+iHksHGNd8u/32drnToEAaTpw1aqoQYR8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tj2nzxL4J4mXQZBQyvZ48XuL831RI+KnyJerXPIkty7yxBK+OdMFae2e0tomrGngGlLJLZQu1YkrN8TT+FxOT66Ifpf9stjAdIOsnJ1WNVK39wEY3mueDCswyOZu5mDXqqnvvf/5R1T0fO8C9zyEd6A/byJi00YRA4DwrZ4GngA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de; spf=pass smtp.mailfrom=c--e.de; arc=none smtp.client-ip=217.10.14.231 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=c--e.de Received: by cae.in-ulm.de (Postfix, from userid 1000) id CEC1314005A; Thu, 26 Mar 2026 22:49:58 +0100 (CET) From: "Christian A. Ehrhardt" To: David Howells , Andrew Morton , linux-kernel@vger.kernel.org Cc: "Christian A. Ehrhardt" , Kees Cook , Petr Mladek , David Gow Subject: [PATCH v3 1/5] lib/scatterlist: Fix length calculations in extract_kvec_to_sg Date: Thu, 26 Mar 2026 22:49:01 +0100 Message-Id: <20260326214905.818170-2-lk@c--e.de> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260326214905.818170-1-lk@c--e.de> References: <20260326214905.818170-1-lk@c--e.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When extracting from a kvec to a scatterlist, do not cross page boundaries. The required length was already calculated but not used as intended. Adjust the copied length if the loop runs out of sglist entries without extracting everything. While there, return immediately from extract_iter_to_sg if there are no sglist entries at all. A subsequent commit will add kunit test cases that demonstrate that the patch is necessary. Cc: David Howells Cc: Andrew Morton Cc: stable@vger.kernel.org # v6.5+ Fixes: 018584697533 ("netfs: Add a function to extract an iterator into a s= catterlist") Signed-off-by: Christian A. Ehrhardt --- lib/scatterlist.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/scatterlist.c b/lib/scatterlist.c index d773720d11bf..befdc4b9c11d 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -1247,7 +1247,7 @@ static ssize_t extract_kvec_to_sg(struct iov_iter *it= er, else page =3D virt_to_page((void *)kaddr); =20 - sg_set_page(sg, page, len, off); + sg_set_page(sg, page, seg, off); sgtable->nents++; sg++; sg_max--; @@ -1256,6 +1256,7 @@ static ssize_t extract_kvec_to_sg(struct iov_iter *it= er, kaddr +=3D PAGE_SIZE; off =3D 0; } while (len > 0 && sg_max > 0); + ret -=3D len; =20 if (maxsize <=3D 0 || sg_max =3D=3D 0) break; @@ -1409,7 +1410,7 @@ ssize_t extract_iter_to_sg(struct iov_iter *iter, siz= e_t maxsize, struct sg_table *sgtable, unsigned int sg_max, iov_iter_extraction_t extraction_flags) { - if (maxsize =3D=3D 0) + if (maxsize =3D=3D 0 || sg_max =3D=3D 0) return 0; =20 switch (iov_iter_type(iter)) { --=20 2.43.0 From nobody Thu Apr 2 19:00:20 2026 Received: from cae.in-ulm.de (cae.in-ulm.de [217.10.14.231]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A8F50311975 for ; Thu, 26 Mar 2026 21:50:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.10.14.231 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774561806; cv=none; b=enWnwm93oLRTbqoX8RexviDfA6dpbm4ZgBkV95x/0IenYTRnJi9TRy3vOuZaFisAv/VtQCMDdZ1ZxE7g+kfyBqGmfHGpnCG0QvCZO2ho/hrFqP3sJIjugIjEHlM7rt3Ocvakq0aYwWfTjuUC3MgaLcG7K224Z+FILwU3NblaNHI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774561806; c=relaxed/simple; bh=7nMEYL8GMl79aYoftSqkErZnLzdcdCYk9bmWpRZ+OBY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ppsurH4WHi72jyl13pUWHbfALzKM7q4FQj8VsafIRld8Vx+ex51EAcf/lZkE46uCf3JJYnbNUD2kNMjNH8Czj0eSpPfp8h1omSkO0LrxDMxQUnFuCOD8aVc0Zu24yfLHwhZZbAa6MzCazCHL/ib1QDIx8nVp0WMVMPi+ipLgeN0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de; spf=pass smtp.mailfrom=c--e.de; arc=none smtp.client-ip=217.10.14.231 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=c--e.de Received: by cae.in-ulm.de (Postfix, from userid 1000) id 8CE7E140060; Thu, 26 Mar 2026 22:50:01 +0100 (CET) From: "Christian A. Ehrhardt" To: David Howells , Andrew Morton , linux-kernel@vger.kernel.org Cc: "Christian A. Ehrhardt" , Kees Cook , Petr Mladek , David Gow Subject: [PATCH v3 2/5] lib/scatterlist: Fix temp buffer in extract_user_to_sg() Date: Thu, 26 Mar 2026 22:49:02 +0100 Message-Id: <20260326214905.818170-3-lk@c--e.de> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260326214905.818170-1-lk@c--e.de> References: <20260326214905.818170-1-lk@c--e.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Instead of allocating a temporary buffer for extracted user pages extract_user_to_sg() uses the end of the to be filled scatterlist as a temporary buffer. Fix the calculation of the start address if the scatterlist already contains elements. The unused space starts at sgtable->sgl + sgtable->nents not directly at sgtable->nents and the temporary buffer is placed at the end of this unused space. A subsequent commit will add kunit test cases that demonstrate that the patch is necessary. Pointed out by sashiko.dev on a previous iteration of this series. Cc: David Howells Cc: Andrew Morton Cc: stable@vger.kernel.org # v6.5+ Fixes: 018584697533 ("netfs: Add a function to extract an iterator into a s= catterlist") Signed-off-by: Christian A. Ehrhardt --- lib/scatterlist.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/scatterlist.c b/lib/scatterlist.c index befdc4b9c11d..b7fe91ef35b8 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -1123,8 +1123,7 @@ static ssize_t extract_user_to_sg(struct iov_iter *it= er, size_t len, off; =20 /* We decant the page list into the tail of the scatterlist */ - pages =3D (void *)sgtable->sgl + - array_size(sg_max, sizeof(struct scatterlist)); + pages =3D (void *)sg + array_size(sg_max, sizeof(struct scatterlist)); pages -=3D sg_max; =20 do { --=20 2.43.0 From nobody Thu Apr 2 19:00:20 2026 Received: from cae.in-ulm.de (cae.in-ulm.de [217.10.14.231]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9975E31F988 for ; Thu, 26 Mar 2026 21:50:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.10.14.231 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774561809; cv=none; b=NtTUMM/FABm56w2pZVtjRK9VIKhdjnw5Ap8PKpLxhn+n+cQyrkMyohjNX+D9Zn4wMXuVi3huR+U3Ka9/bz3YhTvBoVkENdjo7FZk/HfmWn9Y+QkYt3ErQ/hv8MNOjkQgMEIX2nZoSi49zPf8PSoOfK0FqcVHQRFkwjs7WcpfhFs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774561809; c=relaxed/simple; bh=qBdb4sKfmFcI3Bd8QhXn6f/HK5yrx8opiqiAmEzG9wM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=S/kJh+XLlFbh9ZoMRTGFqc5++a8Yyx8Wa20Rn1hKTLcH/03VXlazZM/HBSyAP5/h+MNHI1NUgRT8Oc6JWV3jdjG88luzS+VjbhurcCq+7mo422lLTAWYKA+sxwXrwhox0kjBBdTvNpdTDJQ0ookOHTi3JH6DEp75YRAh8d0jOl0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de; spf=pass smtp.mailfrom=c--e.de; arc=none smtp.client-ip=217.10.14.231 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=c--e.de Received: by cae.in-ulm.de (Postfix, from userid 1000) id 0361614005A; Thu, 26 Mar 2026 22:50:04 +0100 (CET) From: "Christian A. Ehrhardt" To: David Howells , Andrew Morton , linux-kernel@vger.kernel.org Cc: "Christian A. Ehrhardt" , Kees Cook , Petr Mladek , David Gow Subject: [PATCH v3 3/5] lib: kunit_iov_iter: Fix memory leaks Date: Thu, 26 Mar 2026 22:49:03 +0100 Message-Id: <20260326214905.818170-4-lk@c--e.de> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260326214905.818170-1-lk@c--e.de> References: <20260326214905.818170-1-lk@c--e.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use vfree() instead of vunmap() to free the buffer allocated by iov_kunit_create_buffer() because vunmap() does not honour VM_MAP_PUT_PAGES. In order for this to work the page array itself must not be managed by kunit. Remove the folio_put() when destroying a folioq. This is handled by vfree(), now. Pointed out by sashiko.dev on a previous iteration of this series. Tested by running the kunit test 10000 times in a loop. Cc: David Howells Cc: Andrew Morton Fixes: 2d71340ff1d4 ("iov_iter: Kunit tests for copying to/from an iterator= ") Signed-off-by: Christian A. Ehrhardt --- lib/tests/kunit_iov_iter.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/tests/kunit_iov_iter.c b/lib/tests/kunit_iov_iter.c index bb847e5010eb..d16449bdb833 100644 --- a/lib/tests/kunit_iov_iter.c +++ b/lib/tests/kunit_iov_iter.c @@ -42,7 +42,7 @@ static inline u8 pattern(unsigned long x) =20 static void iov_kunit_unmap(void *data) { - vunmap(data); + vfree(data); } =20 static void *__init iov_kunit_create_buffer(struct kunit *test, @@ -53,17 +53,22 @@ static void *__init iov_kunit_create_buffer(struct kuni= t *test, unsigned long got; void *buffer; =20 - pages =3D kunit_kcalloc(test, npages, sizeof(struct page *), GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pages); + pages =3D kzalloc_objs(struct page *, npages, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pages); *ppages =3D pages; =20 got =3D alloc_pages_bulk(GFP_KERNEL, npages, pages); if (got !=3D npages) { release_pages(pages, got); + kvfree(pages); KUNIT_ASSERT_EQ(test, got, npages); } =20 buffer =3D vmap(pages, npages, VM_MAP | VM_MAP_PUT_PAGES, PAGE_KERNEL); + if (buffer =3D=3D NULL) { + release_pages(pages, got); + kvfree(pages); + } KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buffer); =20 kunit_add_action_or_reset(test, iov_kunit_unmap, buffer); @@ -369,9 +374,6 @@ static void iov_kunit_destroy_folioq(void *data) =20 for (folioq =3D data; folioq; folioq =3D next) { next =3D folioq->next; - for (int i =3D 0; i < folioq_nr_slots(folioq); i++) - if (folioq_folio(folioq, i)) - folio_put(folioq_folio(folioq, i)); kfree(folioq); } } --=20 2.43.0 From nobody Thu Apr 2 19:00:20 2026 Received: from cae.in-ulm.de (cae.in-ulm.de [217.10.14.231]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E5E573246E8 for ; Thu, 26 Mar 2026 21:50:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.10.14.231 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774561810; cv=none; b=RZhVkluFcV4bz5eNC12EZL6ev2au8/5AQuLtB39429iuwjXNPbZgo7L0qRQSJabIm3aiR6EGZT5hHvjgglQMyAVuBNLKFN0TyMr1d7cqZ/q64nqFDCX6Efr3FA3qx1B99gpIBsArfcfs3Qur4KrzeXprVMZfq1cSIhHJFQF6/2Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774561810; c=relaxed/simple; bh=vkGW6xKDaw9eBT3dKHpPQ1oYcSujzKf44AiIkFp2+tw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=spamTDWHomVwkbVfRG3gLiIcqZXf7fb6/fshoCuuvV7cZ3UT1LJls1CxPpEXIefr0gvKXetody4T/IZA37FL/5ZE7tH1fvaYJtD1GhYLTp7wDoBmBUL1gunUoJGyebVCBEAmqF9b9t4/yBTltpn/HczCks2M2bewS+RSSd3vUEs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de; spf=pass smtp.mailfrom=c--e.de; arc=none smtp.client-ip=217.10.14.231 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=c--e.de Received: by cae.in-ulm.de (Postfix, from userid 1000) id 97BA4140041; Thu, 26 Mar 2026 22:50:06 +0100 (CET) From: "Christian A. Ehrhardt" To: David Howells , Andrew Morton , linux-kernel@vger.kernel.org Cc: "Christian A. Ehrhardt" , Kees Cook , Petr Mladek , David Gow Subject: [PATCH v3 4/5] lib: kunit_iov_iter: Improve error detection Date: Thu, 26 Mar 2026 22:49:04 +0100 Message-Id: <20260326214905.818170-5-lk@c--e.de> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260326214905.818170-1-lk@c--e.de> References: <20260326214905.818170-1-lk@c--e.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the kunit_iov_iter test prevent the kernel buffer from being a single physically contiguous region. Additionally, make sure that the test pattern written to a page in the buffer depends on the offset of the page within the buffer. Cc: David Howells Cc: Andrew Morton Signed-off-by: Christian A. Ehrhardt --- lib/tests/kunit_iov_iter.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/tests/kunit_iov_iter.c b/lib/tests/kunit_iov_iter.c index d16449bdb833..64a4e2f3eafa 100644 --- a/lib/tests/kunit_iov_iter.c +++ b/lib/tests/kunit_iov_iter.c @@ -13,6 +13,7 @@ #include #include #include +#include #include =20 MODULE_DESCRIPTION("iov_iter testing"); @@ -37,7 +38,7 @@ static const struct kvec_test_range kvec_test_ranges[] = =3D { =20 static inline u8 pattern(unsigned long x) { - return x & 0xff; + return (u8)x + (u8)(x >> 8) + (u8)(x >> 16); } =20 static void iov_kunit_unmap(void *data) @@ -52,6 +53,7 @@ static void *__init iov_kunit_create_buffer(struct kunit = *test, struct page **pages; unsigned long got; void *buffer; + unsigned int i; =20 pages =3D kzalloc_objs(struct page *, npages, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pages); @@ -63,6 +65,9 @@ static void *__init iov_kunit_create_buffer(struct kunit = *test, kvfree(pages); KUNIT_ASSERT_EQ(test, got, npages); } + /* Make sure that we don't get a physically contiguous buffer. */ + for (i =3D 0; i < npages / 4; ++i) + swap(pages[i], pages[i + npages / 2]); =20 buffer =3D vmap(pages, npages, VM_MAP | VM_MAP_PUT_PAGES, PAGE_KERNEL); if (buffer =3D=3D NULL) { --=20 2.43.0 From nobody Thu Apr 2 19:00:20 2026 Received: from cae.in-ulm.de (cae.in-ulm.de [217.10.14.231]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BDC4E155A5D for ; Thu, 26 Mar 2026 21:50:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.10.14.231 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774561814; cv=none; b=bFRB/f7MnmIlwYQqBU26Uy36F/E4jSXM1jovJGwCHheqzOTWQ0B5mwk9X5dbtfSVhwyEsn536fijDBpLA3WaJx2pnfDdXsV5jbNbipu0tgKmfTS3l781IXWO9NUN37yVdFdPj0Zkn6LO+Lzl0k44xuSUaw2zrt6kHz26P7L22Qc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774561814; c=relaxed/simple; bh=IQ/ya0iUzvy0q0KOyG3NbNkr0gHSkUm/bYk/UhSkDmY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=qVmMk9t2zNI9aa5qhTldOZZFMxUlXPgi6RIt2d/iR2KAhBzwD4kO0BQCloJfQwrhkw8G+6tnESEJ6BCIMuwgc6SubZyAuBZmr59BFWOpw+ifwvUlW9I12dRDkImDZggbn9SySrrZttylgqEONGVT7F4REpF3twO6eAmqTqPRCVc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de; spf=pass smtp.mailfrom=c--e.de; arc=none smtp.client-ip=217.10.14.231 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=c--e.de Received: by cae.in-ulm.de (Postfix, from userid 1000) id CDDAF140060; Thu, 26 Mar 2026 22:50:08 +0100 (CET) From: "Christian A. Ehrhardt" To: David Howells , Andrew Morton , linux-kernel@vger.kernel.org Cc: "Christian A. Ehrhardt" , Kees Cook , Petr Mladek , David Gow Subject: [PATCH v3 5/5] lib: kunit_iov_iter: Add tests for extract_iter_to_sg Date: Thu, 26 Mar 2026 22:49:05 +0100 Message-Id: <20260326214905.818170-6-lk@c--e.de> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260326214905.818170-1-lk@c--e.de> References: <20260326214905.818170-1-lk@c--e.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add test cases that test extract_iter_to_sg. For each iterator type an iterator is loaded with a suitable buffer. The iterator is then extracted to a scatterlist with multiple calls to extract_iter_to_sg. The final scatterlist is copied into a scratch buffer. The test passes if the scratch buffer contains the same data as the original buffer. The new tests demonstrate bugs in extract_iter_to_sg for kvec and user iterators that are fixed by the previous commits. Cc: David Howells Cc: Andrew Morton Signed-off-by: Christian A. Ehrhardt --- lib/tests/kunit_iov_iter.c | 203 +++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) diff --git a/lib/tests/kunit_iov_iter.c b/lib/tests/kunit_iov_iter.c index 64a4e2f3eafa..37bd6eb25896 100644 --- a/lib/tests/kunit_iov_iter.c +++ b/lib/tests/kunit_iov_iter.c @@ -13,7 +13,9 @@ #include #include #include +#include #include +#include #include =20 MODULE_DESCRIPTION("iov_iter testing"); @@ -1016,6 +1018,202 @@ static void __init iov_kunit_extract_pages_xarray(s= truct kunit *test) KUNIT_SUCCEED(test); } =20 +struct iov_kunit_iter_to_sg_data { + struct sg_table *sgt; + u8 *buffer, *scratch; + u8 __user *ubuf; + struct page **pages; + size_t npages; +}; + +static void __init +iov_kunit_iter_unpin_sgt(void *data) +{ + struct sg_table *sgt =3D data; + + for (unsigned int i =3D 0; i < sgt->nents; ++i) + unpin_user_page(sg_page(&sgt->sgl[i])); +} + +static void __init +iov_kunit_iter_to_sg_init(struct kunit *test, size_t bufsize, bool user, + struct iov_kunit_iter_to_sg_data *data) +{ + struct page **spages; + struct scatterlist *sg; + unsigned long uaddr; + size_t i; + + data->npages =3D bufsize / PAGE_SIZE; + sg =3D kunit_kmalloc_array(test, data->npages, sizeof(*sg), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sg); + sg_init_table(sg, data->npages); + data->sgt =3D kunit_kzalloc(test, sizeof(*data->sgt), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, data->sgt); + data->sgt->orig_nents =3D 0; + data->sgt->sgl =3D sg; + + data->buffer =3D NULL; + data->ubuf =3D NULL; + if (user) { + uaddr =3D kunit_vm_mmap(test, NULL, 0, bufsize, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, 0); + KUNIT_ASSERT_NE(test, uaddr, 0); + data->ubuf =3D (u8 __user *)uaddr; + for (i =3D 0; i < bufsize; ++i) + put_user(pattern(i), data->ubuf + i); + } else { + data->buffer =3D iov_kunit_create_buffer(test, &data->pages, + data->npages); + for (i =3D 0; i < bufsize; ++i) + data->buffer[i] =3D pattern(i); + } + data->scratch =3D iov_kunit_create_buffer(test, &spages, data->npages); + memset(data->scratch, 0, bufsize); +} + +static void __init +iov_kunit_iter_to_sg_check(struct kunit *test, struct iov_iter *iter, + size_t bufsize, + struct iov_kunit_iter_to_sg_data *data) +{ + static const size_t tail =3D 16 * PAGE_SIZE; + size_t i; + + KUNIT_ASSERT_LT(test, tail, bufsize); + + if (iov_iter_extract_will_pin(iter)) + kunit_add_action_or_reset(test, iov_kunit_iter_unpin_sgt, + data->sgt); + + i =3D extract_iter_to_sg(iter, bufsize, data->sgt, 0, 0); + KUNIT_ASSERT_EQ(test, i, 0); + KUNIT_ASSERT_EQ(test, data->sgt->nents, 0); + + i =3D extract_iter_to_sg(iter, bufsize - tail, data->sgt, 1, 0); + KUNIT_ASSERT_LE(test, i, bufsize - tail); + KUNIT_ASSERT_EQ(test, data->sgt->nents, 1); + + i +=3D extract_iter_to_sg(iter, bufsize - tail - i, data->sgt, + data->npages - data->sgt->nents, 0); + KUNIT_ASSERT_EQ(test, i, bufsize - tail); + KUNIT_ASSERT_LE(test, data->sgt->nents, data->npages); + + i +=3D extract_iter_to_sg(iter, tail, data->sgt, + data->npages - data->sgt->nents, 0); + KUNIT_ASSERT_EQ(test, i, bufsize); + KUNIT_ASSERT_LE(test, data->sgt->nents, data->npages); + + sg_mark_end(&data->sgt->sgl[data->sgt->nents - 1]); + + i =3D sg_copy_to_buffer(data->sgt->sgl, data->sgt->nents, + data->scratch, bufsize); + KUNIT_ASSERT_EQ(test, i, bufsize); + + for (i =3D 0; i < bufsize; ++i) { + KUNIT_EXPECT_EQ_MSG(test, data->scratch[i], pattern(i), + "at i=3D%zx", i); + if (data->scratch[i] !=3D pattern(i)) + break; + } + + KUNIT_EXPECT_EQ(test, i, bufsize); +} + +static void __init iov_kunit_iter_to_sg_kvec(struct kunit *test) +{ + struct iov_kunit_iter_to_sg_data data; + struct iov_iter iter; + struct kvec kvec; + size_t bufsize; + + bufsize =3D 0x100000; + iov_kunit_iter_to_sg_init(test, bufsize, false, &data); + + kvec.iov_base =3D data.buffer; + kvec.iov_len =3D bufsize; + iov_iter_kvec(&iter, READ, &kvec, 1, bufsize); + + iov_kunit_iter_to_sg_check(test, &iter, bufsize, &data); +} + +static void __init iov_kunit_iter_to_sg_bvec(struct kunit *test) +{ + struct iov_kunit_iter_to_sg_data data; + struct page *p, *can_merge =3D NULL; + size_t i, k, bufsize; + struct bio_vec *bvec; + struct iov_iter iter; + + bufsize =3D 0x100000; + iov_kunit_iter_to_sg_init(test, bufsize, false, &data); + + bvec =3D kunit_kmalloc_array(test, data.npages, sizeof(*bvec), + GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bvec); + k =3D 0; + for (i =3D 0; i < data.npages; ++i) { + p =3D data.pages[i]; + if (p =3D=3D can_merge) + bvec[k-1].bv_len +=3D PAGE_SIZE; + else + bvec_set_page(&bvec[k++], p, PAGE_SIZE, 0); + can_merge =3D p + 1; + } + iov_iter_bvec(&iter, READ, bvec, k, bufsize); + + iov_kunit_iter_to_sg_check(test, &iter, bufsize, &data); +} + +static void __init iov_kunit_iter_to_sg_folioq(struct kunit *test) +{ + struct iov_kunit_iter_to_sg_data data; + struct folio_queue *folioq; + struct iov_iter iter; + size_t bufsize; + + bufsize =3D 0x100000; + iov_kunit_iter_to_sg_init(test, bufsize, false, &data); + + folioq =3D iov_kunit_create_folioq(test); + iov_kunit_load_folioq(test, &iter, READ, folioq, data.pages, + data.npages); + + iov_kunit_iter_to_sg_check(test, &iter, bufsize, &data); +} + +static void __init iov_kunit_iter_to_sg_xarray(struct kunit *test) +{ + struct iov_kunit_iter_to_sg_data data; + struct xarray *xarray; + struct iov_iter iter; + size_t bufsize; + + bufsize =3D 0x100000; + iov_kunit_iter_to_sg_init(test, bufsize, false, &data); + + xarray =3D iov_kunit_create_xarray(test); + iov_kunit_load_xarray(test, &iter, READ, xarray, data.pages, + data.npages); + + iov_kunit_iter_to_sg_check(test, &iter, bufsize, &data); +} + +static void __init iov_kunit_iter_to_sg_ubuf(struct kunit *test) +{ + struct iov_kunit_iter_to_sg_data data; + struct iov_iter iter; + size_t bufsize; + + bufsize =3D 0x100000; + iov_kunit_iter_to_sg_init(test, bufsize, true, &data); + + iov_iter_ubuf(&iter, READ, data.ubuf, bufsize); + + iov_kunit_iter_to_sg_check(test, &iter, bufsize, &data); +} + static struct kunit_case __refdata iov_kunit_cases[] =3D { KUNIT_CASE(iov_kunit_copy_to_kvec), KUNIT_CASE(iov_kunit_copy_from_kvec), @@ -1029,6 +1227,11 @@ static struct kunit_case __refdata iov_kunit_cases[]= =3D { KUNIT_CASE(iov_kunit_extract_pages_bvec), KUNIT_CASE(iov_kunit_extract_pages_folioq), KUNIT_CASE(iov_kunit_extract_pages_xarray), + KUNIT_CASE(iov_kunit_iter_to_sg_kvec), + KUNIT_CASE(iov_kunit_iter_to_sg_bvec), + KUNIT_CASE(iov_kunit_iter_to_sg_folioq), + KUNIT_CASE(iov_kunit_iter_to_sg_xarray), + KUNIT_CASE(iov_kunit_iter_to_sg_ubuf), {} }; =20 --=20 2.43.0