deduplicate in[6]_pcbbind() port scan loop.
authorvgross <vgross@openbsd.org>
Mon, 19 Oct 2015 08:49:13 +0000 (08:49 +0000)
committervgross <vgross@openbsd.org>
Mon, 19 Oct 2015 08:49:13 +0000 (08:49 +0000)
ok mpi@

sys/netinet/in_pcb.c
sys/netinet6/in6_pcb.c

index cbdae4d..699d44c 100644 (file)
@@ -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);
index e9e7850..ad20323 100644 (file)
@@ -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);