summaryrefslogtreecommitdiff
path: root/drivers/media/pci/ddbridge
diff options
context:
space:
mode:
authorDaniel Scheller <d.scheller@gmx.net>2018-05-09 23:08:00 +0300
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-05-29 00:43:20 +0300
commit525cac75740542e23c31cd0f248f9b29ae4978e9 (patch)
tree98a7ba3a1574f98363d98d67ebbc5e8970941656 /drivers/media/pci/ddbridge
parentd7832cd2a3c87eb6ae1e802c88b6fc56c5823f6d (diff)
downloadlinux-525cac75740542e23c31cd0f248f9b29ae4978e9.tar.xz
media: ddbridge/mci: protect against out-of-bounds array access in stop()
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>
Diffstat (limited to 'drivers/media/pci/ddbridge')
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-mci.c21
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-mci.h4
2 files changed, 15 insertions, 10 deletions
diff --git a/drivers/media/pci/ddbridge/ddbridge-mci.c b/drivers/media/pci/ddbridge/ddbridge-mci.c
index a85ff3e6b919..8d9592e75ad5 100644
--- a/drivers/media/pci/ddbridge/ddbridge-mci.c
+++ b/drivers/media/pci/ddbridge/ddbridge-mci.c
@@ -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) {
diff --git a/drivers/media/pci/ddbridge/ddbridge-mci.h b/drivers/media/pci/ddbridge/ddbridge-mci.h
index c4193c5ee095..453dcb9f8208 100644
--- a/drivers/media/pci/ddbridge/ddbridge-mci.h
+++ b/drivers/media/pci/ddbridge/ddbridge-mci.h
@@ -19,6 +19,10 @@
#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)