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
This commit is contained in:
parent
94dc571595
commit
c5a2d8c5f5
@ -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>
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user