linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Jakob Koschel <jakobkoschel@gmail.com>
To: Vladimir Oltean <olteanv@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Andrew Lunn <andrew@lunn.ch>,
	Vivien Didelot <vivien.didelot@gmail.com>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Lars Povlsen <lars.povlsen@microchip.com>,
	Steen Hegelund <Steen.Hegelund@microchip.com>,
	UNGLinuxDriver@microchip.com, Ariel Elior <aelior@marvell.com>,
	Manish Chopra <manishc@marvell.com>,
	Edward Cree <ecree.xilinx@gmail.com>,
	Martin Habets <habetsm.xilinx@gmail.com>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>, Jiri Pirko <jiri@resnulli.us>,
	Casper Andersson <casper.casan@gmail.com>,
	Bjarni Jonasson <bjarni.jonasson@microchip.com>,
	Colin Ian King <colin.king@intel.com>,
	Michael Walle <michael@walle.cc>,
	Christophe JAILLET <christophe.jaillet@wanadoo.fr>,
	Arnd Bergmann <arnd@arndb.de>, Eric Dumazet <edumazet@google.com>,
	Di Zhu <zhudi21@huawei.com>, Xu Wang <vulab@iscas.ac.cn>,
	Netdev <netdev@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Linux ARM <linux-arm-kernel@lists.infradead.org>,
	linuxppc-dev <linuxppc-dev@lists.ozlabs.org>,
	Mike Rapoport <rppt@kernel.org>,
	Brian Johannesmeyer <bjohannesmeyer@gmail.com>,
	Cristiano Giuffrida <c.giuffrida@vu.nl>,
	"Bos, H.J." <h.j.bos@vu.nl>
Subject: Re: [PATCH net-next 02/15] net: dsa: sja1105: Remove usage of iterator for list_add() after loop
Date: Sun, 10 Apr 2022 12:51:56 +0200	[thread overview]
Message-ID: <C9081CE3-B008-48DA-A97C-76F51D4F189F@gmail.com> (raw)
In-Reply-To: <FA317E17-3B09-411B-9DF6-05BDD320D988@gmail.com>

Hey Vladimir,

