As a follow-on to r183323, correct another case where ip_output() was
called without an inpcb pointer despite holding the tcbinfo global lock, which lead to a deadlock or panic when ipfw tried to further acquire it recursively. Reported by: Stefan Ehmann <shoesoft at gmx dot net> MFC after: 3 days
This commit is contained in:
parent
4ea219803e
commit
014ea782b1
@ -885,13 +885,29 @@ tcp_input(struct mbuf *m, int off0)
|
||||
|
||||
dropwithreset:
|
||||
INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
|
||||
tcp_dropwithreset(m, th, tp, tlen, rstreason);
|
||||
|
||||
/*
|
||||
* If inp is non-NULL, we call tcp_dropwithreset() holding both inpcb
|
||||
* and global locks. However, if NULL, we must hold neither as
|
||||
* firewalls may acquire the global lock in order to look for a
|
||||
* matching inpcb.
|
||||
*/
|
||||
if (inp != NULL) {
|
||||
tcp_dropwithreset(m, th, tp, tlen, rstreason);
|
||||
INP_WUNLOCK(inp);
|
||||
}
|
||||
INP_INFO_WUNLOCK(&V_tcbinfo);
|
||||
if (inp == NULL)
|
||||
tcp_dropwithreset(m, th, NULL, tlen, rstreason);
|
||||
m = NULL; /* mbuf chain got consumed. */
|
||||
goto drop;
|
||||
|
||||
dropunlock:
|
||||
INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
|
||||
if (inp != NULL)
|
||||
INP_WUNLOCK(inp);
|
||||
INP_INFO_WUNLOCK(&V_tcbinfo);
|
||||
|
||||
drop:
|
||||
INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
|
||||
if (s != NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user