summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/hastd/subr.c64
1 files changed, 48 insertions, 16 deletions
diff --git a/sbin/hastd/subr.c b/sbin/hastd/subr.c
index ae6f984..440061e 100644
--- a/sbin/hastd/subr.c
+++ b/sbin/hastd/subr.c
@@ -31,14 +31,15 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#ifdef HAVE_CAPSICUM
-#include <sys/capability.h>
-#endif
#include <sys/param.h>
#include <sys/disk.h>
#include <sys/ioctl.h>
#include <sys/jail.h>
#include <sys/stat.h>
+#ifdef HAVE_CAPSICUM
+#include <sys/capability.h>
+#include <geom/gate/g_gate.h>
+#endif
#include <errno.h>
#include <fcntl.h>
@@ -224,22 +225,53 @@ drop_privs(const struct hast_resource *res)
return (-1);
}
- /*
- * Until capsicum doesn't allow ioctl(2) we cannot use it to sandbox
- * primary and secondary worker processes, as primary uses GGATE
- * ioctls and secondary uses ioctls to handle BIO_DELETE and BIO_FLUSH.
- * For now capsicum is only used to sandbox hastctl.
- */
#ifdef HAVE_CAPSICUM
- if (res == NULL) {
- capsicum = (cap_enter() == 0);
- if (!capsicum) {
- pjdlog_common(LOG_DEBUG, 1, errno,
- "Unable to sandbox using capsicum");
+ capsicum = (cap_enter() == 0);
+ if (!capsicum) {
+ pjdlog_common(LOG_DEBUG, 1, errno,
+ "Unable to sandbox using capsicum");
+ } else if (res != NULL) {
+ static const unsigned long geomcmds[] = {
+ DIOCGDELETE,
+ DIOCGFLUSH
+ };
+
+ PJDLOG_ASSERT(res->hr_role == HAST_ROLE_PRIMARY ||
+ res->hr_role == HAST_ROLE_SECONDARY);
+
+ if (cap_rights_limit(res->hr_localfd,
+ CAP_FLOCK | CAP_IOCTL | CAP_PREAD | CAP_PWRITE) == -1) {
+ pjdlog_errno(LOG_ERR,
+ "Unable to limit capability rights on local descriptor");
+ }
+ if (cap_ioctls_limit(res->hr_localfd, geomcmds,
+ sizeof(geomcmds) / sizeof(geomcmds[0])) == -1) {
+ pjdlog_errno(LOG_ERR,
+ "Unable to limit allowed GEOM ioctls");
}
- } else
+
+ if (res->hr_role == HAST_ROLE_PRIMARY) {
+ static const unsigned long ggatecmds[] = {
+ G_GATE_CMD_MODIFY,
+ G_GATE_CMD_START,
+ G_GATE_CMD_DONE,
+ G_GATE_CMD_DESTROY
+ };
+
+ if (cap_rights_limit(res->hr_ggatefd, CAP_IOCTL) == -1) {
+ pjdlog_errno(LOG_ERR,
+ "Unable to limit capability rights to CAP_IOCTL on ggate descriptor");
+ }
+ if (cap_ioctls_limit(res->hr_ggatefd, ggatecmds,
+ sizeof(ggatecmds) / sizeof(ggatecmds[0])) == -1) {
+ pjdlog_errno(LOG_ERR,
+ "Unable to limit allowed ggate ioctls");
+ }
+ }
+ }
+#else
+ capsicum = false;
#endif
- capsicum = false;
/*
* Better be sure that everything succeeded.
OpenPOWER on IntegriCloud