From: Xiaomeng Tong <xiam0nd.tong@gmail.com>
To: david.laight@aculab.com
Cc: alsa-devel@alsa-project.org, kvm@vger.kernel.org,
gustavo@embeddedor.com, linux-iio@vger.kernel.org,
kgdb-bugreport@lists.sourceforge.net, linux@rasmusvillemoes.dk,
dri-devel@lists.freedesktop.org, c.giuffrida@vu.nl,
amd-gfx@lists.freedesktop.org, torvalds@linux-foundation.org,
samba-technical@lists.samba.org,
linux1394-devel@lists.sourceforge.net, drbd-dev@lists.linbit.com,
linux-arch@vger.kernel.org, linux-cifs@vger.kernel.org,
linux-aspeed@lists.ozlabs.org, linux-scsi@vger.kernel.org,
linux-rdma@vger.kernel.org, linux-staging@lists.linux.dev,
h.j.bos@vu.nl, jgg@ziepe.ca, intel-wired-lan@lists.osuosl.org,
nouveau@lists.freedesktop.org,
bcm-kernel-feedback-list@broadcom.com, dan.carpenter@oracle.com,
linux-media@vger.kernel.org, keescook@chromium.org,
arnd@arndb.de, linux-pm@vger.kernel.org,
intel-gfx@lists.freedesktop.org, bjohannesmeyer@gmail.com,
linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org,
christophe.jaillet@wanadoo.fr, jakobkoschel@gmail.com,
v9fs-developer@lists.sourceforge.net,
linux-tegra@vger.kernel.org, tglx@linutronix.de,
andriy.shevchenko@linux.intel.com,
linux-arm-kernel@lists.infradead.org, linux-sgx@vger.kernel.org,
nathan@kernel.org, netdev@vger.kernel.org,
linux-usb@vger.kernel.org, linux-wireless@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-f2fs-devel@lists.sourceforge.net, xiam0nd.tong@gmail.com,
tipc-discussion@lists.sourceforge.net,
linux-crypto@vger.kernel.org, dmaengine@vger.kernel.org,
linux-mediatek@lists.infradead.org, akpm@linux-foundation.org,
linuxppc-dev@lists.ozlabs.org, christian.koenig@amd.com,
rppt@kernel.org
Subject: Re: [f2fs-dev] [PATCH 2/6] treewide: remove using list iterator after loop body as a ptr
Date: Thu, 3 Mar 2022 20:37:18 +0800 [thread overview]
Message-ID: <20220303123718.12426-1-xiam0nd.tong@gmail.com> (raw)
In-Reply-To: <2d208771c50b4c6db4f43039e9d62851@AcuMS.aculab.com>
> From: Xiaomeng Tong
> > Sent: 03 March 2022 07:27
> >
> > On Thu, 3 Mar 2022 04:58:23 +0000, David Laight wrote:
> > > on 3 Mar 2022 10:27:29 +0800, Xiaomeng Tong wrote:
> > > > The problem is the mis-use of iterator outside the loop on exit, and
> > > > the iterator will be the HEAD's container_of pointer which pointers
> > > > to a type-confused struct. Sidenote: The *mis-use* here refers to
> > > > mistakely access to other members of the struct, instead of the
> > > > list_head member which acutally is the valid HEAD.
> > >
> > > The problem is that the HEAD's container_of pointer should never
> > > be calculated at all.
> > > This is what is fundamentally broken about the current definition.
> >
> > Yes, the rule is "the HEAD's container_of pointer should never be
> > calculated at all outside the loop", but how do you make sure everyone
> > follows this rule?
> > Everyone makes mistakes, but we can eliminate them all from the beginning
> > with the help of compiler which can catch such use-after-loop things.
> >
> > > > IOW, you would dereference a (NULL + offset_of_member) address here.
> > >
> > >Where?
> >
> > In the case where a developer do not follows the above rule, and mistakely
> > access a non-list-head member of the HEAD's container_of pointer outside
> > the loop. For example:
> > struct req{
> > int a;
> > struct list_head h;
> > }
> > struct req *r;
> > list_for_each_entry(r, HEAD, h) {
> > if (r->a == 0x10)
> > break;
> > }
> > // the developer made a mistake: he didn't take this situation into
> > // account where all entries in the list are *r->a != 0x10*, and now
> > // the r is the HEAD's container_of pointer.
> > r->a = 0x20;
> > Thus the "r->a = 0x20" would dereference a (NULL + offset_of_member)
> > address here.
>
> That is just a bug.
> No different to failing to check anything else might 'return'
> a NULL pointer.
Yes, but it‘s a mistake everyone has made and will make, we should avoid
this at the beginning with the help of compiler.
> Because it is a NULL dereference you find out pretty quickly.
AFAIK,NULL dereference is a undefined bahavior, can compiler quickly
catch it? Or it can only be applied to some simple/restricted cases.
> The existing loop leaves you with a valid pointer to something
> that isn't a list item.
>
> > > > Please remind me if i missed something, thanks.
> > > >
> > > > Can you share your "alternative definitions" details? thanks!
> > >
> > > The loop should probably use as extra variable that points
> > > to the 'list node' in the next structure.
> > > Something like:
> > > for (xxx *iter = head->next;
> > > iter == &head ? ((item = NULL),0) : ((item = list_item(iter),1));
> > > iter = item->member->next) {
> > > ...
> > > With a bit of casting you can use 'item' to hold 'iter'.
> >
> > you still can not make sure everyone follows this rule:
> > "do not use iterator outside the loop" without the help of compiler,
> > because item is declared outside the loop.
>
> That one has 'iter' defined in the loop.
Oh, sorry, I misunderstood. Then this is the same way with my way of
list_for_each_entry_inside(pos, type, head, member), which declare
the iterator inside the loop.
You go further and make things like "&pos->member == (head)" goes away
to avoid calculate the HEAD's container_of pointer, although the
calculation is harmless.
>
> > BTW, to avoid ambiguity,the "alternative definitions" here i asked is
> > something from you in this context:
> > "OTOH there may be alternative definitions that can be used to get
> > the compiler (or other compiler-like tools) to detect broken code.
> > Even if the definition can't possibly generate a working kerrnel."
>
> I was thinking of something like:
> if ((pos = list_first)), 1) pos = NULL else
> so that unchecked dereferences after the loop will be detectable
> as NULL pointer offsets - but that in itself isn't enough to avoid
> other warnings.
>
Do you mean put this right after the loop (I changed somthing that i
do not understand, please correct me if i am worng, thanks):
if (pos == list_first) pos = NULL; else
and compiler can detect the following NULL derefernce?
But if the NULL derefernce is just right after the loop originally,
it will be masked by the *else* keyword。
> > > > The "list_for_each_entry_inside(pos, type, head, member)" way makes
> > > > the iterator invisiable outside the loop, and would be catched by
> > > > compiler if use-after-loop things happened.
> >
> > > It is also a compete PITA for anything doing a search.
> >
> > You mean it would be a burden on search? can you show me some examples?
>
> The whole business of having to save the pointer to the located item
> before breaking the loop, remembering to have set it to NULL earlier etc.
Ok, i see. And then you need pass a "item" to the list_for_each_entry macro
as a new argument.
>
> It is so much better if you can just do:
> if (found)
> break;
>
> David
this confused me. this way is better or the "save the pointer to the located item
before breaking the loop" one?
--
Xiaomeng Tong
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
next prev parent reply other threads:[~2022-03-03 12:38 UTC|newest]
Thread overview: 83+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-28 11:08 [f2fs-dev] [PATCH 0/6] Remove usage of list iterator past the loop body Jakob Koschel
2022-02-28 11:08 ` [f2fs-dev] [PATCH 1/6] drivers: usb: remove " Jakob Koschel
2022-02-28 11:24 ` Dan Carpenter
2022-02-28 12:03 ` Jakob Koschel
2022-02-28 13:18 ` Dan Carpenter
2022-02-28 18:20 ` Joe Perches
2022-03-01 5:52 ` Dan Carpenter
2022-02-28 11:08 ` [f2fs-dev] [PATCH 2/6] treewide: remove using list iterator after loop body as a ptr Jakob Koschel
2022-02-28 11:20 ` Greg KH
2022-02-28 12:06 ` Jakob Koschel
2022-03-01 17:37 ` Greg KH
2022-02-28 12:19 ` Christian König via Linux-f2fs-devel
[not found] ` <CAHk-=wgQps58DPEOe4y5cTh5oE9EdNTWRLXzgMiETc+mFX7jzw@mail.gmail.com>
2022-02-28 20:03 ` Linus Torvalds
[not found] ` <CAHk-=wiTCvLQkHcJ3y0hpqH7FEk9D28LDvZZogC6OVLk7naBww@mail.gmail.com>
2022-02-28 20:14 ` Linus Torvalds
2022-02-28 20:53 ` Segher Boessenkool
2022-02-28 20:16 ` Matthew Wilcox
2022-02-28 20:27 ` Johannes Berg
2022-02-28 20:41 ` Linus Torvalds
2022-02-28 20:37 ` Linus Torvalds
2022-02-28 23:26 ` Matthew Wilcox
2022-03-01 0:45 ` Linus Torvalds
2022-03-01 0:57 ` Linus Torvalds
2022-03-01 18:14 ` Kees Cook
2022-03-01 18:47 ` Linus Torvalds
2022-03-01 19:01 ` Matthew Wilcox
2022-03-01 3:03 ` David Laight
2022-02-28 21:47 ` Jakob Koschel
2022-03-01 0:41 ` Linus Torvalds
2022-03-01 6:32 ` Jakub Kicinski
2022-03-01 11:28 ` Jakob Koschel
2022-03-01 17:36 ` Greg KH
2022-03-01 17:40 ` Jakob Koschel
2022-03-01 17:58 ` Greg KH
2022-03-01 18:21 ` Kees Cook
2022-03-02 9:31 ` Xiaomeng Tong
2022-03-02 14:04 ` David Laight
2022-03-03 2:27 ` Xiaomeng Tong
2022-03-03 4:58 ` David Laight
2022-03-03 7:26 ` Xiaomeng Tong
2022-03-03 9:30 ` David Laight
2022-03-03 12:37 ` Xiaomeng Tong [this message]
2022-03-03 12:18 ` [f2fs-dev] [Kgdb-bugreport] " Daniel Thompson
2022-03-04 6:59 ` [f2fs-dev] " Xiaomeng Tong
2022-03-03 7:32 ` Jakob Koschel
2022-03-03 8:30 ` Xiaomeng Tong
2022-03-03 8:38 ` Xiaomeng Tong
2022-02-28 20:07 ` Christian König via Linux-f2fs-devel
2022-02-28 20:42 ` James Bottomley
2022-02-28 20:56 ` Christian König via Linux-f2fs-devel
2022-02-28 21:13 ` James Bottomley
2022-03-01 7:03 ` Christian König via Linux-f2fs-devel
2022-02-28 22:05 ` Jakob Koschel
2022-02-28 21:18 ` Jeffrey Walton
2022-02-28 21:59 ` Mike Rapoport
2022-02-28 22:28 ` James Bottomley
2022-02-28 22:50 ` Barnabás Pőcze via Linux-f2fs-devel
2022-03-01 0:30 ` Segher Boessenkool
2022-03-01 0:54 ` Linus Torvalds
2022-03-01 19:06 ` Linus Torvalds
2022-03-01 19:42 ` Linus Torvalds
2022-03-01 22:58 ` David Laight
2022-03-01 23:03 ` Linus Torvalds
2022-03-01 23:19 ` David Laight
2022-03-01 23:55 ` Linus Torvalds
2022-03-02 9:29 ` Rasmus Villemoes
2022-03-02 20:07 ` Kees Cook
2022-03-02 20:18 ` Linus Torvalds
2022-03-02 20:59 ` Kees Cook
2022-03-03 8:37 ` Dan Carpenter
2022-03-03 10:56 ` Dan Carpenter
2022-03-01 2:15 ` David Laight
2022-02-28 13:13 ` Dan Carpenter
2022-02-28 11:08 ` [f2fs-dev] [PATCH 3/6] treewide: fix incorrect use to determine if list is empty Jakob Koschel
2022-02-28 11:38 ` Dan Carpenter
2022-02-28 11:08 ` [f2fs-dev] [PATCH 4/6] drivers: remove unnecessary use of list iterator variable Jakob Koschel
2022-02-28 11:08 ` [f2fs-dev] [PATCH 5/6] treewide: remove dereference of list iterator after loop body Jakob Koschel
2022-02-28 11:08 ` [f2fs-dev] [PATCH 6/6] treewide: remove check of list iterator against head past the " Jakob Koschel
2022-02-28 11:22 ` Dominique Martinet
2022-02-28 13:12 ` Dan Carpenter
2022-03-01 20:36 ` Linus Torvalds
2022-03-02 17:14 ` [f2fs-dev] [Intel-gfx] " Tvrtko Ursulin
2022-03-07 15:00 ` [f2fs-dev] [PATCH 0/6] Remove usage of list iterator " Dan Carpenter
2022-03-07 15:26 ` David Laight
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=20220303123718.12426-1-xiam0nd.tong@gmail.com \
--to=xiam0nd.tong@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=alsa-devel@alsa-project.org \
--cc=amd-gfx@lists.freedesktop.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=arnd@arndb.de \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=bjohannesmeyer@gmail.com \
--cc=c.giuffrida@vu.nl \
--cc=christian.koenig@amd.com \
--cc=christophe.jaillet@wanadoo.fr \
--cc=dan.carpenter@oracle.com \
--cc=david.laight@aculab.com \
--cc=dmaengine@vger.kernel.org \
--cc=drbd-dev@lists.linbit.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=gustavo@embeddedor.com \
--cc=h.j.bos@vu.nl \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-wired-lan@lists.osuosl.org \
--cc=jakobkoschel@gmail.com \
--cc=jgg@ziepe.ca \
--cc=keescook@chromium.org \
--cc=kgdb-bugreport@lists.sourceforge.net \
--cc=kvm@vger.kernel.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-aspeed@lists.ozlabs.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=linux-sgx@vger.kernel.org \
--cc=linux-staging@lists.linux.dev \
--cc=linux-tegra@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=linux1394-devel@lists.sourceforge.net \
--cc=linux@rasmusvillemoes.dk \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=nathan@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=nouveau@lists.freedesktop.org \
--cc=rppt@kernel.org \
--cc=samba-technical@lists.samba.org \
--cc=tglx@linutronix.de \
--cc=tipc-discussion@lists.sourceforge.net \
--cc=torvalds@linux-foundation.org \
--cc=v9fs-developer@lists.sourceforge.net \
/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).