diff options
| author | Vidyakumar Athota <vathota@codeaurora.org> | 2015-08-12 16:10:00 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-08-14 23:06:47 -0700 |
| commit | fba97387bef7f702fb2881e63cf0438036ad16f0 (patch) | |
| tree | 1291282d6436a95e38568f9ab127a13ad371c2c6 /drivers/base | |
| parent | 2e45ea728118fa88ba245a0a755d0a3844d9f54e (diff) | |
ASoC: soundwire: fix out of boundary access issues
In soundwire read/write commands, register value is defined
as 8 bit but it is accessed through 32 bit pointer which
may cause out of boundary memory access. Fix this issue by
typecast appropriately.
BUG: KASan: out of bounds access in swrm_read+0x1dc/0x30c at
addr ffffffc089871880
Write of size 4 by task kworker/u8:5/236
==addr ffffffc089871880
[<ffffffc00081d174>] swrm_read+0x1d8/0x30c
[<ffffffc000819808>] swr_read+0x5c/0x74
[<ffffffc000741e58>] regmap_swr_read+0xd8/0x11c
[<ffffffc00073a350>] _regmap_raw_read+0x210/0x314
[<ffffffc00073a4b0>] _regmap_bus_read+0x5c/0xb4
[<ffffffc000739548>] _regmap_read+0xe0/0x1ec
[<ffffffc0007396b8>] regmap_read+0x64/0xa8
[<ffffffc000dc9dd4>] snd_soc_component_read+0x34/0x70
[<ffffffc000dc9f44>] snd_soc_read+0x6c/0x94
Memory state around the buggy address:
ffffffc089871780: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffffffc089871800: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
Change-Id: I3c56dffb4ca197e8fc23d54a44282a60254dd001
Signed-off-by: Vidyakumar Athota <vathota@codeaurora.org>
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/regmap/regmap-swr.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/base/regmap/regmap-swr.c b/drivers/base/regmap/regmap-swr.c index 5ea67421ed85..027cbfc505ab 100644 --- a/drivers/base/regmap/regmap-swr.c +++ b/drivers/base/regmap/regmap-swr.c @@ -23,15 +23,15 @@ static int regmap_swr_gather_write(void *context, const void *reg, size_t reg_size, - const void *val, size_t val_size) + const void *val, size_t val_len) { struct device *dev = context; struct swr_device *swr = to_swr_device(dev); struct regmap *map = dev_get_regmap(dev, NULL); size_t addr_bytes = map->format.reg_bytes; - int ret = 0; - int i; - u32 reg_addr = 0; + size_t val_bytes; + int i, ret = 0; + u16 reg_addr = 0; if (swr == NULL) { dev_err(dev, "%s: swr device is NULL\n", __func__); @@ -43,12 +43,15 @@ static int regmap_swr_gather_write(void *context, return -EINVAL; } reg_addr = *(u16 *)reg; - for (i = 0; i < val_size; i++) { - ret = swr_write(swr, swr->dev_num, (reg_addr+i), - (u32 *)(val+i)); + val_bytes = map->format.val_bytes; + /* val_len = val_bytes * val_count */ + for (i = 0; i < (val_len / val_bytes); i++) { + reg_addr = reg_addr + i; + val = (u8 *)val + (val_bytes * i); + ret = swr_write(swr, swr->dev_num, reg_addr, val); if (ret < 0) { dev_err(dev, "%s: write reg 0x%x failed, err %d\n", - __func__, (reg_addr+i), ret); + __func__, reg_addr, ret); break; } } @@ -153,7 +156,7 @@ static int regmap_swr_read(void *context, struct regmap *map = dev_get_regmap(dev, NULL); size_t addr_bytes = map->format.reg_bytes; int ret = 0; - u32 reg_addr = 0; + u16 reg_addr = 0; if (swr == NULL) { dev_err(dev, "%s: swr is NULL\n", __func__); @@ -164,7 +167,7 @@ static int regmap_swr_read(void *context, __func__, reg_size); return -EINVAL; } - reg_addr = *(u32 *)reg; + reg_addr = *(u16 *)reg; ret = swr_read(swr, swr->dev_num, reg_addr, val, val_size); if (ret < 0) dev_err(dev, "%s: codec reg 0x%x read failed %d\n", |
