From owner-dev-commits-src-main@freebsd.org Sat Jun 5 12:37:10 2021 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 175CD64275C; Sat, 5 Jun 2021 12:37:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4FxzfZ0C1Wz4tjG; Sat, 5 Jun 2021 12:37:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E343E10B23; Sat, 5 Jun 2021 12:37:09 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 155Cb9Oo089502; Sat, 5 Jun 2021 12:37:09 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 155Cb9jb089501; Sat, 5 Jun 2021 12:37:09 GMT (envelope-from git) Date: Sat, 5 Jun 2021 12:37:09 GMT Message-Id: <202106051237.155Cb9jb089501@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Ryan Moeller Subject: git: 94dc57159532 - main - libcasper: Create a minimal cap_netdb service MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: freqlabs X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 94dc57159532d7bbf94d109e79fd202a57150562 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for the main branch of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 05 Jun 2021 12:37:10 -0000 The branch main has been updated by freqlabs: URL: https://cgit.FreeBSD.org/src/commit/?id=94dc57159532d7bbf94d109e79fd202a57150562 commit 94dc57159532d7bbf94d109e79fd202a57150562 Author: Ryan Moeller AuthorDate: 2021-03-26 19:40:19 +0000 Commit: Ryan Moeller 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 + +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 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 +.\" +.\" 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 + * + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 + * + * 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 + +#include + +#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 + +ATF_TESTS_C= netdb_test + +.if ${MK_CASPER} != "no" +LIBADD+= casper +LIBADD+= cap_netdb +CFLAGS+=-DWITH_CASPER +.endif +LIBADD+= nv + +.include 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 + * + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +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 \