diff options
| -rw-r--r-- | sbin/hastctl/hastctl.c | 3 | ||||
| -rw-r--r-- | sbin/hastd/primary.c | 2 | ||||
| -rw-r--r-- | sbin/hastd/secondary.c | 2 | ||||
| -rw-r--r-- | sbin/hastd/subr.c | 65 | ||||
| -rw-r--r-- | sbin/hastd/subr.h | 2 |
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_ */ |
