On 10/14/26 12:21, [email protected] wrote:
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:
- [High] block: type confusion in blk_rq_cur_bytes() due to bio_has_data() 
including REQ_DMABUF
--

commit 338a7d60f029eb7fdd6fca422f1d54a04222c016
Author: Pavel Begunkov <[email protected]>

block: introduce dma map backed bio type

This patch introduces a dma map backed bio type to support pre-mapped
buffers without requiring a generic bio_vec. It repurposes the bi_io_vec
space in struct bio to store a dma_buf_io_map when the REQ_DMABUF flag
is set. It also adds specific splitting logic based on the minimum
segment size provided by the map.

[ ... ]

diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 98e21b4cbf328..0cc09b975d8ff 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -233,7 +233,12 @@ struct bio {
        atomic_t                __bi_remaining;
/* The actual vec list, preserved by bio_reset() */
-       struct bio_vec          *bi_io_vec;
+       union {
+               struct bio_vec          *bi_io_vec;
+               /* Driver specific dma map, valid IFF REQ_DMABUF is set */
+               struct dma_buf_io_map   *bi_dmabuf_map;
+       };
+

[Severity: High]
Does this union introduce type confusion when existing block layer helpers
check bio_has_data()?

Because REQ_DMABUF is a flag rather than an operation type, bio_has_data() in
include/linux/bio.h will still return true for read/write requests carrying
this flag.

When a driver partially completes a REQ_DMABUF request, blk_update_request()
calls blk_rq_cur_bytes() in include/linux/blk-mq.h to verify the size of the
remaining segment:

IIUC, blk-mq.c doesn't do partial updates with blk_update_request(), and
so that recalc shouldn't be reachable for nvme. Would be good to update,
but should be reasonable to do it a bit later.


include/linux/blk-mq.h:blk_rq_cur_bytes() {
     ...
     if (!bio_has_data(rq->bio))
         return rq->bio->bi_iter.bi_size;
     return bio_iovec(rq->bio).bv_len;
}

Since bio_has_data() is true, blk_rq_cur_bytes() invokes
bio_iovec(rq->bio).bv_len. This macro treats the bio->bi_dmabuf_map pointer
as an array of struct bio_vec, reading bv_len from the overlapping bytes of
the dma_buf_io_map struct.

If this garbage value is larger than the remaining blk_rq_bytes(req), it
corrupts req->__data_len and can trigger out-of-bounds memory access or
panics when the request resumes. Should bio_has_data() be updated to
exclude REQ_DMABUF, or is there another way to prevent blk_rq_cur_bytes()
from blindly dereferencing the dma map as a bio_vec?


--
Pavel Begunkov

Reply via email to