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$
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <src.opts.mk>
|
||||||
|
|
||||||
PROG= sockstat
|
PROG= sockstat
|
||||||
|
|
||||||
LIBADD= jail
|
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>
|
.include <bsd.prog.mk>
|
||||||
|
@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <netinet/tcp_var.h>
|
#include <netinet/tcp_var.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include <capsicum_helpers.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -67,6 +68,11 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.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 sstosin(ss) ((struct sockaddr_in *)(ss))
|
||||||
#define sstosin6(ss) ((struct sockaddr_in6 *)(ss))
|
#define sstosin6(ss) ((struct sockaddr_in6 *)(ss))
|
||||||
#define sstosun(ss) ((struct sockaddr_un *)(ss))
|
#define sstosun(ss) ((struct sockaddr_un *)(ss))
|
||||||
@ -132,6 +138,10 @@ static struct sock *sockhash[HASHSIZE];
|
|||||||
static struct xfile *xfiles;
|
static struct xfile *xfiles;
|
||||||
static int nxfiles;
|
static int nxfiles;
|
||||||
|
|
||||||
|
static cap_channel_t *capnet;
|
||||||
|
static cap_channel_t *capnetdb;
|
||||||
|
static cap_channel_t *capsysctl;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xprintf(const char *fmt, ...)
|
xprintf(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -153,9 +163,9 @@ get_proto_type(const char *proto)
|
|||||||
|
|
||||||
if (strlen(proto) == 0)
|
if (strlen(proto) == 0)
|
||||||
return (0);
|
return (0);
|
||||||
pent = getprotobyname(proto);
|
pent = cap_getprotobyname(capnetdb, proto);
|
||||||
if (pent == NULL) {
|
if (pent == NULL) {
|
||||||
warn("getprotobyname");
|
warn("cap_getprotobyname");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
return (pent->p_proto);
|
return (pent->p_proto);
|
||||||
@ -321,17 +331,17 @@ gather_sctp(void)
|
|||||||
vflag |= INP_IPV6;
|
vflag |= INP_IPV6;
|
||||||
|
|
||||||
varname = "net.inet.sctp.assoclist";
|
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)
|
if (errno != ENOENT)
|
||||||
err(1, "sysctlbyname()");
|
err(1, "cap_sysctlbyname()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((buf = (char *)malloc(len)) == NULL) {
|
if ((buf = (char *)malloc(len)) == NULL) {
|
||||||
err(1, "malloc()");
|
err(1, "malloc()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sysctlbyname(varname, buf, &len, 0, 0) < 0) {
|
if (cap_sysctlbyname(capsysctl, varname, buf, &len, 0, 0) < 0) {
|
||||||
err(1, "sysctlbyname()");
|
err(1, "cap_sysctlbyname()");
|
||||||
free(buf);
|
free(buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -618,12 +628,13 @@ gather_inet(int proto)
|
|||||||
if ((buf = realloc(buf, bufsize)) == NULL)
|
if ((buf = realloc(buf, bufsize)) == NULL)
|
||||||
err(1, "realloc()");
|
err(1, "realloc()");
|
||||||
len = bufsize;
|
len = bufsize;
|
||||||
if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
|
if (cap_sysctlbyname(capsysctl, varname, buf, &len,
|
||||||
|
NULL, 0) == 0)
|
||||||
break;
|
break;
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
goto out;
|
goto out;
|
||||||
if (errno != ENOMEM || len != bufsize)
|
if (errno != ENOMEM || len != bufsize)
|
||||||
err(1, "sysctlbyname()");
|
err(1, "cap_sysctlbyname()");
|
||||||
bufsize *= 2;
|
bufsize *= 2;
|
||||||
}
|
}
|
||||||
xig = (struct xinpgen *)buf;
|
xig = (struct xinpgen *)buf;
|
||||||
@ -768,10 +779,11 @@ gather_unix(int proto)
|
|||||||
if ((buf = realloc(buf, bufsize)) == NULL)
|
if ((buf = realloc(buf, bufsize)) == NULL)
|
||||||
err(1, "realloc()");
|
err(1, "realloc()");
|
||||||
len = bufsize;
|
len = bufsize;
|
||||||
if (sysctlbyname(varname, buf, &len, NULL, 0) == 0)
|
if (cap_sysctlbyname(capsysctl, varname, buf, &len,
|
||||||
|
NULL, 0) == 0)
|
||||||
break;
|
break;
|
||||||
if (errno != ENOMEM || len != bufsize)
|
if (errno != ENOMEM || len != bufsize)
|
||||||
err(1, "sysctlbyname()");
|
err(1, "cap_sysctlbyname()");
|
||||||
bufsize *= 2;
|
bufsize *= 2;
|
||||||
}
|
}
|
||||||
xug = (struct xunpgen *)buf;
|
xug = (struct xunpgen *)buf;
|
||||||
@ -835,9 +847,10 @@ getfiles(void)
|
|||||||
olen = len = sizeof(*xfiles);
|
olen = len = sizeof(*xfiles);
|
||||||
if ((xfiles = malloc(len)) == NULL)
|
if ((xfiles = malloc(len)) == NULL)
|
||||||
err(1, "malloc()");
|
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)
|
if (errno != ENOMEM || len != olen)
|
||||||
err(1, "sysctlbyname()");
|
err(1, "cap_sysctlbyname()");
|
||||||
olen = len *= 2;
|
olen = len *= 2;
|
||||||
if ((xfiles = realloc(xfiles, len)) == NULL)
|
if ((xfiles = realloc(xfiles, len)) == NULL)
|
||||||
err(1, "realloc()");
|
err(1, "realloc()");
|
||||||
@ -871,10 +884,10 @@ printaddr(struct sockaddr_storage *ss)
|
|||||||
return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
|
return (xprintf("%.*s", sun->sun_len - off, sun->sun_path));
|
||||||
}
|
}
|
||||||
if (addrstr[0] == '\0') {
|
if (addrstr[0] == '\0') {
|
||||||
error = getnameinfo(sstosa(ss), ss->ss_len, addrstr,
|
error = cap_getnameinfo(capnet, sstosa(ss), ss->ss_len,
|
||||||
sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
|
addrstr, sizeof(addrstr), NULL, 0, NI_NUMERICHOST);
|
||||||
if (error)
|
if (error)
|
||||||
errx(1, "getnameinfo()");
|
errx(1, "cap_getnameinfo()");
|
||||||
}
|
}
|
||||||
if (port == 0)
|
if (port == 0)
|
||||||
return xprintf("%s:*", addrstr);
|
return xprintf("%s:*", addrstr);
|
||||||
@ -894,10 +907,11 @@ getprocname(pid_t pid)
|
|||||||
mib[2] = KERN_PROC_PID;
|
mib[2] = KERN_PROC_PID;
|
||||||
mib[3] = (int)pid;
|
mib[3] = (int)pid;
|
||||||
len = sizeof(proc);
|
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. */
|
/* Do not warn if the process exits before we get its name. */
|
||||||
if (errno != ESRCH)
|
if (errno != ESRCH)
|
||||||
warn("sysctl()");
|
warn("cap_sysctl()");
|
||||||
return ("??");
|
return ("??");
|
||||||
}
|
}
|
||||||
return (proc.ki_comm);
|
return (proc.ki_comm);
|
||||||
@ -915,10 +929,11 @@ getprocjid(pid_t pid)
|
|||||||
mib[2] = KERN_PROC_PID;
|
mib[2] = KERN_PROC_PID;
|
||||||
mib[3] = (int)pid;
|
mib[3] = (int)pid;
|
||||||
len = sizeof(proc);
|
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. */
|
/* Do not warn if the process exits before we get its jid. */
|
||||||
if (errno != ESRCH)
|
if (errno != ESRCH)
|
||||||
warn("sysctl()");
|
warn("cap_sysctl()");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
return (proc.ki_jid);
|
return (proc.ki_jid);
|
||||||
@ -1254,9 +1269,9 @@ set_default_protos(void)
|
|||||||
|
|
||||||
for (pindex = 0; pindex < default_numprotos; pindex++) {
|
for (pindex = 0; pindex < default_numprotos; pindex++) {
|
||||||
pname = default_protos[pindex];
|
pname = default_protos[pindex];
|
||||||
prot = getprotobyname(pname);
|
prot = cap_getprotobyname(capnetdb, pname);
|
||||||
if (prot == NULL)
|
if (prot == NULL)
|
||||||
err(1, "getprotobyname: %s", pname);
|
err(1, "cap_getprotobyname: %s", pname);
|
||||||
protos[pindex] = prot->p_proto;
|
protos[pindex] = prot->p_proto;
|
||||||
}
|
}
|
||||||
numprotos = pindex;
|
numprotos = pindex;
|
||||||
@ -1306,6 +1321,8 @@ usage(void)
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
cap_channel_t *capcas;
|
||||||
|
cap_net_limit_t *limit;
|
||||||
int protos_defined = -1;
|
int protos_defined = -1;
|
||||||
int o, i;
|
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)
|
if ((!opt_4 && !opt_6) && protos_defined != -1)
|
||||||
opt_4 = opt_6 = 1;
|
opt_4 = opt_6 = 1;
|
||||||
if (!opt_4 && !opt_6 && !opt_u)
|
if (!opt_4 && !opt_6 && !opt_u)
|
||||||
|
Loading…
Reference in New Issue
Block a user