diff options
Diffstat (limited to 'drivers/media/tuners/tda18218.c')
| -rw-r--r-- | drivers/media/tuners/tda18218.c | 23 | 
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/media/tuners/tda18218.c b/drivers/media/tuners/tda18218.c index 2d31aeb6b08..9300e9361e3 100644 --- a/drivers/media/tuners/tda18218.c +++ b/drivers/media/tuners/tda18218.c @@ -20,11 +20,14 @@  #include "tda18218_priv.h" +/* Max transfer size done by I2C transfer functions */ +#define MAX_XFER_SIZE  64 +  /* write multiple registers */  static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)  {  	int ret = 0, len2, remaining; -	u8 buf[1 + len]; +	u8 buf[MAX_XFER_SIZE];  	struct i2c_msg msg[1] = {  		{  			.addr = priv->cfg->i2c_address, @@ -33,6 +36,13 @@ static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)  		}  	}; +	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; +	} +  	for (remaining = len; remaining > 0;  			remaining -= (priv->cfg->i2c_wr_max - 1)) {  		len2 = remaining; @@ -63,7 +73,7 @@ static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)  static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)  {  	int ret; -	u8 buf[reg+len]; /* we must start read always from reg 0x00 */ +	u8 buf[MAX_XFER_SIZE]; /* we must start read always from reg 0x00 */  	struct i2c_msg msg[2] = {  		{  			.addr = priv->cfg->i2c_address, @@ -73,11 +83,18 @@ static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)  		}, {  			.addr = priv->cfg->i2c_address,  			.flags = I2C_M_RD, -			.len = sizeof(buf), +			.len = reg + len,  			.buf = buf,  		}  	}; +	if (reg + 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[reg], len);  | 
