summaryrefslogtreecommitdiffstats
path: root/usr.sbin/traceroute
diff options
context:
space:
mode:
authorflorian <florian@openbsd.org>2014-06-05 14:49:11 +0000
committerflorian <florian@openbsd.org>2014-06-05 14:49:11 +0000
commit9118b01e33117b9c3c6babaa60a56398de91f5ac (patch)
treedec535c5a5c7a2d3e7dd3990395a06eb54d5e2e1 /usr.sbin/traceroute
parentMore KNF. (diff)
downloadwireguard-openbsd-9118b01e33117b9c3c6babaa60a56398de91f5ac.tar.xz
wireguard-openbsd-9118b01e33117b9c3c6babaa60a56398de91f5ac.zip
Reduce code running as root by trying to create all needed sockets
first, remember which failed, drop privs and then decide which sockets are needed and close the others. Only error out if the creation of a needed socket failed. That is it is non-fatal if tracerouting an INET4 address and the INET6 socket creations failed. prodding deraadt@; OK benno@
Diffstat (limited to 'usr.sbin/traceroute')
-rw-r--r--usr.sbin/traceroute/traceroute.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/usr.sbin/traceroute/traceroute.c b/usr.sbin/traceroute/traceroute.c
index c7600d675a0..f06b9eaf792 100644
--- a/usr.sbin/traceroute/traceroute.c
+++ b/usr.sbin/traceroute/traceroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: traceroute.c,v 1.131 2014/06/04 12:28:39 florian Exp $ */
+/* $OpenBSD: traceroute.c,v 1.132 2014/06/05 14:49:11 florian Exp $ */
/* $NetBSD: traceroute.c,v 1.10 1995/05/21 15:50:45 mycroft Exp $ */
/*
@@ -357,7 +357,8 @@ main(int argc, char *argv[])
int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
int ttl_flag = 0, incflag = 1, protoset = 0, sump = 0;
int ch, i, lsrr = 0, on = 1, probe, seq = 0, tos = 0, error, packetlen;
- int rcvcmsglen;
+ int rcvcmsglen, rcvsock4, rcvsock6, sndsock4, sndsock6;
+ int v4sock_errno, v6sock_errno;
struct addrinfo hints, *res;
size_t size;
static u_char *rcvcmsgbuf;
@@ -375,24 +376,47 @@ main(int argc, char *argv[])
u_int rtableid;
socklen_t len;
- if (strcmp("traceroute6", __progname) == 0) {
- v6flag = 1;
- if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0)
- err(5, "socket(ICMPv6)");
- if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
- err(5, "socket(SOCK_DGRAM)");
- } else {
- if ((rcvsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
- err(5, "icmp socket");
- if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
- err(5, "raw socket");
- }
+ rcvsock4 = rcvsock6 = sndsock4 = sndsock6 = -1;
+ v4sock_errno = v6sock_errno = 0;
+
+ if ((rcvsock6 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0)
+ v6sock_errno = errno;
+ else if ((sndsock6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
+ v6sock_errno = errno;
+
+ if ((rcvsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
+ v4sock_errno = errno;
+ else if ((sndsock4 = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
+ v4sock_errno = errno;
/* revoke privs */
uid = getuid();
if (setresuid(uid, uid, uid) == -1)
err(1, "setresuid");
+ if (strcmp("traceroute6", __progname) == 0) {
+ v6flag = 1;
+ if (v6sock_errno != 0)
+ errc(5, v6sock_errno, rcvsock6 < 0 ? "socket(ICMPv6)" :
+ "socket(SOCK_DGRAM)");
+ rcvsock = rcvsock6;
+ sndsock = sndsock6;
+ if (rcvsock4 >= 0)
+ close(rcvsock4);
+ if (sndsock4 >= 0)
+ close(sndsock4);
+ } else {
+ if (v4sock_errno != 0)
+ errc(5, v4sock_errno, rcvsock4 < 0 ? "icmp socket" :
+ "raw socket");
+ rcvsock = rcvsock4;
+ sndsock = sndsock4;
+ if (rcvsock6 >= 0)
+ close(rcvsock6);
+ if (sndsock6 >= 0)
+ close(sndsock6);
+ }
+
if (v6flag) {
mib[1] = PF_INET6;
mib[2] = IPPROTO_IPV6;