aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/hastctl/hastctl.c3
-rw-r--r--sbin/hastd/primary.c2
-rw-r--r--sbin/hastd/secondary.c2
-rw-r--r--sbin/hastd/subr.c65
-rw-r--r--sbin/hastd/subr.h2
5 files changed, 63 insertions, 11 deletions
diff --git a/sbin/hastctl/hastctl.c b/sbin/hastctl/hastctl.c
index 9cfef860a361..2f8a6eb8dff7 100644
--- a/sbin/hastctl/hastctl.c
+++ b/sbin/hastctl/hastctl.c
@@ -491,9 +491,8 @@ main(int argc, char *argv[])
cfg->hc_controladdr);
}
- if (drop_privs() != 0)
+ if (drop_privs(NULL) != 0)
exit(EX_CONFIG);
- pjdlog_debug(1, "Privileges successfully dropped.");
/* Send the command to the server... */
if (hast_proto_send(NULL, controlconn, nv, NULL, 0) < 0) {
diff --git a/sbin/hastd/primary.c b/sbin/hastd/primary.c
index 95c1f11f8a77..af0f35375669 100644
--- a/sbin/hastd/primary.c
+++ b/sbin/hastd/primary.c
@@ -906,7 +906,7 @@ hastd_primary(struct hast_resource *res)
init_ggate(res);
init_environment(res);
- if (drop_privs() != 0) {
+ if (drop_privs(res) != 0) {
cleanup(res);
exit(EX_CONFIG);
}
diff --git a/sbin/hastd/secondary.c b/sbin/hastd/secondary.c
index 5a8c90bf7a79..707e44d6c183 100644
--- a/sbin/hastd/secondary.c
+++ b/sbin/hastd/secondary.c
@@ -440,7 +440,7 @@ hastd_secondary(struct hast_resource *res, struct nv *nvin)
init_local(res);
init_environment();
- if (drop_privs() != 0)
+ if (drop_privs(res) != 0)
exit(EX_CONFIG);
pjdlog_info("Privileges successfully dropped.");
diff --git a/sbin/hastd/subr.c b/sbin/hastd/subr.c
index 3ac28a5a347f..89ffda0fe2f3 100644
--- a/sbin/hastd/subr.c
+++ b/sbin/hastd/subr.c
@@ -31,15 +31,20 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
+#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>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
@@ -145,12 +150,15 @@ role2str(int role)
}
int
-drop_privs(void)
+drop_privs(struct hast_resource *res)
{
+ char jailhost[sizeof(res->hr_name) * 2];
+ struct jail jailst;
struct passwd *pw;
uid_t ruid, euid, suid;
gid_t rgid, egid, sgid;
gid_t gidset[1];
+ bool capsicum, jailed;
/*
* According to getpwnam(3) we have to clear errno before calling the
@@ -170,10 +178,34 @@ drop_privs(void)
return (-1);
}
}
- if (chroot(pw->pw_dir) == -1) {
- KEEP_ERRNO(pjdlog_errno(LOG_ERR,
- "Unable to change root directory to %s", pw->pw_dir));
- return (-1);
+
+ bzero(&jailst, sizeof(jailst));
+ jailst.version = JAIL_API_VERSION;
+ jailst.path = pw->pw_dir;
+ if (res == NULL) {
+ (void)snprintf(jailhost, sizeof(jailhost), "hastctl");
+ } else {
+ (void)snprintf(jailhost, sizeof(jailhost), "hastd: %s (%s)",
+ res->hr_name, role2str(res->hr_role));
+ }
+ jailst.hostname = jailhost;
+ jailst.jailname = NULL;
+ jailst.ip4s = 0;
+ jailst.ip4 = NULL;
+ jailst.ip6s = 0;
+ jailst.ip6 = NULL;
+ if (jail(&jailst) >= 0) {
+ jailed = true;
+ } else {
+ jailed = false;
+ pjdlog_errno(LOG_WARNING,
+ "Unable to jail to directory to %s", pw->pw_dir);
+ if (chroot(pw->pw_dir) == -1) {
+ KEEP_ERRNO(pjdlog_errno(LOG_ERR,
+ "Unable to change root directory to %s",
+ pw->pw_dir));
+ return (-1);
+ }
}
PJDLOG_VERIFY(chdir("/") == 0);
gidset[0] = pw->pw_gid;
@@ -195,6 +227,23 @@ drop_privs(void)
}
/*
+ * 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");
+ }
+ } else
+#endif
+ capsicum = false;
+
+ /*
* Better be sure that everything succeeded.
*/
PJDLOG_VERIFY(getresuid(&ruid, &euid, &suid) == 0);
@@ -209,5 +258,9 @@ drop_privs(void)
PJDLOG_VERIFY(getgroups(1, gidset) == 1);
PJDLOG_VERIFY(gidset[0] == pw->pw_gid);
+ pjdlog_debug(1,
+ "Privileges successfully dropped using %s%s+setgid+setuid.",
+ capsicum ? "capsicum+" : "", jailed ? "jail" : "chroot");
+
return (0);
}
diff --git a/sbin/hastd/subr.h b/sbin/hastd/subr.h
index 30304b240964..e76930aa0f6a 100644
--- a/sbin/hastd/subr.h
+++ b/sbin/hastd/subr.h
@@ -51,6 +51,6 @@ int snprlcat(char *str, size_t size, const char *fmt, ...);
int provinfo(struct hast_resource *res, bool dowrite);
const char *role2str(int role);
-int drop_privs(void);
+int drop_privs(struct hast_resource *res);
#endif /* !_SUBR_H_ */