Page MenuHomeFreeBSD

D15938.1774757229.diff
No OneTemporary

Size
13 KB
Referenced Files
None
Subscribers
None

D15938.1774757229.diff

Index: lib/libcasper/libcasper/libcasper.3
===================================================================
--- lib/libcasper/libcasper/libcasper.3
+++ lib/libcasper/libcasper/libcasper.3
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 6, 2018
+.Dd June 20, 2018
.Dt LIBCASPER 3
.Os
.Sh NAME
@@ -263,6 +263,7 @@
.Xr cap_grp 3 ,
.Xr cap_pwd 3 ,
.Xr cap_ranodm 3 ,
+.Xr cap_signal 3 ,
.Xr cap_sysctl 3 ,
.Xr cap_syslog 3 ,
.Xr capsicum 4 ,
Index: lib/libcasper/services/Makefile
===================================================================
--- lib/libcasper/services/Makefile
+++ lib/libcasper/services/Makefile
@@ -6,6 +6,7 @@
SUBDIR+= cap_grp
SUBDIR+= cap_pwd
SUBDIR+= cap_random
+SUBDIR+= cap_signal
SUBDIR+= cap_sysctl
SUBDIR+= cap_syslog
Index: lib/libcasper/services/cap_signal/Makefile
===================================================================
--- /dev/null
+++ lib/libcasper/services/cap_signal/Makefile
@@ -0,0 +1,31 @@
+# $FreeBSD$
+
+SHLIBDIR?= /lib/casper
+
+.include <src.opts.mk>
+
+PACKAGE=libcasper
+
+SHLIB_MAJOR= 1
+INCSDIR?= ${INCLUDEDIR}/casper
+
+.if ${MK_CASPER} != "no"
+SHLIB= cap_signal
+
+SRCS= cap_signal.c
+.endif
+
+INCS= cap_signal.h
+
+LIBADD= nv
+
+CFLAGS+=-I${.CURDIR}
+
+MAN+= cap_signal.3
+
+MLINKS+=cap_signal.3 libcap_signal.3
+MLINKS+=cap_signal.3 cap_kill.3
+MLINKS+=cap_signal.3 cap_signal_limit_pid.3
+MLINKS+=cap_signal.3 cap_signal_limit_sig.3
+
+.include <bsd.lib.mk>
Index: lib/libcasper/services/cap_signal/cap_signal.h
===================================================================
--- /dev/null
+++ lib/libcasper/services/cap_signal/cap_signal.h
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2018 Mariusz Zaborski <oshogbo@FreeBSD.org>
+ * All rights reserved.
+ *
+ * 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_SIGNAL_H_
+#define _CAP_SIGNAL_H_
+
+#include <sys/types.h>
+
+#include <signal.h>
+
+#ifdef HAVE_CASPER
+#define WITH_CASPER
+#endif
+
+#ifdef WITH_CASPER
+int cap_kill(cap_channel_t *chan, pid_t pid, int sig);
+
+int cap_signal_limit_pid(cap_channel_t *chan, const pid_t *pids, size_t npids);
+int cap_signal_limit_signals(cap_channel_t *chan, const int *sigs, size_t nsig);
+#else
+#define cap_kill(chan, pid, sig) kill(pid, sig)
+
+#define cap_signal_limit_pid(chan, pids, npids) (0)
+#define cap_signal_limit_signals(chan, sigs, nsig) (0)
+#endif
+
+#endif /* !_CAP_SIGNAL_H_ */
Index: lib/libcasper/services/cap_signal/cap_signal.3
===================================================================
--- /dev/null
+++ lib/libcasper/services/cap_signal/cap_signal.3
@@ -0,0 +1,125 @@
+.\" Copyright (c) 2018 Mariusz Zaborski <oshogbo@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" 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 June 20, 2018
+.Dt CAP_SIGNAL 3
+.Os
+.Sh NAME
+.Nm cap_kill ,
+.Nm cap_signal_limit_pid ,
+.Nm cap_signal_limit_signals
+.Nd "library for signal operations in capability mode"
+.Sh LIBRARY
+.Lb libcap_signal
+.Sh SYNOPSIS
+.In libcasper.h
+.In casper/cap_signal.h
+.Ft int
+.Fn cap_kill "cap_channel_t *chan" "pid_t pid" "int sig"
+.Ft int
+.Fn cap_signal_limit_pid "cap_channel_t *chan" "const pid_t *pids" "size_t npids"
+.Ft int
+.Fn cap_signal_limit_signals "cap_channel_t *chan" "const int *sigs" "size_t nsig"
+.Sh DESCRIPTION
+The function
+.Fn cap_kill
+is equivalent to
+.Xr kill 2
+except that the connection to the
+.Nm system.signal
+service needs to be provided.
+.Pp
+The
+.Fn cap_signal_limit_pid
+function limits a list of process to which signals can be sent.
+.Pp
+The
+.Fn cap_signal_limit_signals
+function limits signals which can be sent.
+.Sh EXAMPLES
+The following example first create a process, opens a capability to Casper and
+then uses this capability to create the
+.Nm system.signal
+casper service and uses it to send a signal SIGABRT to the process.
+.Bd -literal
+cap_channel_t *capcas, *capsignal;
+pid_t pid;
+int signals[] = { SIGABRT };
+
+/* Spawn a child to which we will send a signal */
+pid = fork();
+if (pid == -1) {
+ return (1);
+} else if (pid == 0) {
+ /* Wait for a moment. */
+ for (;;) {
+ sleep(1);
+ }
+}
+
+/* Open capability to Casper. */
+capcas = cap_init();
+if (capcas == NULL)
+ err(1, "Unable to contact Casper");
+
+/* Enter capability mode sandbox. */
+if (cap_enter() < 0 && errno != ENOSYS)
+ err(1, "Unable to enter capability mode");
+
+/* Use Casper capability to create capability to the system.signal service. */
+capsignal = cap_service_open(capcas, "system.signal");
+if (capsignal == NULL)
+ err(1, "Unable to open system.signal service");
+
+/* Close Casper capability, we don't need it anymore. */
+cap_close(capcas);
+
+/* Limit service to one single process. */
+if (cap_signal_limit_pid(capsignal, &pid, 1) < 0)
+ err(1, "Unable to limit access to system.signal service");
+
+/* Limit service to one field as we only need name of the user. */
+if (cap_signal_limit_signals(capsignal, signals, nitems(signals)) < 0)
+ err(1, "Unable to limit access to system.signal service");
+
+if (cap_kill(capsignal, pid, SIGABRT) < 0)
+ err(1, "Unable to send signal");
+
+printf("The process %d recived SIGABORT.\n", pid);
+.Ed
+.Sh SEE ALSO
+.Xr cap_enter 2 ,
+.Xr errno 2 ,
+.Xr fork 2,
+.Xr kill 2 ,
+.Xr err 3 ,
+.Xr capsicum 4 ,
+.Xr nv 9
+.Sh AUTHORS
+The
+.Nm cap_signal
+service was implemented by
+.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org .
Index: lib/libcasper/services/cap_signal/cap_signal.c
===================================================================
--- /dev/null
+++ lib/libcasper/services/cap_signal/cap_signal.c
@@ -0,0 +1,215 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2018 Mariusz Zaborski <oshogbo@FreeBSD.org>
+ * All rights reserved.
+ *
+ * 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/types.h>
+#include <sys/cnv.h>
+#include <sys/nv.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <libcasper.h>
+#include <libcasper_service.h>
+
+#include "cap_signal.h"
+
+int
+cap_kill(cap_channel_t *chan, pid_t pid, int sig)
+{
+ nvlist_t *nvl;
+ int err;
+
+ nvl = nvlist_create(0);
+ nvlist_add_string(nvl, "cmd", "kill");
+ nvlist_add_number(nvl, "pid", pid);
+ nvlist_add_number(nvl, "sig", sig);
+
+ nvl = cap_xfer_nvlist(chan, nvl);
+ if (nvl == NULL)
+ return (-1);
+
+ err = nvlist_get_number(nvl, "error");
+ nvlist_destroy(nvl);
+ if (err != 0) {
+ errno = err;
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+cap_signal_limit_pids(cap_channel_t *chan, const pid_t *pids, size_t npids)
+{
+ nvlist_t *limits;
+ size_t i;
+
+ if (cap_limit_get(chan, &limits) < 0)
+ return (-1);
+
+ if (limits == NULL)
+ limits = nvlist_create(0);
+ else if (nvlist_exists_nvlist(limits, "pids"))
+ nvlist_free_nvlist(limits, "pids");
+
+ for (i = 0; i < npids; i++)
+ nvlist_append_number_array(limits, "pids", pids[i]);
+
+ return (cap_limit_set(chan, limits));
+}
+
+int
+cap_signal_limit_signals(cap_channel_t *chan, const int *sigs, size_t nsig)
+{
+ nvlist_t *limits;
+ size_t i;
+
+ if (cap_limit_get(chan, &limits) < 0)
+ return (-1);
+
+ if (limits == NULL)
+ limits = nvlist_create(0);
+ else if (nvlist_exists_nvlist(limits, "sigs"))
+ nvlist_free_nvlist(limits, "sigs");
+
+ for (i = 0; i < nsig; i++)
+ nvlist_append_number_array(limits, "sigs", sigs[i]);
+
+ return (cap_limit_set(chan, limits));
+}
+
+/*
+ * Service functions.
+ */
+static bool
+signal_allowed(const nvlist_t *limits, const char *name, int64_t number)
+{
+ const int64_t *numbers;
+ size_t nitems, i;
+
+ if (limits == NULL)
+ return (true);
+
+ if (!nvlist_exists_number_array(limits, name))
+ return (true);
+
+ numbers = nvlist_get_number_array(limits, name, &nitems);
+ for (i = 0; i < nitems; i++) {
+ if (number == numbers[i])
+ return (true);
+ }
+
+ return (false);
+}
+
+static bool
+signal_allowed_pid(const nvlist_t *limits, pid_t pid)
+{
+
+ return (signal_allowed(limits, "pids", pid));
+}
+
+static bool
+signal_allowed_sig(const nvlist_t *limits, int sig)
+{
+
+ return (signal_allowed(limits, "sigs", sig));
+}
+
+static int
+signal_limit(const nvlist_t *oldlimits, const nvlist_t *newlimits)
+{
+ const char *name;
+ const int64_t *values;
+ size_t nitems, i;
+ int nvtype;
+ void *cookie;
+
+ /* XXX: If needed we can optimize the limits using qsort. */
+ if (oldlimits == NULL) {
+ return (0);
+ }
+
+ cookie = NULL;
+ while ((name = nvlist_next(newlimits, &nvtype, &cookie)) != NULL) {
+ if (nvtype != NV_TYPE_NUMBER_ARRAY)
+ return (EINVAL);
+
+ if (strcmp(name, "pids") != 0 && strcmp(name, "sigs") != 0)
+ return (EINVAL);
+
+ values = cnvlist_get_number_array(cookie, &nitems);
+ for (i = 0; i < nitems; i++) {
+ if (!signal_allowed(oldlimits, name, values[i])) {
+ return (ENOTCAPABLE);
+ }
+ }
+ }
+
+ return (0);
+}
+
+static int
+signal_kill(const nvlist_t *limits, const nvlist_t *nvlin)
+{
+ pid_t pid;
+ int sig;
+
+ pid = nvlist_get_number(nvlin, "pid");
+ sig = nvlist_get_number(nvlin, "sig");
+
+ if (!signal_allowed_pid(limits, pid))
+ return (ENOTCAPABLE);
+ if (!signal_allowed_sig(limits, sig))
+ return (ENOTCAPABLE);
+
+ if (kill(pid, sig) != 0)
+ return (errno);
+
+ return (0);
+}
+
+static int
+signal_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin,
+ nvlist_t *nvlout __unused)
+{
+
+ if (strcmp(cmd, "kill") != 0)
+ return (ENOTCAPABLE);
+
+ return (signal_kill(limits, nvlin));
+}
+
+CREATE_SERVICE("system.signal", signal_limit, signal_command, 0)
Index: share/mk/src.libnames.mk
===================================================================
--- share/mk/src.libnames.mk
+++ share/mk/src.libnames.mk
@@ -77,6 +77,7 @@
cap_grp \
cap_pwd \
cap_random \
+ cap_signal \
cap_sysctl \
cap_syslog \
com_err \
@@ -239,6 +240,7 @@
_DP_cap_grp= nv
_DP_cap_pwd= nv
_DP_cap_random= nv
+_DP_cap_signal= nv
_DP_cap_sysctl= nv
_DP_cap_syslog= nv
.if ${MK_OFED} != "no"
@@ -540,6 +542,7 @@
LIBCAP_GRPDIR= ${OBJTOP}/lib/libcasper/services/cap_grp
LIBCAP_PWDDIR= ${OBJTOP}/lib/libcasper/services/cap_pwd
LIBCAP_RANDOMDIR= ${OBJTOP}/lib/libcasper/services/cap_random
+LIBCAP_SINGALDIR= ${OBJTOP}/lib/libcasper/services/cap_signal
LIBCAP_SYSCTLDIR= ${OBJTOP}/lib/libcasper/services/cap_sysctl
LIBCAP_SYSLOGDIR= ${OBJTOP}/lib/libcasper/services/cap_syslog
LIBBSDXMLDIR= ${OBJTOP}/lib/libexpat

File Metadata

Mime Type
text/plain
Expires
Sun, Mar 29, 4:07 AM (15 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28221509
Default Alt Text
D15938.1774757229.diff (13 KB)

Event Timeline