On Tue Sep 22 15:53:27 2026 +0800, Guo Zihao wrote:
> cx18_mdl_update_bufs_for_cpu() copies mdl->bytesused straight into the
> buffer when the MDL holds a single buffer:
>
> if (list_is_singular(&mdl->buf_list)) {
> buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
> list);
> buf->bytesused = mdl->bytesused;
>
> The value originates from the firmware. cx18_queue_get_mdl() receives it
> as its bytesused argument and stores it in ret->bytesused; the mailbox
> handler calls it as cx18_queue_get_mdl(s, id, mdl_ack->data_used), so
> data_used from the firmware ACK is what ends up in the buffer. Firmware
> that reports more than the buffer holds leaves bytesused above
> s->buf_size, and two paths then use it as a bound over a buffer of that
> size.
>
> cx18_buf_swap() walks the buffer in 32 bit words up to bytesused and
> byteswaps them in place:
>
> for (i = 0; i < buf->bytesused; i += 4)
> swab32s((u32 *)(buf->buf + i));
>
> That writes past the end of buf->buf. The call comes from
> cx18_mdl_swap() for MPG streams when CX18_F_M_NEED_SWAP is set, which
> cx18_queue_get_mdl() does for every type except TS.
>
> cx18_copy_buf_to_user() computes the remaining length the same way:
>
> size_t len = buf->bytesused - buf->readpos;
>
> and copies it to userspace. Here len is capped at the count the reader
> asked for, so the read is bounded by the read() size, but it still
> starts from a bytesused that reaches past the buffer.
>
> The multi buffer path already guards this: _cx18_mdl_update_bufs_for_cpu()
> clamps each buffer to s->buf_size before assigning. Apply the same clamp
> in the single buffer case.
>
> The single buffer path is the common one here, not a corner case:
> cx18_stream_init() sets bufs_per_mdl to 1, so list_is_singular() is
> normally true.
>
> No Fixes tag. Both paths were introduced together with the driver
> (1c1e45d17b66, "V4L/DVB (7786): cx18: new driver for the Conexant
> CX23418 MPEG"), and the clamp in the multi buffer path was added later,
> leaving this one behind.
>
> Reviewed-by: Liu Chao <[email protected]>
> Assisted-by: LLM
> Signed-off-by: Guo Zihao <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>
Patch committed.
Thanks,
Hans Verkuil
drivers/media/pci/cx18/cx18-queue.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
---
diff --git a/drivers/media/pci/cx18/cx18-queue.c
b/drivers/media/pci/cx18/cx18-queue.c
index 04d6828f0259..a973367d4cde 100644
--- a/drivers/media/pci/cx18/cx18-queue.c
+++ b/drivers/media/pci/cx18/cx18-queue.c
@@ -114,7 +114,10 @@ static inline void cx18_mdl_update_bufs_for_cpu(struct
cx18_stream *s,
if (list_is_singular(&mdl->buf_list)) {
buf = list_first_entry(&mdl->buf_list, struct cx18_buffer,
list);
- buf->bytesused = mdl->bytesused;
+ if (mdl->bytesused > s->buf_size)
+ buf->bytesused = s->buf_size;
+ else
+ buf->bytesused = mdl->bytesused;
buf->readpos = 0;
cx18_buf_sync_for_cpu(s, buf);
} else {
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]