summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends/cxd2841er.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab2015-08-11 20:22:36 +0200
committerMauro Carvalho Chehab2015-08-11 20:37:10 +0200
commitd13a7b674af085eb67df73a20f5cc77310dd8602 (patch)
tree5b54568be680da6a6b5394e15991aefc3e67f80f /drivers/media/dvb-frontends/cxd2841er.c
parent[media] netup_unidvb: NetUP Universal DVB-S/S2/T/T2/C PCI-E card driver (diff)
downloadkernel-qcow2-linux-d13a7b674af085eb67df73a20f5cc77310dd8602.tar.gz
kernel-qcow2-linux-d13a7b674af085eb67df73a20f5cc77310dd8602.tar.xz
kernel-qcow2-linux-d13a7b674af085eb67df73a20f5cc77310dd8602.zip
[media] cxd2841er: don't use variable length arrays
The Linux stack is short; we need to be able to count the number of bytes used at stack on each function. So, we don't like to use variable-length arrays, as complained by smatch: drivers/media/dvb-frontends/cxd2841er.c:205:19: warning: Variable length array is used. The max usecase of the driver seems to be 15 bytes + 1 for the register. So, let's be safe and allocate 17 bytes for the write buffer. This should be enough to cover all cases. If not, let's print an error message. Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/dvb-frontends/cxd2841er.c')
-rw-r--r--drivers/media/dvb-frontends/cxd2841er.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
index 0d1a15109d1e..fdffb2f0ded8 100644
--- a/drivers/media/dvb-frontends/cxd2841er.c
+++ b/drivers/media/dvb-frontends/cxd2841er.c
@@ -33,6 +33,8 @@
#include "cxd2841er.h"
#include "cxd2841er_priv.h"
+#define MAX_WRITE_REGSIZE 16
+
enum cxd2841er_state {
STATE_SHUTDOWN = 0,
STATE_SLEEP_S,
@@ -202,18 +204,24 @@ static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
u8 addr, u8 reg, const u8 *data, u32 len)
{
int ret;
- u8 buf[len+1];
+ u8 buf[MAX_WRITE_REGSIZE + 1];
u8 i2c_addr = (addr == I2C_SLVX ?
priv->i2c_addr_slvx : priv->i2c_addr_slvt);
struct i2c_msg msg[1] = {
{
.addr = i2c_addr,
.flags = 0,
- .len = sizeof(buf),
+ .len = len + 1,
.buf = buf,
}
};
+ if (len + 1 >= sizeof(buf)) {
+ dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n",
+ reg, len + 1);
+ return -E2BIG;
+ }
+
cxd2841er_i2c_debug(priv, i2c_addr, reg, 1, data, len);
buf[0] = reg;
memcpy(&buf[1], data, len);