summaryrefslogtreecommitdiffstats
path: root/sys/netinet/udp_usrreq.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2008-07-10 16:20:18 +0000
committerrwatson <rwatson@FreeBSD.org>2008-07-10 16:20:18 +0000
commitede873c50ba96701f482c7144c6bd568822aea9b (patch)
treec6f313331f44bb09c1f77029ff18d7d913c1aba8 /sys/netinet/udp_usrreq.c
parentd627b957354cb417c7c3791cadf8a97f87f5edde (diff)
downloadFreeBSD-src-ede873c50ba96701f482c7144c6bd568822aea9b.zip
FreeBSD-src-ede873c50ba96701f482c7144c6bd568822aea9b.tar.gz
Slightly rearrange validation of UDP arguments and jail processing in
udp_output() so that argument validation occurs before jail processing. Add additional comments explaining what's going on when we process addresses and binding during udp_output(). MFC after: 3 weeks
Diffstat (limited to 'sys/netinet/udp_usrreq.c')
-rw-r--r--sys/netinet/udp_usrreq.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 8843d0d..1cce109 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
* The Regents of the University of California.
+ * Copyright (c) 2008 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -875,17 +876,37 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
goto release;
}
+ /*
+ * If a UDP socket has been connected, then a local address/port will
+ * have been selected and bound.
+ *
+ * If a UDP socket has not been connect to, then an explicit
+ * destination address must be used, in which case a local
+ * address/port may not have been selected and bound.
+ */
if (addr) {
INP_INFO_LOCK_ASSERT(&udbinfo);
INP_LOCK_ASSERT(inp);
- sin = (struct sockaddr_in *)addr;
- if (jailed(td->td_ucred))
- prison_remote_ip(td->td_ucred, 0,
- &sin->sin_addr.s_addr);
if (inp->inp_faddr.s_addr != INADDR_ANY) {
error = EISCONN;
goto release;
}
+
+ /*
+ * Jail may rewrite the destination address, so let it do
+ * that before we use it.
+ */
+ sin = (struct sockaddr_in *)addr;
+ if (jailed(td->td_ucred))
+ prison_remote_ip(td->td_ucred, 0,
+ &sin->sin_addr.s_addr);
+
+ /*
+ * If a local address or port hasn't yet been selected, do
+ * that now. Once a port is selected, we commit the binding
+ * back to the socket; we also commit the binding of the
+ * address if in jail.
+ */
error = in_pcbconnect_setup(inp, addr, &laddr.s_addr, &lport,
&faddr.s_addr, &fport, NULL, td->td_ucred);
if (error)
OpenPOWER on IntegriCloud