> On 9. Apr 2022, at 01:54, Jakob Koschel <jakobkoschel@gmail.com> wrote:
> 
> Hello Vladimir,
> 
>> On 8. Apr 2022, at 13:41, Vladimir Oltean <olteanv@gmail.com> wrote:
>> 
>> Hello Jakob,
>> 
>> On Thu, Apr 07, 2022 at 12:28:47PM +0200, Jakob Koschel wrote:
>>> In preparation to limit the scope of a list iterator to the list
>>> traversal loop, use a dedicated pointer to point to the found element [1].
>>> 
>>> Before, the code implicitly used the head when no element was found
>>> when using &pos->list. Since the new variable is only set if an
>>> element was found, the list_add() is performed within the loop
>>> and only done after the loop if it is done on the list head directly.
>>> 
>>> Link: https://lore.kernel.org/all/CAHk-=wgRr_D8CB-D9Kg-c=EHreAsk5SqXPwr9Y7k9sA6cWXJ6w@mail.gmail.com/ [1]
>>> Signed-off-by: Jakob Koschel <jakobkoschel@gmail.com>
>>> ---
>>> drivers/net/dsa/sja1105/sja1105_vl.c | 14 +++++++++-----
>>> 1 file changed, 9 insertions(+), 5 deletions(-)
>>> 
>>> diff --git a/drivers/net/dsa/sja1105/sja1105_vl.c b/drivers/net/dsa/sja1105/sja1105_vl.c
>>> index b7e95d60a6e4..cfcae4d19eef 100644
>>> --- a/drivers/net/dsa/sja1105/sja1105_vl.c
>>> +++ b/drivers/net/dsa/sja1105/sja1105_vl.c
>>> @@ -27,20 +27,24 @@ static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg,
>>> 	if (list_empty(&gating_cfg->entries)) {
>>> 		list_add(&e->list, &gating_cfg->entries);
>>> 	} else {
>>> -		struct sja1105_gate_entry *p;
>>> +		struct sja1105_gate_entry *p = NULL, *iter;
>>> 
>>> -		list_for_each_entry(p, &gating_cfg->entries, list) {
>>> -			if (p->interval == e->interval) {
>>> +		list_for_each_entry(iter, &gating_cfg->entries, list) {
>>> +			if (iter->interval == e->interval) {
>>> 				NL_SET_ERR_MSG_MOD(extack,
>>> 						 "Gate conflict");
>>> 				rc = -EBUSY;
>>> 				goto err;
>>> 			}
>>> 
>>> -			if (e->interval < p->interval)
>>> +			if (e->interval < iter->interval) {
>>> +				p = iter;
>>> +				list_add(&e->list, iter->list.prev);
>>> 				break;
>>> +			}
>>> 		}
>>> -		list_add(&e->list, p->list.prev);
>>> +		if (!p)
>>> +			list_add(&e->list, gating_cfg->entries.prev);
>>> 	}
>>> 
>>> 	gating_cfg->num_entries++;
>>> -- 
>>> 2.25.1
>>> 
>> 
>> I apologize in advance if I've misinterpreted the end goal of your patch.
>> I do have a vague suspicion I understand what you're trying to achieve,
>> and in that case, would you mind using this patch instead of yours?
> 
> I think you are very much spot on!
> 
>> I think it still preserves the intention of the code in a clean manner.
>> 
>> -----------------------------[ cut here ]-----------------------------
>> From 7aed740750d1bc3bff6e85fd33298f5905bb4e01 Mon Sep 17 00:00:00 2001
>> From: Vladimir Oltean <vladimir.oltean@nxp.com>
>> Date: Fri, 8 Apr 2022 13:55:14 +0300
>> Subject: [PATCH] net: dsa: sja1105: avoid use of type-confused pointer in
>> sja1105_insert_gate_entry()
>> 
>> It appears that list_for_each_entry() leaks a type-confused pointer when
>> the iteration loop ends with no early break, since "*p" will no longer
>> point to a "struct sja1105_gate_entry", but rather to some memory in
>> front of "gating_cfg->entries".
>> 
>> This isn't actually a problem here, because if the element we insert has
>> the highest interval, therefore we never exit the loop early, "p->list"
>> (which is all that we use outside the loop) will in fact point to
>> "gating_cfg->entries" even though "p" itself is invalid.
>> 
>> Nonetheless, there are preparations to increase the safety of
>> list_for_each_entry() by making it impossible to use the encapsulating
>> structure of the iterator element outside the loop. So something needs
>> to change here before those preparations go in, even though this
>> constitutes legitimate use.
>> 
>> Make it clear that we are not dereferencing members of the encapsulating
>> "struct sja1105_gate_entry" outside the loop, by using the regular
>> list_for_each() iterator, and dereferencing the struct sja1105_gate_entry
>> only within the loop.
>> 
>> With list_for_each(), the iterator element at the end of the loop does
>> have a sane value in all cases, and we can just use that as the "head"
>> argument of list_add().
>> 
>> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
>> ---
>> drivers/net/dsa/sja1105/sja1105_vl.c | 12 +++++++++---
>> 1 file changed, 9 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/net/dsa/sja1105/sja1105_vl.c b/drivers/net/dsa/sja1105/sja1105_vl.c
>> index c0e45b393fde..fe93c80fe5ef 100644
>> --- a/drivers/net/dsa/sja1105/sja1105_vl.c
>> +++ b/drivers/net/dsa/sja1105/sja1105_vl.c
>> @@ -27,9 +27,15 @@ static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg,
>> 	if (list_empty(&gating_cfg->entries)) {
>> 		list_add(&e->list, &gating_cfg->entries);
>> 	} else {
>> -		struct sja1105_gate_entry *p;
>> +		struct list_head *pos;
>> +
>> +		/* We cannot safely use list_for_each_entry()
>> +		 * because we dereference "pos" after the loop
>> +		 */
>> +		list_for_each(pos, &gating_cfg->entries) {
>> +			struct sja1105_gate_entry *p;
>> 
>> -		list_for_each_entry(p, &gating_cfg->entries, list) {
>> +			p = list_entry(pos, struct sja1105_gate_entry, list);
>> 			if (p->interval == e->interval) {
>> 				NL_SET_ERR_MSG_MOD(extack,
>> 						 "Gate conflict");
>> @@ -40,7 +46,7 @@ static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg,
>> 			if (e->interval < p->interval)
>> 				break;
>> 		}
>> -		list_add(&e->list, p->list.prev);
>> +		list_add(&e->list, pos->prev);
> 
> I was actually considering doing it this way before but wasn't sure if this would be preferred.
> I've done something like this in [1] and it does turn out quite well.
> 
> I'll integrate this in the v2 series.

I've just looked at this again in a bit more detail while integrating it into the patch series.

I realized that this just shifts the 'problem' to using the 'pos' iterator variable after the loop.
If the scope of the list iterator would be lowered to the list traversal loop it would also make sense
to also do it for list_for_each().

What do you think about doing it this way:

diff --git a/drivers/net/dsa/sja1105/sja1105_vl.c b/drivers/net/dsa/sja1105/sja1105_vl.c
index b7e95d60a6e4..f5b0502c1098 100644
--- a/drivers/net/dsa/sja1105/sja1105_vl.c
+++ b/drivers/net/dsa/sja1105/sja1105_vl.c
@@ -28,6 +28,7 @@ static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg,
                list_add(&e->list, &gating_cfg->entries);
        } else {
                struct sja1105_gate_entry *p;
+               struct list_head *pos = NULL;

                list_for_each_entry(p, &gating_cfg->entries, list) {
                        if (p->interval == e->interval) {
@@ -37,10 +38,14 @@ static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg,
                                goto err;
                        }

-                       if (e->interval < p->interval)
+                       if (e->interval < p->interval) {
+                               pos = &p->list;
                                break;
+                       }
                }
-               list_add(&e->list, p->list.prev);
+               if (!pos)
+                       pos = &gating_cfg->entries;
+               list_add(&e->list, pos->prev);
        }

        gating_cfg->num_entries++;
--

> 
> Thanks for the suggestion.
> 
>> 	}
>> 
>> 	gating_cfg->num_entries++;
>> -----------------------------[ cut here ]-----------------------------
> 
> [1] https://lore.kernel.org/linux-kernel/20220407102900.3086255-12-jakobkoschel@gmail.com/
> 
> 	Jakob

Thanks,
Jakob
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2022-04-10 10:53 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-07 10:28 [PATCH net-next 00/15] net: Remove use of list iterator after loop body Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 01/15] connector: Replace usage of found with dedicated list iterator variable Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 02/15] net: dsa: sja1105: Remove usage of iterator for list_add() after loop Jakob Koschel
2022-04-08  3:54   ` Jakub Kicinski
2022-04-08 23:58     ` Jakob Koschel
2022-04-09  0:04       ` Jakub Kicinski
2022-04-09  0:08       ` Vladimir Oltean
2022-04-08  7:47   ` Christophe Leroy
2022-04-08 23:49     ` Jakob Koschel
2022-04-08 11:41   ` Vladimir Oltean
2022-04-08 23:54     ` Jakob Koschel
2022-04-10 10:51       ` Jakob Koschel [this message]
2022-04-10 11:05         ` Vladimir Oltean
2022-04-10 12:39           ` Jakob Koschel
2022-04-10 18:24             ` Jakob Koschel
2022-04-10 20:02               ` Vladimir Oltean
2022-04-10 20:30                 ` Jakob Koschel
2022-04-10 20:34                   ` Vladimir Oltean
2022-04-07 10:28 ` [PATCH net-next 03/15] net: dsa: mv88e6xxx: Replace usage of found with dedicated iterator Jakob Koschel
2022-04-08 12:31   ` Vladimir Oltean
2022-04-08 23:44     ` Jakob Koschel
2022-04-08 23:50       ` Vladimir Oltean
2022-04-09  0:00         ` Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 04/15] net: dsa: Replace usage of found with dedicated list iterator variable Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 05/15] net: sparx5: " Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 06/15] qed: Use " Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 07/15] qed: Replace usage of found with " Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 08/15] qed: Remove usage of list iterator variable after the loop Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 09/15] net: qede: Replace usage of found with dedicated list iterator variable Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 10/15] net: qede: Remove check of list iterator against head past the loop body Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 11/15] sfc: Remove usage of list iterator for list_add() after " Jakob Koschel
2022-04-07 17:42   ` Edward Cree
2022-04-09  0:10     ` Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 12/15] net: netcp: Remove usage of list iterator for list_add() after " Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 13/15] ps3_gelic: Replace usage of found with dedicated list iterator variable Jakob Koschel
2022-04-07 10:28 ` [PATCH net-next 14/15] ipvlan: Remove usage of list iterator variable for the loop body Jakob Koschel
2022-04-07 10:29 ` [PATCH net-next 15/15] team: Remove use of list iterator variable for list_for_each_entry_from() Jakob Koschel

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=C9081CE3-B008-48DA-A97C-76F51D4F189F@gmail.com \
    --to=jakobkoschel@gmail.com \
    --cc=Steen.Hegelund@microchip.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=aelior@marvell.com \
    --cc=andrew@lunn.ch \
    --cc=arnd@arndb.de \
    --cc=benh@kernel.crashing.org \
    --cc=bjarni.jonasson@microchip.com \
    --cc=bjohannesmeyer@gmail.com \
    --cc=c.giuffrida@vu.nl \
    --cc=casper.casan@gmail.com \
    --cc=christophe.jaillet@wanadoo.fr \
    --cc=colin.king@intel.com \
    --cc=davem@davemloft.net \
    --cc=ecree.xilinx@gmail.com \
    --cc=edumazet@google.com \
    --cc=f.fainelli@gmail.com \
    --cc=h.j.bos@vu.nl \
    --cc=habetsm.xilinx@gmail.com \
    --cc=jiri@resnulli.us \
    --cc=kuba@kernel.org \
    --cc=lars.povlsen@microchip.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=manishc@marvell.com \
    --cc=michael@walle.cc \
    --cc=mpe@ellerman.id.au \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=pabeni@redhat.com \
    --cc=paulus@samba.org \
    --cc=rppt@kernel.org \
    --cc=vivien.didelot@gmail.com \
    --cc=vulab@iscas.ac.cn \
    --cc=zhudi21@huawei.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).