[PATCH] media: tda10086: avoid division by zero in set_symbol_rate()

From: Guo Zihao

Date: Thu Sep 17 2026 - 08:36:23 EST


tda10086_set_symbol_rate() derives the decimation factor, the
anti-aliasing filter setting and the BDRI register value from the symbol
rate that userspace supplies through the DTV_SYMBOL_RATE property. That
value is never validated, and the BDRI calculation divides by it:

tmp = (1<<dfn)*(symbol_rate/1000);
bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp;

SACLK is 96000000, so any symbol rate below 1000 makes symbol_rate/1000
evaluate to zero. tmp then becomes zero as well and the division traps
in the kernel.

Reject symbol rates below 1000 with -EINVAL before the divisions. That
matches the precedent in stv0367cab_set_frontend(), which carries the
comment "protect against division error oopses" and rejects a symbol
rate of zero for the same reason.

No Fixes tag. The calculation and its missing validation both date back
to the original driver import (9a0bf528b4d6, 2012), so there is no
single commit that introduced the problem.

Reviewed-by: Liu Chao <liuc63@xxxxxxxxxxxx>
Signed-off-by: Guo Zihao <guozh23@xxxxxxxxxxxx>
---
The divide is reachable from any DVB-S userspace that issues
FE_SET_FRONTEND with a small symbol rate via DTV_SYMBOL_RATE; no
hardware-specific condition is involved. Verified by code inspection
only - reaching set_frontend at runtime needs a tda10086 based tuner,
which I do not have.

While preparing this I checked how the other dvb-frontends drivers
handle symbol_rate. mt312 and stv0299 only compare the value and never
divide by it, stv0910 checks the range and returns -EINVAL, and stv0367
rejects zero explicitly, so tda10086 is the outlier here.

drivers/media/dvb-frontends/tda10086.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/media/dvb-frontends/tda10086.c b/drivers/media/dvb-frontends/tda10086.c
index d43d0eb73..c76d5fc25 100644
--- a/drivers/media/dvb-frontends/tda10086.c
+++ b/drivers/media/dvb-frontends/tda10086.c
@@ -296,6 +296,11 @@ static int tda10086_set_symbol_rate(struct tda10086_state *state,

dprintk ("%s %i\n", __func__, symbol_rate);

+ if (symbol_rate < 1000) {
+ dprintk("%s: symbol rate %u too small\n", __func__, symbol_rate);
+ return -EINVAL;
+ }
+
/* setup the decimation and anti-aliasing filters.. */
if (symbol_rate < SACLK / 10000 * 137) {
dfn=4;
--
2.50.1