From: vgross Date: Mon, 19 Oct 2015 08:49:13 +0000 (+0000) Subject: deduplicate in[6]_pcbbind() port scan loop. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=c1bb031fa17ee116aad5e96aa9531998b067e691;p=openbsd deduplicate in[6]_pcbbind() port scan loop. ok mpi@ --- diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index cbdae4dcfd6..699d44ccd90 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.c,v 1.182 2015/10/18 00:04:43 deraadt Exp $ */ +/* $OpenBSD: in_pcb.c,v 1.183 2015/10/19 08:49:13 vgross Exp $ */ /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ /* @@ -360,67 +360,47 @@ in_pcbbind(struct inpcb *inp, struct mbuf *nam, struct proc *p) inp->inp_laddr = sin->sin_addr; } if (lport == 0) { - u_int16_t first, last; + u_int16_t bound_a, bound_b, first, last; int count; if (inp->inp_flags & INP_HIGHPORT) { - first = ipport_hifirstauto; /* sysctl */ - last = ipport_hilastauto; + bound_a = ipport_hifirstauto; /* sysctl */ + bound_b = ipport_hilastauto; } else if (inp->inp_flags & INP_LOWPORT) { if ((error = suser(p, 0))) return (EACCES); - first = IPPORT_RESERVED-1; /* 1023 */ - last = 600; /* not IPPORT_RESERVED/2 */ + bound_a = IPPORT_RESERVED-1; /* 1023 */ + bound_b = 600; /* not IPPORT_RESERVED/2 */ } else { - first = ipport_firstauto; /* sysctl */ - last = ipport_lastauto; + bound_a = ipport_firstauto; /* sysctl */ + bound_b = ipport_lastauto; + } + if (bound_a < bound_b) { + first = bound_a; + last = bound_b; + } else { + first = bound_b; + last = bound_a; } /* * Simple check to ensure all ports are not used up causing * a deadlock here. - * - * We split the two cases (up and down) so that the direction - * is not being tested on each round of the loop. */ - if (first > last) { - /* - * counting down - */ - count = first - last; - if (count) - lastport = first - arc4random_uniform(count); - - do { - if (count-- < 0) /* completely used? */ - return (EADDRNOTAVAIL); - --lastport; - if (lastport > first || lastport < last) - lastport = first; - lport = htons(lastport); - } while (in_baddynamic(lastport, so->so_proto->pr_protocol) || - in_pcblookup(table, &zeroin_addr, 0, - &inp->inp_laddr, lport, wild, inp->inp_rtableid)); - } else { - /* - * counting up - */ - count = last - first; - if (count) - lastport = first + arc4random_uniform(count); + count = last - first; + lastport = first + arc4random_uniform(count); - do { - if (count-- < 0) /* completely used? */ - return (EADDRNOTAVAIL); - ++lastport; - if (lastport < first || lastport > last) - lastport = first; - lport = htons(lastport); - } while (in_baddynamic(lastport, so->so_proto->pr_protocol) || - in_pcblookup(table, &zeroin_addr, 0, - &inp->inp_laddr, lport, wild, inp->inp_rtableid)); - } + do { + if (count-- < 0) /* completely used? */ + return (EADDRNOTAVAIL); + ++lastport; + if (lastport < first || lastport > last) + lastport = first; + lport = htons(lastport); + } while (in_baddynamic(lastport, so->so_proto->pr_protocol) || + in_pcblookup(table, &zeroin_addr, 0, + &inp->inp_laddr, lport, wild, inp->inp_rtableid)); } inp->inp_lport = lport; in_pcbrehash(inp); diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index e9e785035ad..ad203234c1c 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_pcb.c,v 1.78 2015/10/18 00:04:43 deraadt Exp $ */ +/* $OpenBSD: in6_pcb.c,v 1.79 2015/10/19 08:49:14 vgross Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -293,7 +293,7 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct proc *p) { struct socket *so = inp->inp_socket; struct inpcbtable *table = inp->inp_table; - u_int16_t first, last; + u_int16_t bound_a, bound_b, first, last; u_int16_t lastport = 0; u_int16_t lport = 0; int count; @@ -308,63 +308,43 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct proc *p) wild |= INPLOOKUP_WILDCARD; if (inp->inp_flags & INP_HIGHPORT) { - first = ipport_hifirstauto; /* sysctl */ - last = ipport_hilastauto; + bound_a = ipport_hifirstauto; /* sysctl */ + bound_b = ipport_hilastauto; } else if (inp->inp_flags & INP_LOWPORT) { if ((error = suser(p, 0))) return (EACCES); - first = IPPORT_RESERVED-1; /* 1023 */ - last = 600; /* not IPPORT_RESERVED/2 */ + bound_a = IPPORT_RESERVED-1; /* 1023 */ + bound_b = 600; /* not IPPORT_RESERVED/2 */ } else { - first = ipport_firstauto; /* sysctl */ - last = ipport_lastauto; + bound_a = ipport_firstauto; /* sysctl */ + bound_b = ipport_lastauto; + } + if (bound_a < bound_b) { + first = bound_a; + last = bound_b; + } else { + first = bound_b; + last = bound_a; } /* * Simple check to ensure all ports are not used up causing * a deadlock here. - * - * We split the two cases (up and down) so that the direction - * is not being tested on each round of the loop. */ - if (first > last) { - /* - * counting down - */ - count = first - last; - if (count) - lastport = first - arc4random_uniform(count); - - do { - if (count-- < 0) /* completely used? */ - return (EADDRNOTAVAIL); - --lastport; - if (lastport > first || lastport < last) - lastport = first; - lport = htons(lastport); - } while (in_baddynamic(lastport, so->so_proto->pr_protocol) || - in_pcblookup(table, &zeroin6_addr, 0, - &inp->inp_laddr6, lport, wild, inp->inp_rtableid)); - } else { - /* - * counting up - */ - count = last - first; - if (count) - lastport = first + arc4random_uniform(count); + count = last - first; + lastport = first + arc4random_uniform(count); - do { - if (count-- < 0) /* completely used? */ - return (EADDRNOTAVAIL); - ++lastport; - if (lastport < first || lastport > last) - lastport = first; - lport = htons(lastport); - } while (in_baddynamic(lastport, so->so_proto->pr_protocol) || - in_pcblookup(table, &zeroin6_addr, 0, - &inp->inp_laddr6, lport, wild, inp->inp_rtableid)); - } + do { + if (count-- < 0) /* completely used? */ + return (EADDRNOTAVAIL); + ++lastport; + if (lastport < first || lastport > last) + lastport = first; + lport = htons(lastport); + } while (in_baddynamic(lastport, so->so_proto->pr_protocol) || + in_pcblookup(table, &zeroin6_addr, 0, + &inp->inp_laddr6, lport, wild, inp->inp_rtableid)); inp->inp_lport = lport; in_pcbrehash(inp);