From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6DEA820C029 for ; Wed, 10 Jun 2026 22:39:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.44 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781131176; cv=none; b=f/lrRrF4xMH2UBDmKqDb7r+E00BKY9fWeKubgUtMxxcKH7ON1o6b3RMUK2hQCZZkLkqhwCurwp26Ta1JluZji0o8ACwqADjRQbL82Ce+mHLzXNjLOkJqKyX1iTWbkdZmmrUCGT50Jyywj/89vkv7j5zV1b0unQUaxSNQs9jBfOc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781131176; c=relaxed/simple; bh=Hv+HDAkHP/kdngnX448umnZ9r0VWuIrkJVCba3KgriU=; h=Date:From:To:Subject:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=HnZEQZ4AW7cstNM+XFvK3Ic+upMo6t1kpKfaIDxteO5HEyatKkXKNX3YX09G2yWuwB2p7rgszFhi6Ae2wWNKWRGekNyucqi65VQgRWepN2lwQAZFhST07uB7Rlip8AuHB00raOVwit0q7ocBDZxmWPD49f+Nwe0Jctc38UA+1SM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=T5ZHxuQM; arc=none smtp.client-ip=209.85.221.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="T5ZHxuQM" Received: by mail-wr1-f44.google.com with SMTP id ffacd0b85a97d-46019b190b6so5486682f8f.3 for ; Wed, 10 Jun 2026 15:39:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781131173; x=1781735973; darn=vger.kernel.org; h=mime-version:content-transfer-encoding:references:in-reply-to :message-id:subject:to:from:date:from:to:cc:subject:date:message-id :reply-to; bh=4exwYw439qu3/3mNc3n5Yemr37XsF9/x0MfMgKFazJ4=; b=T5ZHxuQMGYRM6jfUlmBsSGTViTxjZ81JVj5yfMC1YWjIiMIPlrFI4IG3kYGq1KO74G 3cHCz4PtTYhBe2oEt/eiGFsm1Iu0zbPJ/8iebAqV+nj90VM4k8RO+PsYn0rIIt7oqPVO VOVnvXtBek+aGK4pMyKbmfCiamz2L4bMShMlESQBEhRW2bubtVSZ2FRbKg5noEkjkmvY bf0ip/0/TwqYEfMw7ngelYYuaIqWg1Bb3r6qR2LLjcWxHLviZZXOqsmQsk7uKD3MuGII B5RaQ3Ii5Rucgb9iQFhNDFEFeYXMyTpZ0tWvFAvP0nAsPRaNQnUyEBkdK0i1jNjy3np2 3nWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781131173; x=1781735973; h=mime-version:content-transfer-encoding:references:in-reply-to :message-id:subject:to:from:date:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=4exwYw439qu3/3mNc3n5Yemr37XsF9/x0MfMgKFazJ4=; b=tXfB2JKbin58TM+ubhjFnUE7eqsn4wC1zkJ7NB+FfgVtUUU13WOxrfFKHR/cDGqFRq yYetK/712EPMh9DOtlrC5bGLLkBlFAVRjeDzf6RzQeOq9odpA65TPk4L/qvoFwMTV7Jp I3XMK4TN9mWcuuCljZBoyd/dZbkyKHY/DkV25Zd3vWPNIFofCM20ZdtR0k572xCXALVI Dt/VgO6UlqfDFI9Kd5Wkg8DJRWnST/wZ4/vOJUzZlIM8lpq6uW2DOu94OxBPW4jBKbId evGjaEJ5Y/riTLw/z3OuZzOvhkBdn92Gnfc2jTzcDSkCIV1ud2jDGqPj9t/KdKO8ysJp CIjA== X-Forwarded-Encrypted: i=1; AFNElJ/nwbOYuXw/JxvVYBRhJqlOZuVTIOCwr+nYS7jA1+YGUwEzRBOJc2xs/8nfaTTUF7w7kg/+8sc9tNbYUMc=@vger.kernel.org X-Gm-Message-State: AOJu0YzyRrNENg0DDUPM1co8Xd2lJR0sSmMx/jtnDZwd8tU4jxb++A4o +jcHizztpOrv5Jgd65u7EvjYQLbeP7yWY4HtAPpzOZpR4j4egkl+4e/B X-Gm-Gg: Acq92OFgIyHjcwjvcHfuZW6Ize/cOdqpNI4Fzi1M40FpRpJOhMqqkw27pgaASVBHfhD C6s99A6I11zeCvkUo79OnlZg2YCAgz6pAdr1z7puMvS8f2Be/w4eHSUN3lrvZD0iG1wKbiDyC7N 1eGXoK24KeEG6PORypBxzpmQdgnipBk5S7v4VVpwqc0iVotkg+4jidfHYbe1xEcn4OFYO8ywLqr +csjt/2yqysDOwutHWWY/gWJ3RBUDNz/iXSc5qxdsx2eJfdqAPN24AH+BR/JvsRbZvBl3JixXaw Wdq7KPOefN8jvnLR6Y3e/wvRbSBkrjPCoHDI9b4XbTGpGmDj5jYp803mB82tJOQNoRviVntq6Hi /yOuoffS8mdt0yhXM24BN8KQtbAfq/QlL1cU+FYZtgtxmc7pCf3QxGHM1bg2d1DvA3RPHy67C4Q nfkGcwNyggb2Ac6R0E7qE6MVe92oMXsZlFY0QnrX11H1fp5A== X-Received: by 2002:adf:ea51:0:b0:460:3210:4349 with SMTP id ffacd0b85a97d-46067800fcfmr142317f8f.42.1781131172833; Wed, 10 Jun 2026 15:39:32 -0700 (PDT) Received: from [127.0.0.1] ([141.255.129.1]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4601f360bd6sm81616932f8f.36.2026.06.10.15.39.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Jun 2026 15:39:32 -0700 (PDT) Date: Wed, 10 Jun 2026 15:39:32 -0700 (PDT) From: Charles Pellegrini To: akpm@linux-foundation.org, egorenar-dev@posteo.net, robert.jarzmik@free.fr, t-pratham@ti.com, david@davidgow.net, linux-kernel@vger.kernel.org Subject: [PATCH v2 0/5] lib: scatterlist: fix sg_split() partial-coverage geometry, two latent corruption bugs, and add KUnit tests Message-ID: <178113124323.90620.6403136846887207198@gmail.com> In-Reply-To: <178027099087.72481.1976843064458686851@gmail.com> References: <178027099087.72481.1976843064458686851@gmail.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 v1 was a 2-patch series (the overshoot fix + a KUnit suite). Andrew's review asked whether this was seen in real life -- it was not; it came from property-based testing, not a field report -- and pointed at an automated review (Sashiko) that flagged a pre-existing OOB and a bug in the test. Chasing those turned up a third, separate latent bug. v2 addresses all of it. sg_split() is EXPORT_SYMBOL'd, so its contract is "any caller, any split_sizes[]", not just the six in-tree call sites. None of the three bugs below is triggered by an in-tree caller today -- all are latent. So even without a real-world trigger, I think they're worth fixing. The three bugs (all Fixes: f8bcbe62acd0): 1. sg_calculate_split() nb_splits overshoot (the v1 fix, unchanged). Partial coverage ending mid-entry of a non-last input entry overshoots the counter to -1, misses the !nb_splits termination check, and folds a trailing entry into the last split. 2. sg_split_phys() ->length clobber. On !NEED_SG_DMA_LENGTH arches sg_dma_len() aliases ->length, so the DMA-scrub line zeroes the CPU length it has just computed; only the last entry is restored, so the non-last entries of a multi-entry split keep length 0 -> silent short data. Found while correcting the test argument below. 3. zero-nents ZERO_SIZE_PTR OOB. A trailing zero-size split that receives no input entry leaves out_sg == ZERO_SIZE_PTR; the out_sg[-1].length write is then out-of-bounds (KASAN splat). Flagged by the automated review; confirmed with KASAN and a userspace ASAN harness. Plus a test-argument fix folded into the suite: v1 passed in_mapped_nents = n_in for an unmapped list, where it must be 0. On NEED arches that drove the mapped pass to read a zeroed dma_length and return -EINVAL, so the suite would fail there (it passed on UML only because UML aliases dma_len onto ->length). Correcting it is what exposed bug 2. Patch layout (bisect-safe): 1/5 overshoot fix -- unchanged from v1 2/5 ->length clobber fix -- bug 2; lands before the test that exposes it 3/5 KUnit suite -- corrected in_mapped_nents; each case run unmapped AND identity-mapped; DMA-address + end-marker assertions; NEED-gated divergent-geometry cases 4/5 zero-nents OOB guard -- bug 3 5/5 zero-nents regression test -- guards 4/5 Patches 4 and 5 are an isolable tail: if you'd rather treat a malformed zero-size split as the caller's problem, they drop cleanly without touching 1-3. On that bug I went tolerate-and-skip rather than rejecting with -EINVAL, reasoning it's the droppable tail of the request -- trivial to respin to -EINVAL if you prefer the stricter contract. Testing. The suite runs each case both unmapped and identity-mapped (dma_len == length, contiguous IOVA) on all arches, plus NEED-gated divergent CPU/DMA geometry (coalescing) cases exercised on x86_64 with KASAN. Results: UML (!NEED) 17 passed / 3 skipped; x86_64 + KASAN 20/20. With bug 2 reverted, six unmapped multi-entry cases fail while their mapped variants pass, so the suite catches it. A real dma_map_sg / IOMMU rig is still deferred; the mapped coverage here is synthetic (identity mapping + injected coalescing). v1: https://lore.kernel.org/all/178027099087.72481.1976843064458686851@gmail.com/ Changes since v1: - corrected the KUnit in_mapped_nents argument (0 for unmapped lists) - new: sg_split_phys() ->length clobber fix (bug 2) - new: zero-nents OOB guard + its regression test (bug 3) - tests now run unmapped AND identity-mapped, with DMA-address and end-marker assertions and NEED-gated divergent-geometry cases - test file moved to lib/tests/sg_split_kunit.c (modern location); config moved to lib/Kconfig.debug, Makefile line to lib/tests/Makefile Charles Pellegrini (5): lib: scatterlist: fix sg_calculate_split() nb_splits overshoot on partial coverage lib: scatterlist: fix sg_split_phys() ->length clobber on !NEED_SG_DMA_LENGTH lib: scatterlist: add KUnit tests for sg_split() lib: scatterlist: guard sg_split_phys()/sg_split_mapped() against zero-nents splits lib: scatterlist: add zero-nents regression test for sg_split() lib/Kconfig.debug | 14 + lib/sg_split.c | 15 +- lib/tests/Makefile | 1 + lib/tests/sg_split_kunit.c | 526 +++++++++++++++++++++++++++++++++++++ 4 files changed, 552 insertions(+), 4 deletions(-) create mode 100644 lib/tests/sg_split_kunit.c -- 2.47.3