diff options
author | Rick Macklem <rmacklem@FreeBSD.org> | 2016-10-01 19:39:09 +0000 |
---|---|---|
committer | Rick Macklem <rmacklem@FreeBSD.org> | 2016-10-01 19:39:09 +0000 |
commit | 00b460ffc5fde7388bd2dd349973b762bb5cf309 (patch) | |
tree | 4d4bc1e856933670ede361dcdd991514ec217fad /sys | |
parent | 8ee7716721062c936683886b21d8cbd8641c149c (diff) | |
download | src-00b460ffc5fde7388bd2dd349973b762bb5cf309.tar.gz src-00b460ffc5fde7388bd2dd349973b762bb5cf309.zip |
r297225 broke udp_output() for the case where the "addr" argument
is NULL and the function jumps to the "release:" label.
For this case, the "inp" was write locked, but the code attempted to
read unlock it. This patch fixes the problem.
This case could occur for NFS over UDP mounts, where the server was
down for a few minutes under certain circumstances.
Reported by: bde
Tested by: bde
Reviewed by: gnn
MFC after: 2 weeks
Notes
Notes:
svn path=/head/; revision=306559
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/udp_usrreq.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 04d116d82243..b7c183d2327b 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1567,12 +1567,18 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr, release: if (unlock_udbinfo == UH_WLOCKED) { + KASSERT(unlock_inp == UH_WLOCKED, + ("%s: excl udbinfo lock, shared inp lock", __func__)); INP_HASH_WUNLOCK(pcbinfo); INP_WUNLOCK(inp); } else if (unlock_udbinfo == UH_RLOCKED) { + KASSERT(unlock_inp == UH_RLOCKED, + ("%s: shared udbinfo lock, excl inp lock", __func__)); INP_HASH_RUNLOCK(pcbinfo); INP_RUNLOCK(inp); - } else + } else if (unlock_inp == UH_WLOCKED) + INP_WUNLOCK(inp); + else INP_RUNLOCK(inp); m_freem(m); return (error); |