Skip to contentSkip to conversation

media: dib8000: validate SNR exponent before shifting

PATCH New Ilya Krutskih 1 participant 1 message Oct 24

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 media: dib8000: validate SNR exponent before shifting

The exponent extracted from the hardware register can produce a shift count outside the valid range for u32.

Keep the signal and noise mantissas unsigned, as they are used in unsigned fixed-point arithmetic. Check exponent values before shifting by check_shl_overflow().

Return the existing invalid SNR value when the exponent cannot be represented safely.

Fixes 77e2c0f5d471 ("V4L/DVB (12900): DiB8000: added support for DiBcom ISDB-T/ISDB-Tsb demodulator DiB8000")

---
v1->v2: fix unsigned value checked against zero warning

 drivers/media/dvb-frontends/dib8000.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/media/dvb-frontends/dib8000.c +7 -4
index d291113291e0..c9873659d5f5 100644
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/mutex.h>
+#include <linux/overflow.h>
 #include <asm/div64.h>
 
 #include <linux/int_log.h>
@@ -3869,21 +3870,23 @@ static u32 dib8000_get_snr(struct dvb_frontend *fe)
 		val = dib8000_read_word(state, 542);
 	else
 		val = dib8000_read_word(state, 544);
-	n = (val >> 6) & 0xff;
+	n = (val >> 6) & 0xffU;
 	exp = (val & 0x3f);
 	if ((exp & 0x20) != 0)
 		exp -= 0x40;
-	n <<= exp+16;
+	if (check_shl_overflow(n, exp + 16, &n))
+		return 0xffffffff;
 
 	if (state->revision != 0x8090)
 		val = dib8000_read_word(state, 543);
 	else
 		val = dib8000_read_word(state, 545);
-	s = (val >> 6) & 0xff;
+	s = (val >> 6) & 0xffU;
 	exp = (val & 0x3f);
 	if ((exp & 0x20) != 0)
 		exp -= 0x40;
-	s <<= exp+16;
+	if (check_shl_overflow(s, exp + 16, &s))
+		return 0xffffffff;
 
 	if (n > 0) {
 		u32 t = (s/n) << 16;
Signature · 1 line
2.43.0