]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
media: ddbridge/mci: protect against out-of-bounds array access in stop()
authorDaniel Scheller <d.scheller@gmx.net>
Wed, 9 May 2018 20:08:00 +0000 (16:08 -0400)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Mon, 28 May 2018 21:43:20 +0000 (17:43 -0400)
In stop(), an (unlikely) out-of-bounds write error can occur when setting
the demod_in_use element indexed by state->demod to zero, as state->demod
isn't checked for being in the range of the array size of demod_in_use, and
state->demod maybe carrying the magic 0xff (demod unused) value. Prevent
this by checking state->demod not exceeding the array size before setting
the element value. To make the code a bit easier to read, replace the magic
value and the number of array elements with defines, and use them at a few
more places.

Detected by CoverityScan, CID#1468550 ("Out-of-bounds write")

Thanks to Colin for reporting the problem and providing an initial patch.

Fixes: daeeb1319e6f ("media: ddbridge: initial support for MCI-based MaxSX8 cards")
Reported-by: Colin Ian King <colin.king@canonical.com>
Cc: Ralph Metzler <rjkm@metzlerbros.de>
Signed-off-by: Daniel Scheller <d.scheller@gmx.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/media/pci/ddbridge/ddbridge-mci.c
drivers/media/pci/ddbridge/ddbridge-mci.h

index a85ff3e6b91917c0e9aa8767c0d5f14ac979725d..8d9592e75ad5800f32adc99f276a1edbbf85ec7b 100644 (file)
@@ -38,10 +38,10 @@ struct mci_base {
        struct mutex         mci_lock; /* concurrent MCI access lock */
        int                  count;
 
-       u8                   tuner_use_count[4];
-       u8                   assigned_demod[8];
-       u32                  used_ldpc_bitrate[8];
-       u8                   demod_in_use[8];
+       u8                   tuner_use_count[MCI_TUNER_MAX];
+       u8                   assigned_demod[MCI_DEMOD_MAX];
+       u32                  used_ldpc_bitrate[MCI_DEMOD_MAX];
+       u8                   demod_in_use[MCI_DEMOD_MAX];
        u32                  iq_mode;
 };
 
@@ -193,7 +193,7 @@ static int stop(struct dvb_frontend *fe)
        u32 input = state->tuner;
 
        memset(&cmd, 0, sizeof(cmd));
-       if (state->demod != 0xff) {
+       if (state->demod != DEMOD_UNUSED) {
                cmd.command = MCI_CMD_STOP;
                cmd.demod = state->demod;
                mci_cmd(state, &cmd, NULL);
@@ -209,10 +209,11 @@ static int stop(struct dvb_frontend *fe)
        state->base->tuner_use_count[input]--;
        if (!state->base->tuner_use_count[input])
                mci_set_tuner(fe, input, 0);
-       state->base->demod_in_use[state->demod] = 0;
+       if (state->demod < MCI_DEMOD_MAX)
+               state->base->demod_in_use[state->demod] = 0;
        state->base->used_ldpc_bitrate[state->nr] = 0;
-       state->demod = 0xff;
-       state->base->assigned_demod[state->nr] = 0xff;
+       state->demod = DEMOD_UNUSED;
+       state->base->assigned_demod[state->nr] = DEMOD_UNUSED;
        state->base->iq_mode = 0;
        mutex_unlock(&state->base->tuner_lock);
        state->started = 0;
@@ -250,7 +251,7 @@ static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config)
                stat = -EBUSY;
                goto unlock;
        }
-       for (i = 0; i < 8; i++) {
+       for (i = 0; i < MCI_DEMOD_MAX; i++) {
                used_ldpc_bitrate += state->base->used_ldpc_bitrate[i];
                if (state->base->demod_in_use[i])
                        used_demods++;
@@ -342,7 +343,7 @@ static int start_iq(struct dvb_frontend *fe, u32 ts_config)
                stat = -EBUSY;
                goto unlock;
        }
-       for (i = 0; i < 8; i++)
+       for (i = 0; i < MCI_DEMOD_MAX; i++)
                if (state->base->demod_in_use[i])
                        used_demods++;
        if (used_demods > 0) {
index c4193c5ee09544447feb1ace1a9ac01c062fb458..453dcb9f8208fc400eb3b8ed32fe8b45ad4adb74 100644 (file)
 #ifndef _DDBRIDGE_MCI_H_
 #define _DDBRIDGE_MCI_H_
 
+#define MCI_DEMOD_MAX                       8
+#define MCI_TUNER_MAX                       4
+#define DEMOD_UNUSED                        (0xFF)
+
 #define MCI_CONTROL                         (0x500)
 #define MCI_COMMAND                         (0x600)
 #define MCI_RESULT                          (0x680)