提交 0398bdaa 编写于 作者: Y Yang Yingliang 提交者: Zheng Zengkai

regmap: Fix possible double-free in regcache_rbtree_exit()

stable inclusion
from stable-5.10.77
commit 36e911a16b377bde0ad91a8c679069d0d310b1a6
bugzilla: 185677 https://gitee.com/openeuler/kernel/issues/I4IAP7

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=36e911a16b377bde0ad91a8c679069d0d310b1a6

--------------------------------

commit 55e6d803 upstream.

In regcache_rbtree_insert_to_block(), when 'present' realloc failed,
the 'blk' which is supposed to assign to 'rbnode->block' will be freed,
so 'rbnode->block' points a freed memory, in the error handling path of
regcache_rbtree_init(), 'rbnode->block' will be freed again in
regcache_rbtree_exit(), KASAN will report double-free as follows:

BUG: KASAN: double-free or invalid-free in kfree+0xce/0x390
Call Trace:
 slab_free_freelist_hook+0x10d/0x240
 kfree+0xce/0x390
 regcache_rbtree_exit+0x15d/0x1a0
 regcache_rbtree_init+0x224/0x2c0
 regcache_init+0x88d/0x1310
 __regmap_init+0x3151/0x4a80
 __devm_regmap_init+0x7d/0x100
 madera_spi_probe+0x10f/0x333 [madera_spi]
 spi_probe+0x183/0x210
 really_probe+0x285/0xc30

To fix this, moving up the assignment of rbnode->block to immediately after
the reallocation has succeeded so that the data structure stays valid even
if the second reallocation fails.
Reported-by: NHulk Robot <hulkci@huawei.com>
Fixes: 3f4ff561 ("regmap: rbtree: Make cache_present bitmap per node")
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Link: https://lore.kernel.org/r/20211012023735.1632786-1-yangyingliang@huawei.comSigned-off-by: NMark Brown <broonie@kernel.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Acked-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 9070ee4f
...@@ -281,14 +281,14 @@ static int regcache_rbtree_insert_to_block(struct regmap *map, ...@@ -281,14 +281,14 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
if (!blk) if (!blk)
return -ENOMEM; return -ENOMEM;
rbnode->block = blk;
if (BITS_TO_LONGS(blklen) > BITS_TO_LONGS(rbnode->blklen)) { if (BITS_TO_LONGS(blklen) > BITS_TO_LONGS(rbnode->blklen)) {
present = krealloc(rbnode->cache_present, present = krealloc(rbnode->cache_present,
BITS_TO_LONGS(blklen) * sizeof(*present), BITS_TO_LONGS(blklen) * sizeof(*present),
GFP_KERNEL); GFP_KERNEL);
if (!present) { if (!present)
kfree(blk);
return -ENOMEM; return -ENOMEM;
}
memset(present + BITS_TO_LONGS(rbnode->blklen), 0, memset(present + BITS_TO_LONGS(rbnode->blklen), 0,
(BITS_TO_LONGS(blklen) - BITS_TO_LONGS(rbnode->blklen)) (BITS_TO_LONGS(blklen) - BITS_TO_LONGS(rbnode->blklen))
...@@ -305,7 +305,6 @@ static int regcache_rbtree_insert_to_block(struct regmap *map, ...@@ -305,7 +305,6 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
} }
/* update the rbnode block, its size and the base register */ /* update the rbnode block, its size and the base register */
rbnode->block = blk;
rbnode->blklen = blklen; rbnode->blklen = blklen;
rbnode->base_reg = base_reg; rbnode->base_reg = base_reg;
rbnode->cache_present = present; rbnode->cache_present = present;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册