]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
media: mb86a16: avoid division by zero
authorMauro Carvalho Chehab <mchehab@s-opensource.com>
Wed, 1 Nov 2017 21:06:03 +0000 (17:06 -0400)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Mon, 11 Dec 2017 18:04:54 +0000 (13:04 -0500)
As warned by smatch:
drivers/media/dvb-frontends/mb86a16.c:1690 mb86a16_read_ber() error: uninitialized symbol 'timer'.
drivers/media/dvb-frontends/mb86a16.c:1706 mb86a16_read_ber() error: uninitialized symbol 'timer'.

There is a potential risk of doing a division by zero if
timer is not handled well. Enforce it by setting a bit mask
for the values used to select the timer.

It should be noticed that I don't have mb86a16 datasheet. So,
the bitmask was guessed based on the existing checks for
the field. At worse case scenario, it will just show a
badly calculated bit error rate, but it won't crash.

While here, optimize the logic to prevent uneeded tests.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/dvb-frontends/mb86a16.c

index f1aad52094c3d82a3327e99ee49fe459025d8a7b..5d2bb76bc07aad1efa6b536f714546414a9b6ddd 100644 (file)
@@ -1677,15 +1677,15 @@ static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
                         * the deinterleaver output.
                         * monitored BER is expressed as a 20 bit output in total
                         */
-                       ber_rst = ber_mon >> 3;
+                       ber_rst = (ber_mon >> 3) & 0x03;
                        *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
                        if (ber_rst == 0)
                                timer =  12500000;
-                       if (ber_rst == 1)
+                       else if (ber_rst == 1)
                                timer =  25000000;
-                       if (ber_rst == 2)
+                       else if (ber_rst == 2)
                                timer =  50000000;
-                       if (ber_rst == 3)
+                       else /* ber_rst == 3 */
                                timer = 100000000;
 
                        *ber /= timer;
@@ -1697,11 +1697,11 @@ static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
                         * QPSK demodulator output.
                         * monitored BER is expressed as a 24 bit output in total
                         */
-                       ber_tim = ber_mon >> 1;
+                       ber_tim = (ber_mon >> 1) & 0x01;
                        *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
                        if (ber_tim == 0)
                                timer = 16;
-                       if (ber_tim == 1)
+                       else /* ber_tim == 1 */
                                timer = 24;
 
                        *ber /= 2 ^ timer;