mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: <linux-media@dittrich.top>
To: <linux-media@vger.kernel.org>
Cc: <mchehab@kernel.org>, <nibble.max@gmail.com>,
	<linux-kernel@vger.kernel.org>
Subject: [RFC PATCH v2] media: smipcie: validate DMA lengths and avoid stale work
Date: Sat, 10 Oct 2026 01:45:40 +0200	[thread overview]
Message-ID: <041301dd5848$4af6c9c0$e0e45d40$@dittrich.top> (raw)
In-Reply-To: 

smi_dma_xfer() passes a register-derived length to the DVB demux without
checking it against the 192,512-byte DMA buffer. A zero register value
is interpreted as 4 MiB, allowing the demux to read beyond the buffer
if that completion is processed. Reject oversized lengths on both channels.

smi_start_feed() also unconditionally queues work without refreshing
_int_status. Clear the saved status and enable work before IRQ/DMA;
let a new IRQ queue the completion work.

A VDR 2.8.2 restart with two DVBSky S952 V3 cards caused a panic on
Debian 6.12.107-1 in the unmodified driver:
  RIP: dvb_dmx_swfilter_packets+0x5d/0x90 [dvb_core]
  Call Trace: smi_dma_xfer+0x154/0x210 [smipcie]
The exact IRQ sequence and DMA length at the crash were not captured,
so the connection to stale completion work remains a hypothesis.

Fixes: d32f9ff7376c ("[media] smipcie: SMI pcie bridge driver for DVBSky S950 V3 dvb-s/s2 cards")
Fixes: 1021dd010d21 ("media: Convert from tasklet to BH workqueue")
Reported-by: Michael Dittrich <linux-media@dittrich.top>
Closes: https://lore.kernel.org/r/000001dd4e71$a853ad30$f8fb0790$@dittrich.top
Cc: stable@vger.kernel.org
Assisted-by: LLM sparse smatch

Signed-off-by: Michael Dittrich <linux-media@dittrich.top>

---
v2: Correct the wrapped inline diff from the original report; code unchanged.

Base: media-committers next, checked on 10 October 2026:
d7e7bca7169873b46e857c025c10f3336c1258d8

The equivalent Debian fix passed ten VDR restarts and a reboot.
A stubbed test of the current source passed all 22-bit lengths on both
DMA channels and checked startup queuing/status. It does not test IRQ races.
Built on the above base as an x86_64 module with W=1 and section checks.
Sparse and Smatch found no smipcie diagnostics, as did the compiler.
The kernel build completed with warnings in unrelated, unchanged code.
No mainline hardware test or standalone mainline reproducer;
restart script and full trace are available to maintainers on request.

checkpatch --strict --no-signoff: one CHECK for existing finishedData;
retained to avoid unrelated renaming. AI assisted with source review,
the patch, tests and this message.

 drivers/media/pci/smipcie/smipcie-main.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/media/pci/smipcie/smipcie-main.c b/drivers/media/pci/smipcie/smipcie-main.c
--- a/drivers/media/pci/smipcie/smipcie-main.c
+++ b/drivers/media/pci/smipcie/smipcie-main.c
@@ -310,8 +310,15 @@
 				"DMA CH0 engine complete length mismatched, finish data=%d !\n",
 				finishedData);
 		}
-		dvb_dmx_swfilter_packets(&port->demux,
-			port->cpu_addr[0], (finishedData / 188));
+		/* Reject lengths exceeding the DMA buffer. */
+		if (finishedData > SMI_TS_DMA_BUF_SIZE)
+			dev_warn_ratelimited(&dev->pci_dev->dev,
+					     "DMA CH0 invalid length %u, dropping completion\n",
+					     finishedData);
+		else
+			dvb_dmx_swfilter_packets(&port->demux,
+						 port->cpu_addr[0],
+						 finishedData / 188);
 		/*dvb_dmx_swfilter(&port->demux,
 			port->cpu_addr[0], finishedData);*/
 	}
@@ -333,8 +340,15 @@
 				"DMA CH1 engine complete length mismatched, finish data=%d !\n",
 				finishedData);
 		}
-		dvb_dmx_swfilter_packets(&port->demux,
-			port->cpu_addr[1], (finishedData / 188));
+		/* Reject lengths exceeding the DMA buffer. */
+		if (finishedData > SMI_TS_DMA_BUF_SIZE)
+			dev_warn_ratelimited(&dev->pci_dev->dev,
+					     "DMA CH1 invalid length %u, dropping completion\n",
+					     finishedData);
+		else
+			dvb_dmx_swfilter_packets(&port->demux,
+						 port->cpu_addr[1],
+						 finishedData / 188);
 		/*dvb_dmx_swfilter(&port->demux,
 			port->cpu_addr[1], finishedData);*/
 	}
@@ -821,9 +835,11 @@
 	if (port->users++ == 0) {
 		dmaManagement = smi_config_DMA(port);
 		smi_port_clearInterrupt(port);
+		/* Clear stale status; let the IRQ queue work. */
+		port->_int_status = 0;
+		enable_work(&port->bh_work);
 		smi_port_enableInterrupt(port);
 		smi_write(port->DMA_MANAGEMENT, dmaManagement);
-		enable_and_queue_work(system_bh_wq, &port->bh_work);
 	}
 	return port->users;
 }


                 reply	other threads:[~2026-10-09 23:52 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='041301dd5848$4af6c9c0$e0e45d40$@dittrich.top' \
    --to=linux-media@dittrich.top \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=nibble.max@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®