From: Robin Murphy <robin.murphy@arm.com>
To: yf.wang@mediatek.com, Christoph Hellwig <hch@lst.de>,
Marek Szyprowski <m.szyprowski@samsung.com>,
Matthias Brugger <matthias.bgg@gmail.com>,
"open list:DMA MAPPING HELPERS" <iommu@lists.linux.dev>,
open list <linux-kernel@vger.kernel.org>,
"moderated list:ARM/Mediatek SoC support"
<linux-arm-kernel@lists.infradead.org>,
"moderated list:ARM/Mediatek SoC support"
<linux-mediatek@lists.infradead.org>
Cc: wsd_upstream@mediatek.com, Libo Kang <Libo.Kang@mediatek.com>,
Ning Li <Ning.Li@mediatek.com>, Yong Wu <Yong.Wu@mediatek.com>,
Miles Chen <miles.chen@mediatek.com>,
jianjiao zeng <jianjiao.zeng@mediatek.com>
Subject: Re: [PATCH] dma-debug: Fix overflow issue in bucket_find_contain
Date: Mon, 1 Aug 2022 19:47:54 +0100 [thread overview]
Message-ID: <15735fab-e53d-e95d-84f8-ae2e435dbb78@arm.com> (raw)
In-Reply-To: <20220730114146.32669-1-yf.wang@mediatek.com>
On 2022-07-30 12:41, yf.wang@mediatek.com wrote:
> From: Yunfei Wang <yf.wang@mediatek.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@mediatek.com>
> Signed-off-by: Yunfei Wang <yf.wang@mediatek.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;
This seems a bit clunky since the first condition here effectively makes
the loop condition redundant.
FWIW I found the whole "range" business here rather hard to make sense
of - personally I'd calculate a lower bound for the address then just
iterate down to that, but maybe that's just me :/
Otherwise, at the very least we should be capping max_range so that the
loop doesn't go beyond HASH_SIZE iterations and pointlessly search the
same buckets more than once - it's stupid to even *get* to the point of
having to worry about that overflowing. Whether we really care about
dev_addr underflow is then another matter.
Really it would seem even more logical to make this a lower-level
function that can walk round the dma_entry_hash array directly and not
have to monkey about with the fake "index" entry at all, but cleaning up
the almost-unnecessary amount of internal abstractions here is maybe
more work than it's worth at this point.
Robin.
> +
> /*
> * 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);
> }
>
WARNING: multiple messages have this Message-ID (diff)
From: Robin Murphy <robin.murphy@arm.com>
To: yf.wang@mediatek.com, Christoph Hellwig <hch@lst.de>,
Marek Szyprowski <m.szyprowski@samsung.com>,
Matthias Brugger <matthias.bgg@gmail.com>,
"open list:DMA MAPPING HELPERS" <iommu@lists.linux.dev>,
open list <linux-kernel@vger.kernel.org>,
"moderated list:ARM/Mediatek SoC support"
<linux-arm-kernel@lists.infradead.org>,
"moderated list:ARM/Mediatek SoC support"
<linux-mediatek@lists.infradead.org>
Cc: wsd_upstream@mediatek.com, Libo Kang <Libo.Kang@mediatek.com>,
Ning Li <Ning.Li@mediatek.com>, Yong Wu <Yong.Wu@mediatek.com>,
Miles Chen <miles.chen@mediatek.com>,
jianjiao zeng <jianjiao.zeng@mediatek.com>
Subject: Re: [PATCH] dma-debug: Fix overflow issue in bucket_find_contain
Date: Mon, 1 Aug 2022 19:47:54 +0100 [thread overview]
Message-ID: <15735fab-e53d-e95d-84f8-ae2e435dbb78@arm.com> (raw)
In-Reply-To: <20220730114146.32669-1-yf.wang@mediatek.com>
On 2022-07-30 12:41, yf.wang@mediatek.com wrote:
> From: Yunfei Wang <yf.wang@mediatek.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@mediatek.com>
> Signed-off-by: Yunfei Wang <yf.wang@mediatek.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;
This seems a bit clunky since the first condition here effectively makes
the loop condition redundant.
FWIW I found the whole "range" business here rather hard to make sense
of - personally I'd calculate a lower bound for the address then just
iterate down to that, but maybe that's just me :/
Otherwise, at the very least we should be capping max_range so that the
loop doesn't go beyond HASH_SIZE iterations and pointlessly search the
same buckets more than once - it's stupid to even *get* to the point of
having to worry about that overflowing. Whether we really care about
dev_addr underflow is then another matter.
Really it would seem even more logical to make this a lower-level
function that can walk round the dma_entry_hash array directly and not
have to monkey about with the fake "index" entry at all, but cleaning up
the almost-unnecessary amount of internal abstractions here is maybe
more work than it's worth at this point.
Robin.
> +
> /*
> * 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);
> }
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2022-08-01 18:48 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-30 11:41 [PATCH] dma-debug: Fix overflow issue in bucket_find_contain yf.wang
2022-07-30 11:41 ` yf.wang
2022-08-01 17:57 ` Christoph Hellwig
2022-08-01 17:57 ` Christoph Hellwig
2022-08-01 18:47 ` Robin Murphy [this message]
2022-08-01 18:47 ` Robin Murphy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=15735fab-e53d-e95d-84f8-ae2e435dbb78@arm.com \
--to=robin.murphy@arm.com \
--cc=Libo.Kang@mediatek.com \
--cc=Ning.Li@mediatek.com \
--cc=Yong.Wu@mediatek.com \
--cc=hch@lst.de \
--cc=iommu@lists.linux.dev \
--cc=jianjiao.zeng@mediatek.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=m.szyprowski@samsung.com \
--cc=matthias.bgg@gmail.com \
--cc=miles.chen@mediatek.com \
--cc=wsd_upstream@mediatek.com \
--cc=yf.wang@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.