On 03/31/16 14:07, Alexander Bluhm wrote:
> On Wed, Mar 30, 2016 at 10:44:14PM +0200, Vincent Gross wrote:
>> This diff moves the "are we binding to a privileged port while not being 
>> root ?"
>> check from in(6)_pcbaddrisavail() to in_pcbbind().
> 
>> --- sys/netinet/in_pcb.c     26 Mar 2016 21:56:04 -0000      1.198
>> +++ sys/netinet/in_pcb.c     30 Mar 2016 20:33:00 -0000
>> @@ -341,9 +341,14 @@ in_pcbbind(struct inpcb *inp, struct mbu
>>              }
>>      }
>>  
>> -    if (lport == 0)
>> +    if (lport == 0) {
>>              if ((error = in_pcbpickport(&lport, wild, inp, p)))
>>                      return (error);
>> +    } else {
>> +            if (ntohs(lport) < IPPORT_RESERVED &&
>> +                (error = suser(p, 0)))
>> +                    return (EACCES);
>> +    }
>>      inp->inp_lport = lport;
> 
> At this point inp has already been modified.  So when we bail out
> with EACCES here, we have a partially successful system call.
> 
> Move the assignments
>                         inp->inp_laddr6 = sin6->sin6_addr;
>                         inp->inp_laddr = sin->sin_addr;
> down after the return (EACCES).
> 
> Looks like that return (error) was wrong before.

diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 1ff0056..63b3357 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -343,9 +343,22 @@ in_pcbbind(struct inpcb *inp, struct mbuf *nam, struct 
proc *p)
                }
        }
 
-       if (lport == 0)
+       if (lport == 0) {
                if ((error = in_pcbpickport(&lport, laddr, wild, inp, p)))
                        return (error);
+       } else {
+               /*
+                * Question:  Do we wish to continue the Berkeley
+                * tradition of ports < IPPORT_RESERVED be only for
+                * root?
+                * Answer: For now yes, but IMHO, it should be REMOVED!
+                * OUCH: One other thing, is there no better way of
+                * finding a process for a socket instead of using
+                * curproc?  (Marked with BSD's {in,}famous XXX ?
+                */
+               if (ntohs(lport) < IPPORT_RESERVED && (error = suser(p, 0)))
+                       return (EACCES);
+       }
        if (nam) {
                switch (sotopf(so)) {
 #ifdef INET6
@@ -371,7 +384,6 @@ in_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in 
*sin, int wild,
        struct inpcbtable *table = inp->inp_table;
        u_int16_t lport = sin->sin_port;
        int reuseport = (so->so_options & SO_REUSEPORT);
-       int error;
 
        if (IN_MULTICAST(sin->sin_addr.s_addr)) {
                /*
@@ -411,10 +423,6 @@ in_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in 
*sin, int wild,
        if (lport) {
                struct inpcb *t;
 
-               /* GROSS */
-               if (ntohs(lport) < IPPORT_RESERVED &&
-                   (error = suser(p, 0)))
-                       return (EACCES);
                if (so->so_euid) {
                        t = in_pcblookup(table, &zeroin_addr, 0,
                            &sin->sin_addr, lport, INPLOOKUP_WILDCARD,
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 4fde210..c11b936 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -158,7 +158,6 @@ in6_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in6 
*sin6, int wild,
        struct inpcbtable *table = inp->inp_table;
        u_short lport = sin6->sin6_port;
        int reuseport = (so->so_options & SO_REUSEPORT);
-       int error;
 
        wild |= INPLOOKUP_IPV6;
        /* KAME hack: embed scopeid */
@@ -217,17 +216,6 @@ in6_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in6 
*sin6, int wild,
        if (lport) {
                struct inpcb *t;
 
-               /*
-                * Question:  Do we wish to continue the Berkeley
-                * tradition of ports < IPPORT_RESERVED be only for
-                * root?
-                * Answer: For now yes, but IMHO, it should be REMOVED!
-                * OUCH: One other thing, is there no better way of
-                * finding a process for a socket instead of using
-                * curproc?  (Marked with BSD's {in,}famous XXX ?
-                */
-               if (ntohs(lport) < IPPORT_RESERVED && (error = suser(p, 0)))
-                       return error;
                if (so->so_euid) {
                        t = in_pcblookup(table,
                            (struct in_addr *)&zeroin6_addr, 0,

Reply via email to