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.

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.
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.

Please let me know if you see any fault in above reasoning or if
something is still no clear.

Andriy Gapon
freebsd-current@freebsd.org mailing list
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to