Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F141058967
D21050.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D21050.diff
View Options
Index: head/sbin/ping6/Makefile
===================================================================
--- head/sbin/ping6/Makefile
+++ head/sbin/ping6/Makefile
@@ -1,5 +1,7 @@
# $FreeBSD$
+.include <src.opts.mk>
+
PACKAGE=runtime
PROG= ping6
MAN= ping6.8
@@ -11,5 +13,13 @@
BINMODE=4555
LIBADD= ipsec m md
+
+.if ${MK_DYNAMICROOT} == "no"
+.warning ${PROG} built without libcasper support
+.elif ${MK_CASPER} != "no" && !defined(RESCUE)
+LIBADD+= casper
+LIBADD+= cap_dns
+CFLAGS+=-DWITH_CASPER
+.endif
.include <bsd.prog.mk>
Index: head/sbin/ping6/ping6.c
===================================================================
--- head/sbin/ping6/ping6.c
+++ head/sbin/ping6/ping6.c
@@ -104,6 +104,7 @@
*/
#include <sys/param.h>
+#include <sys/capsicum.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/time.h>
@@ -118,6 +119,10 @@
#include <arpa/nameser.h>
#include <netdb.h>
+#include <capsicum_helpers.h>
+#include <casper/cap_dns.h>
+#include <libcasper.h>
+
#include <ctype.h>
#include <err.h>
#include <errno.h>
@@ -214,7 +219,8 @@
static struct sockaddr_in6 src; /* src addr of this packet */
static socklen_t srclen;
static size_t datalen = DEFDATALEN;
-static int s; /* socket file descriptor */
+static int ssend; /* send socket file descriptor */
+static int srecv; /* receive socket file descriptor */
static u_char outpack[MAXPACKETLEN];
static char BSPACE = '\b'; /* characters written for flood */
static char BBELL = '\a'; /* characters written for AUDIBLE */
@@ -224,6 +230,7 @@
static u_int8_t nonce[8]; /* nonce field for node information */
static int hoplimit = -1; /* hoplimit */
static u_char *packet = NULL;
+static cap_channel_t *capdns;
/* counters */
static long nmissedmax; /* max value of ntransmitted - nreceived - 1 */
@@ -256,6 +263,7 @@
#endif
int main(int, char *[]);
+static cap_channel_t *capdns_setup(void);
static void fill(char *, char *);
static int get_hoplim(struct msghdr *);
static int get_pathmtu(struct msghdr *);
@@ -318,6 +326,9 @@
#ifdef IPV6_USE_MIN_MTU
int mflag = 0;
#endif
+ cap_rights_t rights_srecv;
+ cap_rights_t rights_ssend;
+ cap_rights_t rights_stdin;
/* just to be sure */
memset(&smsghdr, 0, sizeof(smsghdr));
@@ -325,6 +336,7 @@
alarmtimeout = preload = 0;
datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN];
+ capdns = capdns_setup();
#ifndef IPSEC
#define ADDOPTS
#else
@@ -503,7 +515,7 @@
hints.ai_socktype = SOCK_RAW;
hints.ai_protocol = IPPROTO_ICMPV6;
- error = getaddrinfo(optarg, NULL, &hints, &res);
+ error = cap_getaddrinfo(capdns, optarg, NULL, &hints, &res);
if (error) {
errx(1, "invalid source address: %s",
gai_strerror(error));
@@ -619,14 +631,14 @@
} else
target = argv[argc - 1];
- /* getaddrinfo */
+ /* cap_getaddrinfo */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_RAW;
hints.ai_protocol = IPPROTO_ICMPV6;
- error = getaddrinfo(target, NULL, &hints, &res);
+ error = cap_getaddrinfo(capdns, target, NULL, &hints, &res);
if (error)
errx(1, "%s", gai_strerror(error));
if (res->ai_canonname)
@@ -635,13 +647,16 @@
hostname = target;
if (!res->ai_addr)
- errx(1, "getaddrinfo failed");
+ errx(1, "cap_getaddrinfo failed");
(void)memcpy(&dst, res->ai_addr, res->ai_addrlen);
- if ((s = socket(res->ai_family, res->ai_socktype,
+ if ((ssend = socket(res->ai_family, res->ai_socktype,
res->ai_protocol)) < 0)
- err(1, "socket");
+ err(1, "socket ssend");
+ if ((srecv = socket(res->ai_family, res->ai_socktype,
+ res->ai_protocol)) < 0)
+ err(1, "socket srecv");
freeaddrinfo(res);
/* set the source address if specified. */
@@ -656,7 +671,7 @@
if (dst.sin6_scope_id == 0)
dst.sin6_scope_id = src.sin6_scope_id;
}
- if (bind(s, (struct sockaddr *)&src, srclen) != 0)
+ if (bind(ssend, (struct sockaddr *)&src, srclen) != 0)
err(1, "bind");
}
/* set the gateway (next hop) if specified */
@@ -666,15 +681,15 @@
hints.ai_socktype = SOCK_RAW;
hints.ai_protocol = IPPROTO_ICMPV6;
- error = getaddrinfo(gateway, NULL, &hints, &res);
+ error = cap_getaddrinfo(capdns, gateway, NULL, &hints, &res);
if (error) {
- errx(1, "getaddrinfo for the gateway %s: %s",
+ errx(1, "cap_getaddrinfo for the gateway %s: %s",
gateway, gai_strerror(error));
}
if (res->ai_next && (options & F_VERBOSE))
warnx("gateway resolves to multiple addresses");
- if (setsockopt(s, IPPROTO_IPV6, IPV6_NEXTHOP,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_NEXTHOP,
res->ai_addr, res->ai_addrlen)) {
err(1, "setsockopt(IPV6_NEXTHOP)");
}
@@ -690,25 +705,25 @@
int opton = 1;
#ifdef IPV6_RECVHOPOPTS
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_RECVHOPOPTS)");
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPOPTS, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_HOPOPTS, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_HOPOPTS)");
#endif
#ifdef IPV6_RECVDSTOPTS
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_RECVDSTOPTS)");
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_DSTOPTS, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_DSTOPTS, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_DSTOPTS)");
#endif
#ifdef IPV6_RECVRTHDRDSTOPTS
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)");
#endif
@@ -751,31 +766,34 @@
arc4random_buf(nonce, sizeof(nonce));
optval = 1;
if (options & F_DONTFRAG)
- if (setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_DONTFRAG,
&optval, sizeof(optval)) == -1)
err(1, "IPV6_DONTFRAG");
hold = 1;
- if (options & F_SO_DEBUG)
- (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
+ if (options & F_SO_DEBUG) {
+ (void)setsockopt(ssend, SOL_SOCKET, SO_DEBUG, (char *)&hold,
sizeof(hold));
+ (void)setsockopt(srecv, SOL_SOCKET, SO_DEBUG, (char *)&hold,
+ sizeof(hold));
+ }
optval = IPV6_DEFHLIM;
if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr))
- if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
&optval, sizeof(optval)) == -1)
err(1, "IPV6_MULTICAST_HOPS");
#ifdef IPV6_USE_MIN_MTU
if (mflag != 1) {
optval = mflag > 1 ? 0 : 1;
- if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
&optval, sizeof(optval)) == -1)
err(1, "setsockopt(IPV6_USE_MIN_MTU)");
}
#ifdef IPV6_RECVPATHMTU
else {
optval = 1;
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPATHMTU,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVPATHMTU,
&optval, sizeof(optval)) == -1)
err(1, "setsockopt(IPV6_RECVPATHMTU)");
}
@@ -785,29 +803,38 @@
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
if (options & F_POLICY) {
- if (setpolicy(s, policy_in) < 0)
+ if (setpolicy(srecv, policy_in) < 0)
errx(1, "%s", ipsec_strerror());
- if (setpolicy(s, policy_out) < 0)
+ if (setpolicy(ssend, policy_out) < 0)
errx(1, "%s", ipsec_strerror());
}
#else
if (options & F_AUTHHDR) {
optval = IPSEC_LEVEL_REQUIRE;
#ifdef IPV6_AUTH_TRANS_LEVEL
- if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
&optval, sizeof(optval)) == -1)
err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)");
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
+ &optval, sizeof(optval)) == -1)
+ err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)");
#else /* old def */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_LEVEL,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_AUTH_LEVEL,
&optval, sizeof(optval)) == -1)
err(1, "setsockopt(IPV6_AUTH_LEVEL)");
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_AUTH_LEVEL,
+ &optval, sizeof(optval)) == -1)
+ err(1, "setsockopt(IPV6_AUTH_LEVEL)");
#endif
}
if (options & F_ENCRYPT) {
optval = IPSEC_LEVEL_REQUIRE;
- if (setsockopt(s, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
&optval, sizeof(optval)) == -1)
err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)");
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
+ &optval, sizeof(optval)) == -1)
+ err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)");
}
#endif /*IPSEC_POLICY_IPSEC*/
#endif
@@ -825,7 +852,7 @@
} else {
ICMP6_FILTER_SETPASSALL(&filt);
}
- if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
+ if (setsockopt(srecv, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
sizeof(filt)) < 0)
err(1, "setsockopt(ICMP6_FILTER)");
}
@@ -836,11 +863,11 @@
int opton = 1;
#ifdef IPV6_RECVRTHDR
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_RECVRTHDR)");
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, &opton,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RTHDR, &opton,
sizeof(opton)))
err(1, "setsockopt(IPV6_RTHDR)");
#endif
@@ -849,7 +876,7 @@
/*
optval = 1;
if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr))
- if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
&optval, sizeof(optval)) == -1)
err(1, "IPV6_MULTICAST_LOOP");
*/
@@ -916,7 +943,7 @@
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
- if ((error = getaddrinfo(argv[hops], NULL, &hints,
+ if ((error = cap_getaddrinfo(capdns, argv[hops], NULL, &hints,
&res)))
errx(1, "%s", gai_strerror(error));
if (res->ai_addr->sa_family != AF_INET6)
@@ -931,6 +958,15 @@
scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
}
+ /* From now on we will use only reverse DNS lookups. */
+ if (capdns != NULL) {
+ const char *types[1];
+
+ types[0] = "ADDR2NAME";
+ if (cap_dns_type_limit(capdns, types, nitems(types)) < 0)
+ err(1, "unable to limit access to system.dns service");
+ }
+
if (!(options & F_SRCADDR)) {
/*
* get the source address. XXX since we revoked the root
@@ -976,14 +1012,36 @@
close(dummy);
}
+ if (connect(ssend, (struct sockaddr *)&dst, sizeof(dst)) != 0)
+ err(1, "connect() ssend");
+
+ caph_cache_catpages();
+ if (caph_enter_casper() < 0)
+ err(1, "caph_enter_casper");
+
+ cap_rights_init(&rights_stdin);
+ if (cap_rights_limit(STDIN_FILENO, &rights_stdin) < 0)
+ err(1, "cap_rights_limit stdin");
+ if (caph_limit_stdout() < 0)
+ err(1, "caph_limit_stdout");
+ if (caph_limit_stderr() < 0)
+ err(1, "caph_limit_stderr");
+
+ cap_rights_init(&rights_srecv, CAP_RECV, CAP_EVENT, CAP_SETSOCKOPT);
+ if (caph_rights_limit(srecv, &rights_srecv) < 0)
+ err(1, "cap_rights_limit srecv");
+ cap_rights_init(&rights_ssend, CAP_SEND, CAP_SETSOCKOPT);
+ if (caph_rights_limit(ssend, &rights_ssend) < 0)
+ err(1, "cap_rights_limit ssend");
+
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
if (sockbufsize) {
if (datalen > (size_t)sockbufsize)
warnx("you need -b to increase socket buffer size");
- if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
+ if (setsockopt(ssend, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
sizeof(sockbufsize)) < 0)
err(1, "setsockopt(SO_SNDBUF)");
- if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &sockbufsize,
+ if (setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, &sockbufsize,
sizeof(sockbufsize)) < 0)
err(1, "setsockopt(SO_RCVBUF)");
}
@@ -997,7 +1055,7 @@
* to get some stuff for /etc/ethers.
*/
hold = 48 * 1024;
- setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
+ setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
sizeof(hold));
}
#endif
@@ -1005,25 +1063,32 @@
optval = 1;
#ifndef USE_SIN6_SCOPE_ID
#ifdef IPV6_RECVPKTINFO
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval,
sizeof(optval)) < 0)
warn("setsockopt(IPV6_RECVPKTINFO)"); /* XXX err? */
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &optval,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_PKTINFO, &optval,
sizeof(optval)) < 0)
warn("setsockopt(IPV6_PKTINFO)"); /* XXX err? */
#endif
#endif /* USE_SIN6_SCOPE_ID */
#ifdef IPV6_RECVHOPLIMIT
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval,
sizeof(optval)) < 0)
warn("setsockopt(IPV6_RECVHOPLIMIT)"); /* XXX err? */
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval,
+ if (setsockopt(srecv, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval,
sizeof(optval)) < 0)
warn("setsockopt(IPV6_HOPLIMIT)"); /* XXX err? */
#endif
+ cap_rights_clear(&rights_srecv, CAP_SETSOCKOPT);
+ if (caph_rights_limit(srecv, &rights_srecv) < 0)
+ err(1, "cap_rights_limit srecv setsockopt");
+ cap_rights_clear(&rights_ssend, CAP_SETSOCKOPT);
+ if (caph_rights_limit(ssend, &rights_ssend) < 0)
+ err(1, "cap_rights_limit ssend setsockopt");
+
printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()),
(unsigned long)(pingerlen() - 8));
printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src)));
@@ -1081,7 +1146,7 @@
}
#endif
FD_ZERO(&rfds);
- FD_SET(s, &rfds);
+ FD_SET(srecv, &rfds);
gettimeofday(&now, NULL);
timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec;
timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec;
@@ -1096,7 +1161,7 @@
if (timeout.tv_sec < 0)
timeout.tv_sec = timeout.tv_usec = 0;
- n = select(s + 1, &rfds, NULL, NULL, &timeout);
+ n = select(srecv + 1, &rfds, NULL, NULL, &timeout);
if (n < 0)
continue; /* EINTR */
if (n == 1) {
@@ -1111,7 +1176,7 @@
m.msg_control = (void *)cm;
m.msg_controllen = CONTROLLEN;
- cc = recvmsg(s, &m, 0);
+ cc = recvmsg(srecv, &m, 0);
if (cc < 0) {
if (errno != EINTR) {
warn("recvmsg");
@@ -1325,15 +1390,13 @@
errx(1, "internal error; length mismatch");
#endif
- smsghdr.msg_name = (caddr_t)&dst;
- smsghdr.msg_namelen = sizeof(dst);
memset(&iov, 0, sizeof(iov));
iov[0].iov_base = (caddr_t)outpack;
iov[0].iov_len = cc;
smsghdr.msg_iov = iov;
smsghdr.msg_iovlen = 1;
- i = sendmsg(s, &smsghdr, 0);
+ i = sendmsg(ssend, &smsghdr, 0);
if (i < 0 || i != cc) {
if (i < 0)
@@ -2497,7 +2560,8 @@
if ((options & F_HOSTNAME) == 0)
flag |= NI_NUMERICHOST;
- if (getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, flag) == 0)
+ if (cap_getnameinfo(capdns, addr, addrlen, buf, sizeof(buf), NULL, 0,
+ flag) == 0)
return (buf);
else
return "?";
@@ -2631,7 +2695,7 @@
buf = ipsec_set_policy(policy, strlen(policy));
if (buf == NULL)
errx(1, "%s", ipsec_strerror());
- if (setsockopt(s, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf,
+ if (setsockopt(ssend, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf,
ipsec_get_policylen(buf)) < 0)
warnx("Unable to set IPsec policy");
free(buf);
@@ -2727,4 +2791,30 @@
"[-x waittime]\n"
" [-X timeout] [hops ...] host\n");
exit(1);
+}
+
+static cap_channel_t *
+capdns_setup(void)
+{
+ cap_channel_t *capcas, *capdnsloc;
+ const char *types[2];
+ int families[1];
+
+ capcas = cap_init();
+ if (capcas == NULL)
+ err(1, "unable to create casper process");
+ capdnsloc = cap_service_open(capcas, "system.dns");
+ /* Casper capability no longer needed. */
+ cap_close(capcas);
+ if (capdnsloc == NULL)
+ err(1, "unable to open system.dns service");
+ types[0] = "NAME2ADDR";
+ types[1] = "ADDR2NAME";
+ if (cap_dns_type_limit(capdnsloc, types, nitems(types)) < 0)
+ err(1, "unable to limit access to system.dns service");
+ families[0] = AF_INET6;
+ if (cap_dns_family_limit(capdnsloc, families, nitems(families)) < 0)
+ err(1, "unable to limit access to system.dns service");
+
+ return (capdnsloc);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 1, 8:21 AM (19 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27432626
Default Alt Text
D21050.diff (15 KB)
Attached To
Mode
D21050: Capsicumize ping6
Attached
Detach File
Event Timeline
Log In to Comment