libcasper: Create a minimal cap_netdb service

Create a casper service for netdb functions.
Initially only cap_getprotobyname is implemented.

This is needed for capsicumizing sockstat.

Reviewed by:	oshogbo, bcr (manpages)
Relnotes:	yes
Differential Revision:	https://reviews.freebsd.org/D24832
This commit is contained in:
Ryan Moeller 2021-03-26 15:40:19 -04:00
parent 1970d69303
commit 94dc571595
8 changed files with 436 additions and 0 deletions

View file

@ -6,6 +6,7 @@ SUBDIR= cap_dns
SUBDIR+= cap_fileargs
SUBDIR+= cap_grp
SUBDIR+= cap_net
SUBDIR+= cap_netdb
SUBDIR+= cap_pwd
SUBDIR+= cap_sysctl
SUBDIR+= cap_syslog

View file

@ -0,0 +1,32 @@
# $FreeBSD$
SHLIBDIR?= /lib/casper
.include <src.opts.mk>
PACKAGE= runtime
SHLIB_MAJOR= 1
INCSDIR?= ${INCLUDEDIR}/casper
.if ${MK_CASPER} != "no"
SHLIB= cap_netdb
SRCS= cap_netdb.c
.endif
INCS= cap_netdb.h
LIBADD= nv
CFLAGS+=-I${.CURDIR}
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
MAN+= cap_netdb.3
MLINKS+=cap_netdb.3 libcap_netdb.3
MLINKS+=cap_netdb.3 cap_getprotobyname.3
.include <bsd.lib.mk>

View file

@ -0,0 +1,90 @@
.\" Copyright (c) 2020 Ryan Moeller <freqlabs@FreeBSD.org>
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd May 12, 2020
.Dt CAP_NETDB 3
.Os
.Sh NAME
.Nm cap_getprotobyname ,
.Nd "library for getting network proto entry in capability mode"
.Sh LIBRARY
.Lb libcap_netdb
.Sh SYNOPSIS
.In sys/nv.h
.In libcasper.h
.In casper/cap_netdb.h
.Ft "struct protoent *"
.Fn cap_getprotobyname "const cap_channel_t *chan" "const char *name"
.Sh DESCRIPTION
.Bf -symbolic
The function
.Fn cap_getprotobyname
is equivalent to
.Xr getprotobyname 3
except that the connection to the
.Nm system.netdb
service needs to be provided.
.Sh EXAMPLES
The following example first opens a capability to casper and then uses this
capability to create the
.Nm system.netdb
casper service and uses it to look up a protocol by name.
.Bd -literal
cap_channel_t *capcas, *capnetdb;
struct protoent *ent;
/* Open capability to Casper. */
capcas = cap_init();
if (capcas == NULL)
err(1, "Unable to contact Casper");
/* Enter capability mode sandbox. */
if (caph_enter() < 0)
err(1, "Unable to enter capability mode");
/* Use Casper capability to create capability to the system.netdb service. */
capnetdb = cap_service_open(capcas, "system.netdb");
if (capnetdb == NULL)
err(1, "Unable to open system.netdb service");
/* Close Casper capability, we don't need it anymore. */
cap_close(capcas);
ent = cap_getprotobyname(capnetdb, "http");
if (ent == NULL)
errx(1, "cap_getprotobyname failed to find http proto");
.Ed
.Sh SEE ALSO
.Xr cap_enter 2 ,
.Xr caph_enter 3 ,
.Xr err 3 ,
.Xr getprotobyname 3 ,
.Xr capsicum 4 ,
.Xr nv 9
.Sh AUTHORS
The
.Nm cap_netdb
service was implemented by
.An Ryan Moeller Aq Mt freqlabs@FreeBSD.org .

View file

