Message ID | 1424335255-7517-1-git-send-email-srinivas.kandagatla@linaro.org |
---|---|
State | New |
Headers | show |
On 19/02/15 10:31, Mark Brown wrote: > On Thu, Feb 19, 2015 at 08:40:55AM +0000, Srinivas Kandagatla wrote: >> regmap_bulk_write() ends up using the path that invokes _regmap_raw_write(), >> however _regmap_raw_write() never checks if the registers that are accessed >> are actually within the accessible range. This results in kernel crashes when >> trying to access registers beyond max_registers. >> >> This patch just adds check before accessing the register range. > >> /* Check for unwritable registers before we start */ >> - if (map->writeable_reg) >> - for (i = 0; i < val_len / map->format.val_bytes; i++) >> - if (!map->writeable_reg(map->dev, >> - reg + (i * map->reg_stride))) >> - return -EINVAL; >> + for (i = 0; i < count; i++) >> + if (!regmap_writeable(map, reg + (i * map->reg_stride))) >> + return -EINVAL; > > Your changelog doesn't correspond to what the code is actually doing > here... what you're actually doing here is replacing an open coding of > regmap_writeable() with calls to the function. > > The same papering over the cracks concerns do apply here as well, it's > not immediately obvious that this is a good fix for the issue you > describe. Only reason for me to send this patch was that fact that _regmap_raw_write() also suffers from same issue as _regmap_raw_read(), which is "access beyond max_register". Should I drop this patch? Or Adding similar check of max_register before the writing makes sense? --srini -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index d480e49..32ce7b3 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1202,16 +1202,14 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg, void *buf; int ret = -ENOTSUPP; size_t len; - int i; + int i, count = val_len/map->format.val_bytes; WARN_ON(!map->bus); /* Check for unwritable registers before we start */ - if (map->writeable_reg) - for (i = 0; i < val_len / map->format.val_bytes; i++) - if (!map->writeable_reg(map->dev, - reg + (i * map->reg_stride))) - return -EINVAL; + for (i = 0; i < count; i++) + if (!regmap_writeable(map, reg + (i * map->reg_stride))) + return -EINVAL; if (!map->cache_bypass && map->format.parse_val) { unsigned int ival;
regmap_bulk_write() ends up using the path that invokes _regmap_raw_write(), however _regmap_raw_write() never checks if the registers that are accessed are actually within the accessible range. This results in kernel crashes when trying to access registers beyond max_registers. This patch just adds check before accessing the register range. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> --- drivers/base/regmap/regmap.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)