Date: Mon, 10 Sep 2018 17:00:33 -0400 From: Ryan Stone <rysto32@gmail.com> To: freebsd-net <freebsd-net@freebsd.org> Subject: udp_notify() invalidates the routing cache without a write lock Message-ID: <CAFMmRNzS0xFJg04-urmUdk=UWGSxMHcowfYow9fasQhaTj8ojA@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
Recently at work I had a system crash while executing RTFREE() in udp_notify(). In looking at the system I discovered that two threads had called udp_notify() on the same pcb. This was possible because the threads only held a read lock on the socket. The obvious solution is to hold a write lock in this path. I haven't even compile-tested the patch below yet, but would anybody have any objections to this approach? diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index cae044c066c3..429f195ee954 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -756,13 +756,7 @@ struct inpcb * udp_notify(struct inpcb *inp, int errno) { - /* - * While udp_ctlinput() always calls udp_notify() with a read lock - * when invoking it directly, in_pcbnotifyall() currently uses write - * locks due to sharing code with TCP. For now, accept either a read - * or a write lock, but a read lock is sufficient. - */ - INP_LOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if ((errno == EHOSTUNREACH || errno == ENETUNREACH || errno == EHOSTDOWN) && inp->inp_route.ro_rt) { RTFREE(inp->inp_route.ro_rt); @@ -808,13 +802,13 @@ udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip, if (ip != NULL) { uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2)); inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport, - ip->ip_src, uh->uh_sport, INPLOOKUP_RLOCKPCB, NULL); + ip->ip_src, uh->uh_sport, INPLOOKUP_WLOCKPCB, NULL); if (inp != NULL) { - INP_RLOCK_ASSERT(inp); + INP_WLOCK_ASSERT(inp); if (inp->inp_socket != NULL) { udp_notify(inp, inetctlerrmap[cmd]); } - INP_RUNLOCK(inp); + INP_WUNLOCK(inp); } else { inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport, ip->ip_src, uh->uh_sport,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAFMmRNzS0xFJg04-urmUdk=UWGSxMHcowfYow9fasQhaTj8ojA>