* [PATCH] media: cxd2099: bound the CAM reply length in read_data
@ 2026-07-01 12:36 Maoyi Xie
0 siblings, 0 replies; only message in thread
From: Maoyi Xie @ 2026-07-01 12:36 UTC (permalink / raw)
To: Jasmin Jessich; +Cc: linux-media, linux-kernel
read_data() drains the CAM FIFO into ci->rbuf with a length the CAM
controls:
len = ((u16)msb << 8) | lsb;
if (len > ecount || len < 2) {
/* read it anyway or cxd may hang */
read_block(ci, 0x12, ci->rbuf, len);
msb and lsb come from two CAM registers, so len can be as large as 65535.
ci->rbuf is u8 rbuf[1028], and wbuf[1028] follows it as the last member of
struct cxd. read_block() advances the destination pointer for each chunk it
reads, and it never checks the buffer size. A len above 1028 runs past rbuf
into wbuf, then off the end of the struct.
The drain branch runs whenever len is larger than ecount, and the caller
caps ecount at 512. A CAM length from 1029 to 65535 writes up to about 63KB
past the buffer.
This only happens with buffermode=1, which is not the default. A faulty CAM
reaches the path the same as a malicious one.
Three sibling frontends already guard this. s5h1420, stb0899 and tda10071
bound the device length to the destination before they copy. read_data()
now clamps len to sizeof(ci->rbuf) before the drain read. The FIFO still
drains and the write stays in bounds.
Fixes: 2748e76ddb29 ("media: staging: cxd2099: Activate cxd2099 buffer mode")
Cc: stable@vger.kernel.org
Co-developed-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
Signed-off-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
---
I do not have the hardware. The out-of-bounds write was shown with a small
harness that models the rbuf and wbuf tail, not on a real device.
drivers/media/dvb-frontends/cxd2099.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/media/dvb-frontends/cxd2099.c b/drivers/media/dvb-frontends/cxd2099.c
index f95950a613..67b2ac4464 100644
--- a/drivers/media/dvb-frontends/cxd2099.c
+++ b/drivers/media/dvb-frontends/cxd2099.c
@@ -560,6 +560,8 @@ static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
len = ((u16)msb << 8) | lsb;
if (len > ecount || len < 2) {
/* read it anyway or cxd may hang */
+ if (len > sizeof(ci->rbuf))
+ len = sizeof(ci->rbuf);
read_block(ci, 0x12, ci->rbuf, len);
mutex_unlock(&ci->lock);
return -EIO;
--
2.34.1
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-01 12:36 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-01 12:36 [PATCH] media: cxd2099: bound the CAM reply length in read_data Maoyi Xie
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox