git: 94dc57159532 - main - libcasper: Create a minimal cap_netdb service

Ryan Moeller freqlabs at FreeBSD.org
Sat Jun 5 12:37:10 UTC 2021


The branch main has been updated by freqlabs:

URL: https://cgit.FreeBSD.org/src/commit/?id=94dc57159532d7bbf94d109e79fd202a57150562

commit 94dc57159532d7bbf94d109e79fd202a57150562
Author:     Ryan Moeller <freqlabs at FreeBSD.org>
AuthorDate: 2021-03-26 19:40:19 +0000
Commit:     Ryan Moeller <freqlabs at FreeBSD.org>
CommitDate: 2021-06-05 12:36:53 +0000

    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
---
 lib/libcasper/services/Makefile                    |   1 +
 lib/libcasper/services/cap_netdb/Makefile          |  32 +++++
 lib/libcasper/services/cap_netdb/cap_netdb.3       |  90 ++++++++++++
 lib/libcasper/services/cap_netdb/cap_netdb.c       | 155 +++++++++++++++++++++
 lib/libcasper/services/cap_netdb/cap_netdb.h       |  49 +++++++
 lib/libcasper/services/cap_netdb/tests/Makefile    |  14 ++
 .../services/cap_netdb/tests/netdb_test.c          |  94 +++++++++++++
 share/mk/src.libnames.mk                           |   1 +
 8 files changed, 436 insertions(+)

diff --git a/lib/libcasper/services/Makefile b/lib/libcasper/services/Makefile
index 8fcb2e1e5c64..dfd4aaa76653 100644
--- a/lib/libcasper/services/Makefile
+++ b/lib/libcasper/services/Makefile
@@ -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
diff --git a/lib/libcasper/services/cap_netdb/Makefile b/lib/libcasper/services/cap_netdb/Makefile
new file mode 100644
index 000000000000..5070976d2e25
--- /dev/null
+++ b/lib/libcasper/services/cap_netdb/Makefile
@@ -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>
diff --git a/lib/libcasper/services/cap_netdb/cap_netdb.3 b/lib/libcasper/services/cap_netdb/cap_netdb.3
new file mode 100644
index 000000000000..6df34559224c
--- /dev/null
+++ b/lib/libcasper/services/cap_netdb/cap_netdb.3
@@ -0,0 +1,90 @@
+.\" Copyright (c) 2020 Ryan Moeller <freqlabs at 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 at FreeBSD.org .
diff --git a/lib/libcasper/services/cap_netdb/cap_netdb.c b/lib/libcasper/services/cap_netdb/cap_netdb.c
new file mode 100644
index 000000000000..e07deb93a798
--- /dev/null
+++ b/lib/libcasper/services/cap_netdb/cap_netdb.c
@@ -0,0 +1,155 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Ryan Moeller <freqlabs at 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);
diff --git a/lib/libcasper/services/cap_netdb/cap_netdb.h b/lib/libcasper/services/cap_netdb/cap_netdb.h
new file mode 100644
index 000000000000..4dc33c351520
--- /dev/null
+++ b/lib/libcasper/services/cap_netdb/cap_netdb.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2020 Ryan Moeller <freqlabs at 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_ */
diff --git a/lib/libcasper/services/cap_netdb/tests/Makefile b/lib/libcasper/services/cap_netdb/tests/Makefile
new file mode 100644
index 000000000000..eb7bc45d960d
--- /dev/null
+++ b/lib/libcasper/services/cap_netdb/tests/Makefile
@@ -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>
diff --git a/lib/libcasper/services/cap_netdb/tests/netdb_test.c b/lib/libcasper/services/cap_netdb/tests/netdb_test.c
new file mode 100644
index 000000000000..afe43b575572
--- /dev/null
+++ b/lib/libcasper/services/cap_netdb/tests/netdb_test.c
@@ -0,0 +1,94 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Ryan Moeller <freqlabs at 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());
+}
diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk
index db76fdd0486c..61373dceb4d1 100644
--- a/share/mk/src.libnames.mk
+++ b/share/mk/src.libnames.mk
@@ -107,6 +107,7 @@ _LIBRARIES=	\
 		cap_fileargs \
 		cap_grp \
 		cap_net \
+		cap_netdb \
 		cap_pwd \
 		cap_sysctl \
 		cap_syslog \


More information about the dev-commits-src-all mailing list