Fix the unitialized rtableid bug discovered and fixed in the previous
authorflorian <florian@openbsd.org>
Fri, 10 Jan 2014 21:57:44 +0000 (21:57 +0000)
committerflorian <florian@openbsd.org>
Fri, 10 Jan 2014 21:57:44 +0000 (21:57 +0000)
commit by brad@ by calling setsockopt SO_RTABLE only when -V is
present. As a bonus drop privileges very early in main, before option
parsing.
This brings ping6 more in line with what ping does and will make
eventual unification easier.

OK deraadt@
"works for me" brad@

sbin/ping/ping.c
sbin/ping6/ping6.c

index 2cc843e..6170e7e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ping.c,v 1.98 2014/01/10 06:18:40 brad Exp $  */
+/*     $OpenBSD: ping.c,v 1.99 2014/01/10 21:57:44 florian Exp $       */
 /*     $NetBSD: ping.c,v 1.20 1995/08/11 22:37:58 cgd Exp $    */
 
 /*
@@ -190,7 +190,7 @@ main(int argc, char *argv[])
        fd_set *fdmaskp;
        size_t fdmasks;
        uid_t uid;
-       int rtableid = -1;
+       u_int rtableid;
 
        if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
                err(1, "socket");
index 2ac9440..a0cb298 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ping6.c,v 1.87 2014/01/10 06:18:40 brad Exp $ */
+/*     $OpenBSD: ping6.c,v 1.88 2014/01/10 21:57:44 florian Exp $      */
 /*     $KAME: ping6.c,v 1.163 2002/10/25 02:19:06 itojun Exp $ */
 
 /*
@@ -271,7 +271,15 @@ main(int argc, char *argv[])
        size_t rthlen;
        int mflag = 0;
        uid_t uid;
-       int rtableid = -1;
+       u_int rtableid;
+
+       if ((s = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0)
+               err(1, "socket");
+
+       /* revoke root privilege */
+       uid = getuid();
+       if (setresuid(uid, uid, uid) == -1)
+               err(1, "setresuid");
 
        /* just to be sure */
        memset(&smsghdr, 0, sizeof(smsghdr));
@@ -479,6 +487,9 @@ main(int argc, char *argv[])
                        if (errstr)
                                errx(1, "rtable value is %s: %s",
                                    errstr, optarg);
+                       if (setsockopt(s, SOL_SOCKET, SO_RTABLE, &rtableid,
+                           sizeof(rtableid)) == -1)
+                               err(1, "setsockopt SO_RTABLE");
                        break;
                case 'w':
                        options &= ~F_NOUSERDATA;
@@ -540,14 +551,6 @@ main(int argc, char *argv[])
 
        memcpy(&dst, res->ai_addr, res->ai_addrlen);
 
-       if ((s = socket(res->ai_family, res->ai_socktype,
-           res->ai_protocol)) < 0)
-               err(1, "socket");
-
-       if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE, &rtableid,
-           sizeof(rtableid)) == -1))
-               err(1, "setsockopt SO_RTABLE");
-
        /* set the source address if specified. */
        if ((options & F_SRCADDR) &&
            bind(s, (struct sockaddr *)&src, srclen) != 0) {
@@ -595,11 +598,6 @@ main(int argc, char *argv[])
                        err(1, "setsockopt(IPV6_RECVDSTOPTS)");
        }
 
-       /* revoke root privilege */
-       uid = getuid();
-       if (setresuid(uid, uid, uid) == -1)
-               err(1, "setresuid");
-
        if ((options & F_FLOOD) && (options & F_INTERVAL))
                errx(1, "-f and -i incompatible options");