From ede873c50ba96701f482c7144c6bd568822aea9b Mon Sep 17 00:00:00 2001 From: rwatson Date: Thu, 10 Jul 2008 16:20:18 +0000 Subject: 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 --- sys/netinet/udp_usrreq.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'sys/netinet/udp_usrreq.c') 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) -- cgit v1.1