Date: Thu, 27 Aug 2015 11:06:49 +0300 From: Konstantin Belousov <kostikbel@gmail.com> To: Andriy Gapon <avg@FreeBSD.org> Cc: John-Mark Gurney <jmg@funkthat.com>, FreeBSD Current <freebsd-current@FreeBSD.org>, Lawrence Stewart <lstewart@room52.net>, Pawel Pekala <pawel@FreeBSD.org>, "K. Macy" <kmacy@FreeBSD.org> Subject: Re: Instant panic while trying run ports-mgmt/poudriere Message-ID: <20150827080649.GG2072@kib.kiev.ua> In-Reply-To: <55DEBA8B.5060009@FreeBSD.org> References: <20150714223829.GY8523@funkthat.com> <20150715174616.652d0aea@FreeBSD.org> <20150715180526.GM8523@funkthat.com> <20150715223703.78b9197c@FreeBSD.org> <CAHM0Q_PLRP4t6JgkstXHNOVV%2B2DyathOgi8bg4-RQkW-BcGXow@mail.gmail.com> <20150806233328.47a02594@FreeBSD.org> <55CB5428.2090505@room52.net> <55D96E24.9060106@FreeBSD.org> <20150826233616.GU33167@funkthat.com> <55DEBA8B.5060009@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Aug 27, 2015 at 10:21:47AM +0300, Andriy Gapon wrote: > On 27/08/2015 02:36, John-Mark Gurney wrote: > > We should/cannot get here w/ an empty list. If we do, then there is > > something seriously wrong... The current kn (which we must have as we > > are here) MUST be on the list, but as you just showed, there are no > > knotes on the list. > > > > Can you get me a print of the knote? That way I can see what flags > > are on it? > > Apologies if the following might sound a little bit patronizing, but it > seems that you have got all the facts correctly, but somehow the > connection between them did not become clear. > > So: > 1. The list originally is NOT empty. I guess that it has one entry, but > that's an unimportant detail. > 2. This is why the loop is entered. It's a fact that it is entered. > 3. The list becomes empty precisely because the entry is removed during > the iteration in the loop (as kib has explained). It's a fact that the > list became empty at least in the panic that I reported. The only detail I can add to this explanation, which is probably third (?) time, is that the removal is done in the filt_proc() event method, by the call to knlist_remove_inevent(). > 4. The element is not only unlinked from the list, but its memory is > also freed. > 5. That's why we have the use after free: SLIST_FOREACH is trying to get > a pointer to a next element from the freed memory. > 6. This is why the commit for trashing the freed memory made all the > difference: previously the freed memory was unlikely to be re-used / > modified, so the use-after-free had a high chance of succeeding. It's a > fact that in my panic there was an attempt to dereference a trashed pointer. > 7. Finally, this is why SLIST_FOREACH_SAFE helps here: we stash the > pointer to the next element beforehand and, thus, we do not access the > freed memory. The additional, eighth item, should explain why the change to _SAFE() is the correct fix, and not just a papering over the problem. Nobody except the current thread can modify the knlist, because knlist is locked. As a consequence, only the current element can be unlinked and removed. So the _SAFE() iterator actually work. > > Please let me know if you see any fault in above reasoning or if > something is still no clear.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150827080649.GG2072>