@ -0,0 +1,155 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2020 Ryan Moeller <freqlabs@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/dnv.h>
#include <sys/nv.h>
#include <netinet/in.h>
#include <assert.h>
#include <errno.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libcasper.h>
#include <libcasper_service.h>
#include "cap_netdb.h"
static struct protoent *
protoent_unpack(nvlist_t *nvl)
{
struct protoent *pp;
char **aliases;
size_t n;
pp = malloc(sizeof(*pp));
if (pp == NULL) {
nvlist_destroy(nvl);
return (NULL);
}
pp->p_name = nvlist_take_string(nvl, "name");
aliases = nvlist_take_string_array(nvl, "aliases", &n);
pp->p_aliases = realloc(aliases, sizeof(char *) * (n + 1));
if (pp->p_aliases == NULL) {
while (n-- > 0)
free(aliases[n]);
free(aliases);
free(pp->p_name);
free(pp);
nvlist_destroy(nvl);
return (NULL);
}
pp->p_aliases[n] = NULL;
pp->p_proto = (int)nvlist_take_number(nvl, "proto");
nvlist_destroy(nvl);
return (pp);
}
struct protoent *
cap_getprotobyname(cap_channel_t *chan, const char *name)
{
nvlist_t *nvl;
nvl = nvlist_create(0);
nvlist_add_string(nvl, "cmd", "getprotobyname");
nvlist_add_string(nvl, "name", name);
nvl = cap_xfer_nvlist(chan, nvl);
if (nvl == NULL)
return (NULL);
if (dnvlist_get_number(nvl, "error", 0) != 0) {
nvlist_destroy(nvl);
return (NULL);
}
return (protoent_unpack(nvl));
}
static void
protoent_pack(const struct protoent *pp, nvlist_t *nvl)
{
int n = 0;
nvlist_add_string(nvl, "name", pp->p_name);
while (pp->p_aliases[n] != NULL)
++n;
nvlist_add_string_array(nvl, "aliases",
(const char * const *)pp->p_aliases, n);
nvlist_add_number(nvl, "proto", (uint64_t)pp->p_proto);
}
static int
netdb_getprotobyname(const nvlist_t *limits __unused, const nvlist_t *nvlin,
nvlist_t *nvlout)
{
const char *name;
struct protoent *pp;
name = dnvlist_get_string(nvlin, "name", NULL);
if (name == NULL)
return (EDOOFUS);
pp = getprotobyname(name);
if (pp == NULL)
return (EINVAL);
protoent_pack(pp, nvlout);
return (0);
}
static int
netdb_limit(const nvlist_t *oldlimits __unused,
const nvlist_t *newlimits __unused)
{
return (0);
}
static int
netdb_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin,
nvlist_t *nvlout)
{
int error;
if (strcmp(cmd, "getprotobyname") == 0)
error = netdb_getprotobyname(limits, nvlin, nvlout);
else
error = NO_RECOVERY;
return (error);
}
CREATE_SERVICE("system.netdb", netdb_limit, netdb_command, 0);

View file

@ -0,0 +1,49 @@
/*-
* Copyright (c) 2020 Ryan Moeller <freqlabs@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _CAP_NETDB_H_
#define _CAP_NETDB_H_
#ifdef HAVE_CASPER
#define WITH_CASPER
#endif
#include <sys/cdefs.h>
#include <netdb.h>
#ifdef WITH_CASPER
__BEGIN_DECLS
struct protoent *cap_getprotobyname(cap_channel_t *chan, const char *name);
__END_DECLS
#else
#define cap_getprotobyname(chan, name) getprotobyname(name)
#endif
#endif /* !_CAP_NETDB_H_ */

View file

@ -0,0 +1,14 @@
# $FreeBSD$
.include <src.opts.mk>
ATF_TESTS_C= netdb_test
.if ${MK_CASPER} != "no"
LIBADD+= casper
LIBADD+= cap_netdb
CFLAGS+=-DWITH_CASPER
.endif
LIBADD+= nv
.include <bsd.test.mk>

View file

@ -0,0 +1,94 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2020 Ryan Moeller <freqlabs@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/capsicum.h>
#include <sys/nv.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libcasper.h>
#include <casper/cap_netdb.h>
#include <atf-c.h>
static cap_channel_t *
initcap(void)
{
cap_channel_t *capcas, *capnetdb;
capcas = cap_init();
ATF_REQUIRE(capcas != NULL);
capnetdb = cap_service_open(capcas, "system.netdb");
ATF_REQUIRE(capnetdb != NULL);
cap_close(capcas);
return (capnetdb);
}
ATF_TC_WITHOUT_HEAD(cap_netdb__getprotobyname);
ATF_TC_BODY(cap_netdb__getprotobyname, tc)
{
cap_channel_t *capnetdb;
struct protoent *pp;
size_t n = 0;
capnetdb = initcap();
pp = cap_getprotobyname(capnetdb, "tcp");
ATF_REQUIRE(pp != NULL);
ATF_REQUIRE(pp->p_name != NULL);
ATF_REQUIRE(pp->p_aliases != NULL);
while (pp->p_aliases[n] != NULL)
++n;
ATF_REQUIRE(n > 0);
ATF_REQUIRE(pp->p_proto != 0);
cap_close(capnetdb);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, cap_netdb__getprotobyname);
return (atf_no_error());
}

View file

@ -107,6 +107,7 @@ _LIBRARIES= \
cap_fileargs \
cap_grp \
cap_net \
cap_netdb \
cap_pwd \
cap_sysctl \
cap_syslog \