2022-03-31 04:44:54

by Xiaomeng Tong

[permalink] [raw]
Subject: [PATCH v2] opp: use list iterator only inside the loop

The list iterator 'new_dev' will point to a bogus position containing
HEAD if any one of these conditions is possible: the list is empty or
no element is found, thus can potentially lead to an invalid memory
access in 'dev = new_dev->dev;'.

As discussed before, we should avoid to use a list iterator variable
outside the loop which is considered harmful[1].

In this case, use a new variable 'iter' as the list iterator, while
use the old variable 'new_dev' as a dedicated pointer to point to the
found entry. And BUG_ON(!new_dev);.

[1]: https://lkml.org/lkml/2022/2/17/1032

Signed-off-by: Xiaomeng Tong <[email protected]>
---

changes since v1:
- use BUG_ON(!new_dev); instead of return; (Viresh Kumar)

v1: https://lore.kernel.org/lkml/[email protected]/

---
drivers/opp/debugfs.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c
index 596c185b5dda..81b2bc4b5f43 100644
--- a/drivers/opp/debugfs.c
+++ b/drivers/opp/debugfs.c
@@ -187,14 +187,18 @@ void opp_debug_register(struct opp_device *opp_dev, struct opp_table *opp_table)
static void opp_migrate_dentry(struct opp_device *opp_dev,
struct opp_table *opp_table)
{
- struct opp_device *new_dev;
+ struct opp_device *new_dev = NULL, *iter;
const struct device *dev;
struct dentry *dentry;

/* Look for next opp-dev */
- list_for_each_entry(new_dev, &opp_table->dev_list, node)
- if (new_dev != opp_dev)
+ list_for_each_entry(iter, &opp_table->dev_list, node)
+ if (iter != opp_dev) {
+ new_dev = iter;
break;
+ }
+
+ BUG_ON(!new_dev);

/* new_dev is guaranteed to be valid here */
dev = new_dev->dev;
--
2.17.1


2022-03-31 05:07:47

by Viresh Kumar

[permalink] [raw]
Subject: Re: [PATCH v2] opp: use list iterator only inside the loop

On 31-03-22, 10:36, Xiaomeng Tong wrote:
> The list iterator 'new_dev' will point to a bogus position containing
> HEAD if any one of these conditions is possible: the list is empty or
> no element is found, thus can potentially lead to an invalid memory
> access in 'dev = new_dev->dev;'.

There is no such bug as I explained earlier, why you added this again
despite being discussed ?

> As discussed before,

I just told you not to use such language as this will go in logs, but
you still chose to add it :(

> we should avoid to use a list iterator variable
> outside the loop which is considered harmful[1].
>
> In this case, use a new variable 'iter' as the list iterator, while
> use the old variable 'new_dev' as a dedicated pointer to point to the
> found entry. And BUG_ON(!new_dev);.

Please look at this on how to write the log, which fixes a very
similar problem.

https://lore.kernel.org/all/[email protected]/

>
> [1]: https://lkml.org/lkml/2022/2/17/1032
>
> Signed-off-by: Xiaomeng Tong <[email protected]>
> ---
>
> changes since v1:
> - use BUG_ON(!new_dev); instead of return; (Viresh Kumar)
>
> v1: https://lore.kernel.org/lkml/[email protected]/
>
> ---
> drivers/opp/debugfs.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c
> index 596c185b5dda..81b2bc4b5f43 100644
> --- a/drivers/opp/debugfs.c
> +++ b/drivers/opp/debugfs.c
> @@ -187,14 +187,18 @@ void opp_debug_register(struct opp_device *opp_dev, struct opp_table *opp_table)
> static void opp_migrate_dentry(struct opp_device *opp_dev,
> struct opp_table *opp_table)
> {
> - struct opp_device *new_dev;
> + struct opp_device *new_dev = NULL, *iter;
> const struct device *dev;
> struct dentry *dentry;
>
> /* Look for next opp-dev */
> - list_for_each_entry(new_dev, &opp_table->dev_list, node)
> - if (new_dev != opp_dev)
> + list_for_each_entry(iter, &opp_table->dev_list, node)
> + if (iter != opp_dev) {
> + new_dev = iter;
> break;
> + }
> +
> + BUG_ON(!new_dev);
>
> /* new_dev is guaranteed to be valid here */
> dev = new_dev->dev;
> --
> 2.17.1

--
viresh

2022-03-31 08:57:40

by Viresh Kumar

[permalink] [raw]
Subject: Re: [PATCH v2] opp: use list iterator only inside the loop

This is V3 and not V2. You need to be careful to update them for every
single version of patch you send.

On 31-03-22, 16:30, Xiaomeng Tong wrote:
> To move the list iterator variable into the list_for_each_entry_*()
> macro in the future it should be avoided to use the list iterator
> variable after the loop body.
>
> To *never* use the list iterator variable after the loop it was
> concluded to use a separate dedicated pointer variable [1].
>
> In this case, use a new variable 'iter' as the list iterator, while
> use the old variable 'new_dev' as a dedicated pointer to point to the
> found entry. And BUG_ON(!new_dev);.
>
> [1]: https://lore.kernel.org/all/CAHk-=wgRr_D8CB-D9Kg-c=EHreAsk5SqXPwr9Y7k9sA6cWXJ6w@mail.gmail.com/
>
> Signed-off-by: Xiaomeng Tong <[email protected]>
> ---
>
> changes since v1:
> - use BUG_ON(!new_dev); instead of return; (Viresh Kumar)
>
> v1: https://lore.kernel.org/lkml/[email protected]/
>
> ---
> drivers/opp/debugfs.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)

Looks good now. I will apply it in few days.

--
viresh

2022-03-31 11:45:15

by Xiaomeng Tong

[permalink] [raw]
Subject: Re: [PATCH v2] opp: use list iterator only inside the loop

On Thu, 31 Mar 2022 14:14:53 +0530, Viresh Kumar wrote:
> This is V3 and not V2. You need to be careful to update them for every
> single version of patch you send.
>

Thank you very much for your patient reply. I got it.

--
Xiaomeng Tong