aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2016-10-01 19:39:09 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2016-10-01 19:39:09 +0000
commit00b460ffc5fde7388bd2dd349973b762bb5cf309 (patch)
tree4d4bc1e856933670ede361dcdd991514ec217fad /sys
parent8ee7716721062c936683886b21d8cbd8641c149c (diff)
downloadsrc-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.c8
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);