]> www.infradead.org Git - users/hch/misc.git/commitdiff
lib: scatterlist: fix sg_split_phys to preserve original scatterlist offsets
authorT Pratham <t-pratham@ti.com>
Wed, 19 Mar 2025 11:14:38 +0000 (16:44 +0530)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 1 Apr 2025 22:20:46 +0000 (15:20 -0700)
The split_sg_phys function was incorrectly setting the offsets of all
scatterlist entries (except the first) to 0.  Only the first scatterlist
entry's offset and length needs to be modified to account for the skip.
Setting the rest entries' offsets to 0 could lead to incorrect data
access.

I am using this function in a crypto driver that I'm currently developing
(not yet sent to mailing list).  During testing, it was observed that the
output scatterlists (except the first one) contained incorrect garbage
data.

I narrowed this issue down to the call of sg_split().  Upon debugging
inside this function, I found that this resetting of offset is the cause
of the problem, causing the subsequent scatterlists to point to incorrect
memory locations in a page.  By removing this code, I am obtaining
expected data in all the split output scatterlists.  Thus, this was indeed
causing observable runtime effects!

This patch removes the offending code, ensuring that the page offsets in
the input scatterlist are preserved in the output scatterlist.

Link: https://lkml.kernel.org/r/20250319111437.1969903-1-t-pratham@ti.com
Fixes: f8bcbe62acd0 ("lib: scatterlist: add sg splitting function")
Signed-off-by: T Pratham <t-pratham@ti.com>
Cc: Robert Jarzmik <robert.jarzmik@free.fr>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Kamlesh Gurudasani <kamlesh@ti.com>
Cc: Praneeth Bajjuri <praneeth@ti.com>
Cc: Vignesh Raghavendra <vigneshr@ti.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
lib/sg_split.c

index 60a0babebf2efca4f94ebcf3bf160be8715c2a30..0f89aab5c6715b23fe01ee60d662097f6235ea3d 100644 (file)
@@ -88,8 +88,6 @@ static void sg_split_phys(struct sg_splitter *splitters, const int nb_splits)
                        if (!j) {
                                out_sg->offset += split->skip_sg0;
                                out_sg->length -= split->skip_sg0;
-                       } else {
-                               out_sg->offset = 0;
                        }
                        sg_dma_address(out_sg) = 0;
                        sg_dma_len(out_sg) = 0;