aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Moeller <freqlabs@FreeBSD.org>2021-03-26 19:40:19 +0000
committerRyan Moeller <freqlabs@FreeBSD.org>2021-06-05 12:36:53 +0000
commit94dc57159532d7bbf94d109e79fd202a57150562 (patch)
tree704dd64b6f709f1daa86d4adc7e5c99470373ba0
parent1970d69303946116e6c88ab5b903ae4b65efddc5 (diff)
downloadsrc-94dc57159532.tar.gz
src-94dc57159532.zip
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
-rw-r--r--lib/libcasper/services/Makefile1
-rw-r--r--lib/libcasper/services/cap_netdb/Makefile32
-rw-r--r--lib/libcasper/services/cap_netdb/cap_netdb.390
-rw-r--r--lib/libcasper/services/cap_netdb/cap_netdb.c155
-rw-r--r--lib/libcasper/services/cap_netdb/cap_netdb.h49
-rw-r--r--lib/libcasper/services/cap_netdb/tests/Makefile14
-rw-r--r--lib/libcasper/services/cap_netdb/tests/netdb_test.c94
-rw-r--r--share/mk/src.libnames.mk1
8 files changed, 436 insertions, 0 deletions
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@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 .
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@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@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@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 \