diff options
author | Ryan Moeller <freqlabs@FreeBSD.org> | 2021-03-26 19:42:19 +0000 |
---|---|---|
committer | Ryan Moeller <freqlabs@FreeBSD.org> | 2021-06-05 12:36:55 +0000 |
commit | c5a2d8c5f517b056bed2af64e6134481367773d4 (patch) | |
tree | 627bd5b8ef5c0313e48b6c60da0e843724e06d96 | |
parent | 94dc57159532d7bbf94d109e79fd202a57150562 (diff) | |
download | src-c5a2d8c5f517.tar.gz src-c5a2d8c5f517.zip |
sockstat: Use libcasper to capsicumize
Drop rights we do not need. This has to be done after jail_attach.
Reviewed by: oshogbo
Relnotes: yes
Differential Revision: https://reviews.freebsd.org/D26958
-rw-r--r-- | usr.bin/sockstat/Makefile | 10 | ||||
-rw-r--r-- | usr.bin/sockstat/sockstat.c | 80 |
2 files changed, 69 insertions, 21 deletions
diff --git a/usr.bin/sockstat/Makefile b/usr.bin/sockstat/Makefile index 2f8f9655e8db..6d0de7dc22d0 100644 --- a/usr.bin/sockstat/Makefile +++ b/usr.bin/sockstat/Makefile @@ -1,7 +1,17 @@ # $FreeBSD$ +.include <src.opts.mk> + PROG= sockstat LIBADD= jail +.if ${MK_CASPER} != "no" +LIBADD+= casper +LIBADD+= cap_net +LIBADD+= cap_netdb +LIBADD+= cap_sysctl +CFLAGS+= -DWITH_CASPER +.endif + .include <bsd.prog.mk> diff --git a/usr.bin/sockstat/sockstat.c b/usr.bin/sockstat/sockstat.c index 109b254b7438..7dc5e4904deb 100644 --- a/usr.bin/sockstat/sockstat.c +++ b/usr.bin/sockstat/sockstat.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/tcp_var.h> #include <arpa/inet.h> +#include <capsicum_helpers.h> #include <ctype.h> #include <err.h> #include <errno.h> @@ -67,6 +68,11 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <unistd.h> +#include <libcasper.h> +#include <casper/cap_net.h> +#include <casper/cap_netdb.h> +#include <casper/cap_sysctl.h> + #define sstosin(ss) ((struct sockaddr_in *)(ss)) #define sstosin6(ss) ((struct sockaddr_in6 *)(ss)) #define sstosun(ss) ((struct sockaddr_un *)(ss)) @@ -132,6 +138,10 @@ static struct sock *sockhash[HASHSIZE]; static struct xfile *xfiles; static int nxfiles; +static cap_channel_t *capnet; +static cap_channel_t *capnetdb; +static cap_channel_t *capsysctl; + static int xprintf(const char *fmt, ...) { @@ -153,9 +163,9 @@ get_proto_type(const char *proto) if (strlen(proto) == 0) return (0); - pent = getprotobyname(proto); + pent = cap_getprotobyname(capnetdb, proto); if (pent == NULL) { - warn("getprotobyname"); + warn("cap_getprotobyname"); return (-1); } return (pent->p_proto); @@ -321,17 +331,17 @@ gather_sctp(void) vflag |= INP_IPV6; varname = "net.inet.sctp.assoclist"; - if (sysctlbyname(varname, 0, &len, 0, 0) < 0) { + if (cap_sysctlbyname(capsysctl, varname, 0, &len, 0, 0) < 0) { if (errno != ENOENT) - err(1, "sysctlbyname()"); + err(1, "cap_sysctlbyname()"); return; } if ((buf = (char *)malloc(len)) == NULL) { err(1, "malloc()"); return; } - if (sysctlbyname(varname, buf, &len, 0, 0) < 0) { - err(1, "sysctlbyname()"); + if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) { + err(1, "cap_sysctlbyname()"); free(buf); return; } @@ -618,12 +628,13 @@ gather_inet(int proto) if ((buf = realloc(buf, bufsize)) == NULL) err(1, "realloc()"); len = bufsize; - if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) + if (cap_sysctlbyname(capsysctl, varname, buf, &len, + NULL, 0) == 0) break; if (errno == ENOENT) goto out; if (errno != ENOMEM || len != bufsize) - err(1, "sysctlbyname()"); + err(1, "cap_sysctlbyname()"); bufsize *= 2; } xig = (struct xinpgen *)buf; @@ -768,10 +779,11 @@ gather_unix(int proto) if ((buf = realloc(buf, bufsize)) == NULL) err(1, "realloc()"); len = bufsize; - if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) + if (cap_sysctlbyname(capsysctl, varname, buf, &len, + NULL, 0) == 0) break; if (errno != ENOMEM || len != bufsize) - err(1, "sysctlbyname()"); + err(1, "cap_sysctlbyname()"); bufsize *= 2; } xug = (struct xunpgen *)buf; @@ -835,9 +847,10 @@ getfiles(void) olen = len = sizeof(*xfiles); if ((xfiles = malloc(len)) == NULL) err(1, "malloc()"); - while (sysctlbyname("kern.file", xfiles, &len, 0, 0) == -1) { + while (cap_sysctlbyname(capsysctl, "kern.file", xfiles, &len, 0, 0) + == -1) { if (errno != ENOMEM || len != olen) - err(1, "sysctlbyname()"); + err(1, "cap_sysctlbyname()"); olen = len *= 2; if ((xfiles = realloc(xfiles, len)) == NULL) err(1, "realloc()"); @@ -871,10 +884,10 @@ printaddr(struct sockaddr_storage *ss) return (xprintf("%.*s", sun->sun_len - off, sun->sun_path)); } if (addrstr[0] == '\0') { - error = getnameinfo(sstosa(ss), ss->ss_len, addrstr, - sizeof(addrstr), NULL, 0, NI_NUMERICHOST); + error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len, + addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST); if (error) - errx(1, "getnameinfo()"); + errx(1, "cap_getnameinfo()"); } if (port == 0) return xprintf("%s:*", addrstr); @@ -894,10 +907,11 @@ getprocname(pid_t pid) mib[2] = KERN_PROC_PID; mib[3] = (int)pid; len = sizeof(proc); - if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { + if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0) + == -1) { /* Do not warn if the process exits before we get its name. */ if (errno != ESRCH) - warn("sysctl()"); + warn("cap_sysctl()"); return ("??"); } return (proc.ki_comm); @@ -915,10 +929,11 @@ getprocjid(pid_t pid) mib[2] = KERN_PROC_PID; mib[3] = (int)pid; len = sizeof(proc); - if (sysctl(mib, nitems(mib), &proc, &len, NULL, 0) == -1) { + if (cap_sysctl(capsysctl, mib, nitems(mib), &proc, &len, NULL, 0) + == -1) { /* Do not warn if the process exits before we get its jid. */ if (errno != ESRCH) - warn("sysctl()"); + warn("cap_sysctl()"); return (-1); } return (proc.ki_jid); @@ -1254,9 +1269,9 @@ set_default_protos(void) for (pindex = 0; pindex < default_numprotos; pindex++) { pname = default_protos[pindex]; - prot = getprotobyname(pname); + prot = cap_getprotobyname(capnetdb, pname); if (prot == NULL) - err(1, "getprotobyname: %s", pname); + err(1, "cap_getprotobyname: %s", pname); protos[pindex] = prot->p_proto; } numprotos = pindex; @@ -1306,6 +1321,8 @@ usage(void) int main(int argc, char *argv[]) { + cap_channel_t *capcas; + cap_net_limit_t *limit; int protos_defined = -1; int o, i; @@ -1390,6 +1407,27 @@ main(int argc, char *argv[]) } } + capcas = cap_init(); + if (capcas == NULL) + err(1, "Unable to contact Casper"); + if (caph_enter_casper() < 0) + err(1, "Unable to enter capability mode"); + capnet = cap_service_open(capcas, "system.net"); + if (capnet == NULL) + err(1, "Unable to open system.net service"); + capnetdb = cap_service_open(capcas, "system.netdb"); + if (capnetdb == NULL) + err(1, "Unable to open system.netdb service"); + capsysctl = cap_service_open(capcas, "system.sysctl"); + if (capsysctl == NULL) + err(1, "Unable to open system.sysctl service"); + cap_close(capcas); + limit = cap_net_limit_init(capnet, CAPNET_ADDR2NAME); + if (limit == NULL) + err(1, "Unable to init cap_net limits"); + if (cap_net_limit(limit) < 0) + err(1, "Unable to apply limits"); + if ((!opt_4 && !opt_6) && protos_defined != -1) opt_4 = opt_6 = 1; if (!opt_4 && !opt_6 && !opt_u) |