Re: [PATCH 2/6] treewide: remove using list iterator after loop body as a ptr
| From: | Linus Torvalds <torvalds-AT-linux-foundation.org> | |
| To: | Christian König <christian.koenig-AT-amd.com> | |
| Subject: | Re: [PATCH 2/6] treewide: remove using list iterator after loop body as a ptr | |
| Date: | Mon, 28 Feb 2022 11:56:07 -0800 | |
| Message-ID: | <CAHk-=wgQps58DPEOe4y5cTh5oE9EdNTWRLXzgMiETc+mFX7jzw@mail.gmail.com> | |
| Cc: | Jakob Koschel <jakobkoschel-AT-gmail.com>, alsa-devel-AT-alsa-project.org, linux-aspeed-AT-lists.ozlabs.org, "Gustavo A. R. Silva" <gustavo-AT-embeddedor.com>, linux-iio-AT-vger.kernel.org, nouveau-AT-lists.freedesktop.org, Rasmus Villemoes <linux-AT-rasmusvillemoes.dk>, dri-devel <dri-devel-AT-lists.freedesktop.org>, Cristiano Giuffrida <c.giuffrida-AT-vu.nl>, amd-gfx list <amd-gfx-AT-lists.freedesktop.org>, samba-technical-AT-lists.samba.org, linux1394-devel-AT-lists.sourceforge.net, drbd-dev-AT-lists.linbit.com, linux-arch <linux-arch-AT-vger.kernel.org>, CIFS <linux-cifs-AT-vger.kernel.org>, KVM list <kvm-AT-vger.kernel.org>, linux-scsi <linux-scsi-AT-vger.kernel.org>, linux-rdma <linux-rdma-AT-vger.kernel.org>, linux-staging-AT-lists.linux.dev, "Bos, H.J." <h.j.bos-AT-vu.nl>, Jason Gunthorpe <jgg-AT-ziepe.ca>, intel-wired-lan-AT-lists.osuosl.org, kgdb-bugreport-AT-lists.sourceforge.net, bcm-kernel-feedback-list-AT-broadcom.com, Dan Carpenter <dan.carpenter-AT-oracle.com>, Linux Media Mailing List <linux-media-AT-vger.kernel.org>, Kees Cook <keescook-AT-chromium.org>, Arnd Bergman <arnd-AT-arndb.de>, Linux PM <linux-pm-AT-vger.kernel.org>, intel-gfx <intel-gfx-AT-lists.freedesktop.org>, Brian Johannesmeyer <bjohannesmeyer-AT-gmail.com>, Nathan Chancellor <nathan-AT-kernel.org>, linux-fsdevel <linux-fsdevel-AT-vger.kernel.org>, Christophe JAILLET <christophe.jaillet-AT-wanadoo.fr>, v9fs-developer-AT-lists.sourceforge.net, linux-tegra <linux-tegra-AT-vger.kernel.org>, Thomas Gleixner <tglx-AT-linutronix.de>, Andy Shevchenko <andriy.shevchenko-AT-linux.intel.com>, Linux ARM <linux-arm-kernel-AT-lists.infradead.org>, linux-sgx-AT-vger.kernel.org, linux-block <linux-block-AT-vger.kernel.org>, Netdev <netdev-AT-vger.kernel.org>, linux-usb-AT-vger.kernel.org, linux-wireless <linux-wireless-AT-vger.kernel.org>, Linux Kernel Mailing List <linux-kernel-AT-vger.kernel.org>, Linux F2FS Dev Mailing List <linux-f2fs-devel-AT-lists.sourceforge.net>, tipc-discussion-AT-lists.sourceforge.net, Linux Crypto Mailing List <linux-crypto-AT-vger.kernel.org>, dma <dmaengine-AT-vger.kernel.org>, linux-mediatek-AT-lists.infradead.org, Andrew Morton <akpm-AT-linux-foundation.org>, linuxppc-dev <linuxppc-dev-AT-lists.ozlabs.org>, Mike Rapoport <rppt-AT-kernel.org> | |
| Archive-link: | Article |
On Mon, Feb 28, 2022 at 4:19 AM Christian König
<christian.koenig@amd.com> wrote:
>
> I don't think that using the extra variable makes the code in any way
> more reliable or easier to read.
So I think the next step is to do the attached patch (which requires
that "-std=gnu11" that was discussed in the original thread).
That will guarantee that the 'pos' parameter of list_for_each_entry()
is only updated INSIDE the for_each_list_entry() loop, and can never
point to the (wrongly typed) head entry.
And I would actually hope that it should actually cause compiler
warnings about possibly uninitialized variables if people then use the
'pos' pointer outside the loop. Except
(a) that code in sgx/encl.c currently initializes 'tmp' to NULL for
inexplicable reasons - possibly because it already expected this
behavior
(b) when I remove that NULL initializer, I still don't get a warning,
because we've disabled -Wno-maybe-uninitialized since it results in so
many false positives.
Oh well.
Anyway, give this patch a look, and at least if it's expanded to do
"(pos) = NULL" in the entry statement for the for-loop, it will avoid
the HEAD type confusion that Jakob is working on. And I think in a
cleaner way than the horrid games he plays.
(But it won't avoid possible CPU speculation of such type confusion.
That, in my opinion, is a completely different issue)
I do wish we could actually poison the 'pos' value after the loop
somehow - but clearly the "might be uninitialized" I was hoping for
isn't the way to do it.
Anybody have any ideas?
Linus
diff --git a/include/linux/list.h b/include/linux/list.h
index dd6c2041d09c..bab995596aaa 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -634,10 +634,10 @@ static inline void list_splice_tail_init(struct list_head *list,
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
-#define list_for_each_entry(pos, head, member) \
- for (pos = list_first_entry(head, typeof(*pos), member); \
- !list_entry_is_head(pos, head, member); \
- pos = list_next_entry(pos, member))
+#define list_for_each_entry(pos, head, member) \
+ for (typeof(pos) __iter = list_first_entry(head, typeof(*pos), member); \
+ !list_entry_is_head(__iter, head, member) && (((pos)=__iter),1); \
+ __iter = list_next_entry(__iter, member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
