Re: git: 71a1539e3783 - main - inet6: fix a LOR between rip and rawinp
- In reply to: Mateusz Guzik : "git: 71a1539e3783 - main - inet6: fix a LOR between rip and rawinp"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 19 Dec 2021 16:10:54 UTC
On Sun, Dec 19, 2021 at 02:43:09PM +0000, Mateusz Guzik wrote:
M> commit 71a1539e378310120fede100b867ffa995fd9a7a
M> Author: Mateusz Guzik <mjg@FreeBSD.org>
M> AuthorDate: 2021-12-16 14:11:42 +0000
M> Commit: Mateusz Guzik <mjg@FreeBSD.org>
M> CommitDate: 2021-12-19 14:43:04 +0000
M>
M> inet6: fix a LOR between rip and rawinp
M>
M> Running sys/netpfil/pf/fragmentation v6 results in:
M>
M> lock order reversal:
M> 1st 0xfffffe00050429a8 rip (rip, sleep mutex) @ /usr/src/sys/netinet6/raw_ip6.c:803
M> 2nd 0xfffff8009491e1d0 rawinp (rawinp, rw) @ /usr/src/sys/netinet6/raw_ip6.c:804
...
M> --- a/sys/netinet6/raw_ip6.c
M> +++ b/sys/netinet6/raw_ip6.c
M> @@ -800,24 +800,24 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
M> if ((error = sa6_embedscope(addr, V_ip6_use_defzone)) != 0)
M> return (error);
M>
M> - INP_INFO_WLOCK(&V_ripcbinfo);
M> INP_WLOCK(inp);
M> + INP_INFO_WLOCK(&V_ripcbinfo);
M> /* Source address selection. XXX: need pcblookup? */
M> NET_EPOCH_ENTER(et);
M> error = in6_selectsrc_socket(addr, inp->in6p_outputopts,
M> inp, so->so_cred, scope_ambiguous, &in6a, NULL);
M> NET_EPOCH_EXIT(et);
M> if (error) {
M> - INP_WUNLOCK(inp);
M> INP_INFO_WUNLOCK(&V_ripcbinfo);
M> + INP_WUNLOCK(inp);
M> return (error);
M> }
M>
M> inp->in6p_faddr = addr->sin6_addr;
M> inp->in6p_laddr = in6a;
M> soisconnected(so);
M> - INP_WUNLOCK(inp);
M> INP_INFO_WUNLOCK(&V_ripcbinfo);
M> + INP_WUNLOCK(inp);
M> return (0);
I actually see no reason for INP_INFO_WLOCK() in this function. That's why it
was missed by my commit. I'm 99% sure that epoch protection is enough for
in6_selectsrc_socket(). But I will leave that to IPv6 experts.
--
Gleb Smirnoff