diff options
Diffstat (limited to 'drivers/media/dvb-frontends/cxd2820r_core.c')
| -rw-r--r-- | drivers/media/dvb-frontends/cxd2820r_core.c | 25 | 
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c index 7ca5c69dd20..03930d5e9fe 100644 --- a/drivers/media/dvb-frontends/cxd2820r_core.c +++ b/drivers/media/dvb-frontends/cxd2820r_core.c @@ -21,21 +21,31 @@  #include "cxd2820r_priv.h" +/* Max transfer size done by I2C transfer functions */ +#define MAX_XFER_SIZE  64 +  /* write multiple registers */  static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,  	u8 *val, int len)  {  	int ret; -	u8 buf[len+1]; +	u8 buf[MAX_XFER_SIZE];  	struct i2c_msg msg[1] = {  		{  			.addr = i2c,  			.flags = 0, -			.len = sizeof(buf), +			.len = len + 1,  			.buf = buf,  		}  	}; +	if (1 + len > sizeof(buf)) { +		dev_warn(&priv->i2c->dev, +			 "%s: i2c wr reg=%04x: len=%d is too big!\n", +			 KBUILD_MODNAME, reg, len); +		return -EINVAL; +	} +  	buf[0] = reg;  	memcpy(&buf[1], val, len); @@ -55,7 +65,7 @@ static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,  	u8 *val, int len)  {  	int ret; -	u8 buf[len]; +	u8 buf[MAX_XFER_SIZE];  	struct i2c_msg msg[2] = {  		{  			.addr = i2c, @@ -65,11 +75,18 @@ static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,  		}, {  			.addr = i2c,  			.flags = I2C_M_RD, -			.len = sizeof(buf), +			.len = len,  			.buf = buf,  		}  	}; +	if (len > sizeof(buf)) { +		dev_warn(&priv->i2c->dev, +			 "%s: i2c wr reg=%04x: len=%d is too big!\n", +			 KBUILD_MODNAME, reg, len); +		return -EINVAL; +	} +  	ret = i2c_transfer(priv->i2c, msg, 2);  	if (ret == 2) {  		memcpy(val, buf, len);  | 
