diff options
author | florian <florian@openbsd.org> | 2016-09-28 06:39:12 +0000 |
---|---|---|
committer | florian <florian@openbsd.org> | 2016-09-28 06:39:12 +0000 |
commit | 8db0c4f0e5ba4e178fac856a786d5d41536f8f71 (patch) | |
tree | e4deb97b22efcc9d3362dbd33a58920167e64e81 | |
parent | Move bug description to the BUGS section (diff) | |
download | wireguard-openbsd-8db0c4f0e5ba4e178fac856a786d5d41536f8f71.tar.xz wireguard-openbsd-8db0c4f0e5ba4e178fac856a786d5d41536f8f71.zip |
Always do the setgroups, setresgid and setresuid even if if the
unprivileged user is not present instead of erroring out. This lets
ping and traceroute work in restricted enviornments like the bgplg
chroot.
Problem reported by sthen@
input & prodding deraadt@
-rw-r--r-- | sbin/ping/ping.c | 28 | ||||
-rw-r--r-- | usr.sbin/traceroute/traceroute.c | 26 |
2 files changed, 33 insertions, 21 deletions
diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c index 383ef654af5..6f96a602420 100644 --- a/sbin/ping/ping.c +++ b/sbin/ping/ping.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ping.c,v 1.215 2016/09/26 16:42:46 florian Exp $ */ +/* $OpenBSD: ping.c,v 1.216 2016/09/28 06:39:12 florian Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -259,7 +259,8 @@ main(int argc, char *argv[]) char rspace[3 + 4 * NROUTES + 1]; /* record route space */ const char *errstr; double intval; - uid_t uid; + uid_t ouid, uid; + gid_t gid; u_int rtableid = 0; extern char *__progname; @@ -274,12 +275,17 @@ main(int argc, char *argv[]) } /* revoke privs */ - uid = getuid(); - if ((pw = getpwnam(PING_USER)) == NULL) - errx(1, "no %s user", PING_USER); - if (setgroups(1, &pw->pw_gid) || - setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || - setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) + ouid = getuid(); + if ((pw = getpwnam(PING_USER)) != NULL) { + uid = pw->pw_uid; + gid = pw->pw_gid; + } else { + uid = getuid(); + gid = getgid(); + } + if (setgroups(1, &gid) || + setresgid(gid, gid, gid) || + setresuid(uid, uid, uid)) err(1, "unable to revoke privs"); preload = 0; @@ -309,7 +315,7 @@ main(int argc, char *argv[]) options |= F_AUD_RECV; break; case 'f': - if (uid) + if (ouid) errc(1, EPERM, NULL); options |= F_FLOOD; setvbuf(stdout, NULL, _IONBF, 0); @@ -330,7 +336,7 @@ main(int argc, char *argv[]) intval = strtod(optarg, &e); if (*optarg == '\0' || *e != '\0') errx(1, "illegal timing interval %s", optarg); - if (intval < 1 && uid) + if (intval < 1 && ouid) errx(1, "only root may use interval < 1s"); interval.tv_sec = (time_t)intval; interval.tv_usec = @@ -349,7 +355,7 @@ main(int argc, char *argv[]) loop = 0; break; case 'l': - if (uid) + if (ouid) errc(1, EPERM, NULL); preload = strtonum(optarg, 1, INT64_MAX, &errstr); if (errstr) diff --git a/usr.sbin/traceroute/traceroute.c b/usr.sbin/traceroute/traceroute.c index ba04494693d..1444de11f9e 100644 --- a/usr.sbin/traceroute/traceroute.c +++ b/usr.sbin/traceroute/traceroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: traceroute.c,v 1.148 2016/09/27 05:33:46 florian Exp $ */ +/* $OpenBSD: traceroute.c,v 1.149 2016/09/28 06:39:12 florian Exp $ */ /* $NetBSD: traceroute.c,v 1.10 1995/05/21 15:50:45 mycroft Exp $ */ /* @@ -328,7 +328,8 @@ main(int argc, char *argv[]) char *ep, hbuf[NI_MAXHOST], *dest, *source = NULL; const char *errstr; long l; - uid_t uid; + uid_t ouid, uid; + gid_t gid; u_int rtableid; socklen_t len; @@ -346,12 +347,17 @@ main(int argc, char *argv[]) v4sock_errno = errno; /* revoke privs */ - uid = getuid(); - if ((pw = getpwnam(TRACEROUTE_USER)) == NULL) - errx(1, "no %s user", TRACEROUTE_USER); - if (setgroups(1, &pw->pw_gid) || - setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || - setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) + ouid = getuid(); + if ((pw = getpwnam(TRACEROUTE_USER)) != NULL) { + uid = pw->pw_uid; + gid = pw->pw_gid; + } else { + uid = getuid(); + gid = getgid(); + } + if (setgroups(1, &gid) || + setresgid(gid, gid, gid) || + setresuid(uid, uid, uid)) err(1, "unable to revoke privs"); if (strcmp("traceroute6", __progname) == 0) { @@ -670,13 +676,13 @@ main(int argc, char *argv[]) if (inet_aton(source, &from4.sin_addr) == 0) errx(1, "unknown host %s", source); ip->ip_src = from4.sin_addr; - if (uid != 0 && + if (ouid != 0 && (ntohl(from4.sin_addr.s_addr) & 0xff000000U) == 0x7f000000U && (ntohl(to4.sin_addr.s_addr) & 0xff000000U) != 0x7f000000U) errx(1, "source is on 127/8, destination is" " not"); - if (uid && bind(sndsock, (struct sockaddr *)&from4, + if (ouid && bind(sndsock, (struct sockaddr *)&from4, sizeof(from4)) < 0) err(1, "bind"); } |