mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-16 21:34:10 +00:00
Fix a kernel assertion issue introduced with r286227:
Avoid too strict INP_INFO_RLOCK_ASSERT checks due to tcp_notify() being called from in6_pcbnotify(). Reported by: Larry Rosenman <ler@lerctr.org> Submitted by: markj, jch
This commit is contained in:
parent
ecab6b807c
commit
079672cb07
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=286443
|
@ -1259,7 +1259,7 @@ in_pcbfree(struct inpcb *inp)
|
||||||
|
|
||||||
#ifdef INVARIANTS
|
#ifdef INVARIANTS
|
||||||
if (pcbinfo == &V_tcbinfo) {
|
if (pcbinfo == &V_tcbinfo) {
|
||||||
INP_INFO_RLOCK_ASSERT(pcbinfo);
|
INP_INFO_LOCK_ASSERT(pcbinfo);
|
||||||
} else {
|
} else {
|
||||||
INP_INFO_WLOCK_ASSERT(pcbinfo);
|
INP_INFO_WLOCK_ASSERT(pcbinfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -491,6 +491,7 @@ short inp_so_options(const struct inpcb *inp);
|
||||||
#define INP_INFO_TRY_RLOCK(ipi) rw_try_rlock(&(ipi)->ipi_lock)
|
#define INP_INFO_TRY_RLOCK(ipi) rw_try_rlock(&(ipi)->ipi_lock)
|
||||||
#define INP_INFO_TRY_WLOCK(ipi) rw_try_wlock(&(ipi)->ipi_lock)
|
#define INP_INFO_TRY_WLOCK(ipi) rw_try_wlock(&(ipi)->ipi_lock)
|
||||||
#define INP_INFO_TRY_UPGRADE(ipi) rw_try_upgrade(&(ipi)->ipi_lock)
|
#define INP_INFO_TRY_UPGRADE(ipi) rw_try_upgrade(&(ipi)->ipi_lock)
|
||||||
|
#define INP_INFO_WLOCKED(ipi) rw_wowned(&(ipi)->ipi_lock)
|
||||||
#define INP_INFO_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_lock)
|
#define INP_INFO_RUNLOCK(ipi) rw_runlock(&(ipi)->ipi_lock)
|
||||||
#define INP_INFO_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_lock)
|
#define INP_INFO_WUNLOCK(ipi) rw_wunlock(&(ipi)->ipi_lock)
|
||||||
#define INP_INFO_LOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_LOCKED)
|
#define INP_INFO_LOCK_ASSERT(ipi) rw_assert(&(ipi)->ipi_lock, RA_LOCKED)
|
||||||
|
|
|
@ -906,7 +906,7 @@ tcp_drop(struct tcpcb *tp, int errno)
|
||||||
{
|
{
|
||||||
struct socket *so = tp->t_inpcb->inp_socket;
|
struct socket *so = tp->t_inpcb->inp_socket;
|
||||||
|
|
||||||
INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
|
INP_INFO_LOCK_ASSERT(&V_tcbinfo);
|
||||||
INP_WLOCK_ASSERT(tp->t_inpcb);
|
INP_WLOCK_ASSERT(tp->t_inpcb);
|
||||||
|
|
||||||
if (TCPS_HAVERCVDSYN(tp->t_state)) {
|
if (TCPS_HAVERCVDSYN(tp->t_state)) {
|
||||||
|
@ -1108,7 +1108,7 @@ tcp_close(struct tcpcb *tp)
|
||||||
struct inpcb *inp = tp->t_inpcb;
|
struct inpcb *inp = tp->t_inpcb;
|
||||||
struct socket *so;
|
struct socket *so;
|
||||||
|
|
||||||
INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
|
INP_INFO_LOCK_ASSERT(&V_tcbinfo);
|
||||||
INP_WLOCK_ASSERT(inp);
|
INP_WLOCK_ASSERT(inp);
|
||||||
|
|
||||||
#ifdef TCP_OFFLOAD
|
#ifdef TCP_OFFLOAD
|
||||||
|
@ -1186,7 +1186,7 @@ tcp_notify(struct inpcb *inp, int error)
|
||||||
{
|
{
|
||||||
struct tcpcb *tp;
|
struct tcpcb *tp;
|
||||||
|
|
||||||
INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
|
INP_INFO_LOCK_ASSERT(&V_tcbinfo);
|
||||||
INP_WLOCK_ASSERT(inp);
|
INP_WLOCK_ASSERT(inp);
|
||||||
|
|
||||||
if ((inp->inp_flags & INP_TIMEWAIT) ||
|
if ((inp->inp_flags & INP_TIMEWAIT) ||
|
||||||
|
|
|
@ -163,7 +163,7 @@ tcp_detach(struct socket *so, struct inpcb *inp)
|
||||||
{
|
{
|
||||||
struct tcpcb *tp;
|
struct tcpcb *tp;
|
||||||
|
|
||||||
INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
|
INP_INFO_LOCK_ASSERT(&V_tcbinfo);
|
||||||
INP_WLOCK_ASSERT(inp);
|
INP_WLOCK_ASSERT(inp);
|
||||||
|
|
||||||
KASSERT(so->so_pcb == inp, ("tcp_detach: so_pcb != inp"));
|
KASSERT(so->so_pcb == inp, ("tcp_detach: so_pcb != inp"));
|
||||||
|
@ -241,15 +241,20 @@ static void
|
||||||
tcp_usr_detach(struct socket *so)
|
tcp_usr_detach(struct socket *so)
|
||||||
{
|
{
|
||||||
struct inpcb *inp;
|
struct inpcb *inp;
|
||||||
|
int rlock = 0;
|
||||||
|
|
||||||
inp = sotoinpcb(so);
|
inp = sotoinpcb(so);
|
||||||
KASSERT(inp != NULL, ("tcp_usr_detach: inp == NULL"));
|
KASSERT(inp != NULL, ("tcp_usr_detach: inp == NULL"));
|
||||||
INP_INFO_RLOCK(&V_tcbinfo);
|
if (!INP_INFO_WLOCKED(&V_tcbinfo)) {
|
||||||
|
INP_INFO_RLOCK(&V_tcbinfo);
|
||||||
|
rlock = 1;
|
||||||
|
}
|
||||||
INP_WLOCK(inp);
|
INP_WLOCK(inp);
|
||||||
KASSERT(inp->inp_socket != NULL,
|
KASSERT(inp->inp_socket != NULL,
|
||||||
("tcp_usr_detach: inp_socket == NULL"));
|
("tcp_usr_detach: inp_socket == NULL"));
|
||||||
tcp_detach(so, inp);
|
tcp_detach(so, inp);
|
||||||
INP_INFO_RUNLOCK(&V_tcbinfo);
|
if (rlock)
|
||||||
|
INP_INFO_RUNLOCK(&V_tcbinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INET
|
#ifdef INET
|
||||||
|
|
Loading…
Reference in a new issue