Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fba97387 authored by Vidyakumar Athota's avatar Vidyakumar Athota Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarVidyakumar Athota <vathota@codeaurora.org>
parent 2e45ea72
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -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",
+1 −1
Original line number Diff line number Diff line
@@ -476,7 +476,7 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr,
{
	struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
	int ret = 0;
	int val = 0;
	int val;
	u8 *reg_val = (u8 *)buf;

	if (!swrm) {