There seems to be a correctness issue in pr_inputs defined for various extension header processing routines for IPv6.
The routines call IP6_EXTHDR_* macros which may end up releasing the mbuf passed to the routine.
Even though the functions are passed pointer to the pointer to mbuf, the pointer is not updated before returning from the routine even for the cases that may not return IPPROTO_DONE.
Change would be to simply update the mbuf pointer along with updating the offset.
Please refer to implementation of route6_input/dest6_input
I think I have fixed this in a local tree as part of removing most of the PULLDOWN_TEST and IP6_EXTHDR* foo.
I'll hopefully upload a clean patch for review later today and will point you at it. It's really helpful to have another pair of eyes on these things.
A commit references this bug:
Date: Tue Nov 12 15:46:30 UTC 2019
New revision: 354643
netinet*: update *mp to pass the proper value back
In ip6_[direct_]input() we are looping over the extension headers
to deal with the next header. We pass a pointer to an mbuf pointer
to the handling functions. In certain cases the mbuf can be updated
there and we need to pass the new one back. That missing in
dest6_input() and route6_input(). In tcp6_input() we should also
update it before we call tcp_input().
In addition to that mark the mbuf NULL all the times when we return
that we are done with handling the packet and no next header should
be checked (IPPROTO_DONE). This will eventually allow us to assert
proper behaviour and catch the above kind of errors more easily,
expecting *mp to always be set.
This change is extracted from a larger patch and not an exhaustive
change across the entire stack yet.
Reported by: prabhakar.lakhera gmail.com
MFC after: 3 weeks
Sponsored by: Netflix