lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Sat, 30 Jul 2022 19:41:45 +0800 From: <yf.wang@...iatek.com> To: Christoph Hellwig <hch@....de>, Robin Murphy <robin.murphy@....com>, "Marek Szyprowski" <m.szyprowski@...sung.com>, Matthias Brugger <matthias.bgg@...il.com>, "open list:DMA MAPPING HELPERS" <iommu@...ts.linux.dev>, open list <linux-kernel@...r.kernel.org>, "moderated list:ARM/Mediatek SoC support" <linux-arm-kernel@...ts.infradead.org>, "moderated list:ARM/Mediatek SoC support" <linux-mediatek@...ts.infradead.org> CC: <wsd_upstream@...iatek.com>, Libo Kang <Libo.Kang@...iatek.com>, Ning Li <Ning.Li@...iatek.com>, Yong Wu <Yong.Wu@...iatek.com>, Miles Chen <miles.chen@...iatek.com>, Yunfei Wang <yf.wang@...iatek.com>, jianjiao zeng <jianjiao.zeng@...iatek.com> Subject: [PATCH] dma-debug: Fix overflow issue in bucket_find_contain From: Yunfei Wang <yf.wang@...iatek.com> There are two issue: 1. If max_rang is set to 0xFFFF_FFFF, and __hash_bucket_find always returns NULL, the rang will be accumulated. When rang is accumulated to 0xFFFF_E000, after executing rang += (1 << HASH_FN_SHIFT) again, rang will overflow to 0, making it impossible to exit the while loop. 2. dev_addr reduce maybe overflow. So, add range and dev_addr check to avoid overflow. Signed-off-by: jianjiao zeng <jianjiao.zeng@...iatek.com> Signed-off-by: Yunfei Wang <yf.wang@...iatek.com> --- kernel/dma/debug.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index ad731f7858c9..9d7d54cd4c63 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -352,6 +352,7 @@ static struct dma_debug_entry *bucket_find_contain(struct hash_bucket **bucket, unsigned int max_range = dma_get_max_seg_size(ref->dev); struct dma_debug_entry *entry, index = *ref; + unsigned int shift = (1 << HASH_FN_SHIFT); unsigned int range = 0; while (range <= max_range) { @@ -360,12 +361,15 @@ static struct dma_debug_entry *bucket_find_contain(struct hash_bucket **bucket, if (entry) return entry; + if (max_range - range < shift || index.dev_addr < shift) + return NULL; + /* * Nothing found, go back a hash bucket */ put_hash_bucket(*bucket, *flags); - range += (1 << HASH_FN_SHIFT); - index.dev_addr -= (1 << HASH_FN_SHIFT); + range += shift; + index.dev_addr -= shift; *bucket = get_hash_bucket(&index, flags); } -- 2.18.0
Powered by blists - more mailing lists