From 71a1539e378310120fede100b867ffa995fd9a7a Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Thu, 16 Dec 2021 15:11:42 +0100 Subject: [PATCH] inet6: fix a LOR between rip and rawinp Running sys/netpfil/pf/fragmentation v6 results in: lock order reversal: 1st 0xfffffe00050429a8 rip (rip, sleep mutex) @ /usr/src/sys/netinet6/raw_ip6.c:803 2nd 0xfffff8009491e1d0 rawinp (rawinp, rw) @ /usr/src/sys/netinet6/raw_ip6.c:804 lock order rawinp -> rip established at: 0xffffffff8068e26a at witness_lock_order_add+0x28a 0xffffffff8068d087 at witness_checkorder+0x627 0xffffffff805a9f05 at __mtx_lock_flags+0x205 0xffffffff808102e4 at in_pcballoc+0x204 0xffffffff808d53c6 at rip6_attach+0x116 0xffffffff806dc4e8 at socreate+0x368 0xffffffff806eaedc at kern_socket+0xfc 0xffffffff806eadcd at sys_socket+0x2d 0xffffffff80abc774 at syscallenter+0x5c4 0xffffffff80abbeeb at amd64_syscall+0x1b 0xffffffff80a8044b at fast_syscall_common+0xf8 lock order rip -> rawinp attempted at: 0xffffffff8068dc2a at witness_checkorder+0x11ca 0xffffffff805d1b7f at _rw_wlock_cookie+0x18f 0xffffffff808d596c at rip6_connect+0x19c 0xffffffff806e0842 at soconnectat+0x142 0xffffffff806ebe36 at kern_connectat+0x136 0xffffffff806ebcdf at sys_connect+0x4f 0xffffffff80abc774 at syscallenter+0x5c4 0xffffffff80abbeeb at amd64_syscall+0x1b 0xffffffff80a8044b at fast_syscall_common+0xf8 Reviewed by: glebius Fixes: de2d47842e880281 ("SMR protection for inpcbs") Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D33508 --- sys/netinet6/raw_ip6.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 5b179015100..cb54d1268ce 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -800,24 +800,24 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td) if ((error = sa6_embedscope(addr, V_ip6_use_defzone)) != 0) return (error); - INP_INFO_WLOCK(&V_ripcbinfo); INP_WLOCK(inp); + INP_INFO_WLOCK(&V_ripcbinfo); /* Source address selection. XXX: need pcblookup? */ NET_EPOCH_ENTER(et); error = in6_selectsrc_socket(addr, inp->in6p_outputopts, inp, so->so_cred, scope_ambiguous, &in6a, NULL); NET_EPOCH_EXIT(et); if (error) { - INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&V_ripcbinfo); + INP_WUNLOCK(inp); return (error); } inp->in6p_faddr = addr->sin6_addr; inp->in6p_laddr = in6a; soisconnected(so); - INP_WUNLOCK(inp); INP_INFO_WUNLOCK(&V_ripcbinfo); + INP_WUNLOCK(inp); return (0); }