diff options
author | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2011-05-14 17:02:03 +0000 |
---|---|---|
committer | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2011-05-14 17:02:03 +0000 |
commit | 0cddb12ffd5d10e7805ea269afea0f5a41671fcf (patch) | |
tree | 4582135bbbedab14d50df3c3ec3b7ec8b4f47185 | |
parent | bcc9f32110ae7b8b1094c010ceb188c00656afda (diff) | |
download | src-0cddb12ffd5d10e7805ea269afea0f5a41671fcf.tar.gz src-0cddb12ffd5d10e7805ea269afea0f5a41671fcf.zip |
Currently we are unable to use capsicum for the primary worker process,
because we need to do ioctl(2)s, which are not permitted in the capability
mode. What we do now is to chroot(2) to /var/empty, which restricts access
to file system name space and we drop privileges to hast user and hast
group.
This still allows to access to other name spaces, like list of processes,
network and sysvipc.
To address that, use jail(2) instead of chroot(2). Using jail(2) will restrict
access to process table, network (we use ip-less jails) and sysvipc (if
security.jail.sysvipc_allowed is turned off). This provides much better
separation.
MFC after: 1 week
Notes
Notes:
svn path=/head/; revision=221899
-rw-r--r-- | sbin/hastctl/hastctl.c | 2 | ||||
-rw-r--r-- | sbin/hastd/primary.c | 2 | ||||
-rw-r--r-- | sbin/hastd/secondary.c | 2 | ||||
-rw-r--r-- | sbin/hastd/subr.c | 58 | ||||
-rw-r--r-- | sbin/hastd/subr.h | 2 |
5 files changed, 44 insertions, 22 deletions
diff --git a/sbin/hastctl/hastctl.c b/sbin/hastctl/hastctl.c index cf692ce95f52..c4cd6a4b91c1 100644 --- a/sbin/hastctl/hastctl.c +++ b/sbin/hastctl/hastctl.c @@ -480,7 +480,7 @@ main(int argc, char *argv[]) cfg->hc_controladdr); } - if (drop_privs(true) != 0) + if (drop_privs(NULL) != 0) exit(EX_CONFIG); /* Send the command to the server... */ diff --git a/sbin/hastd/primary.c b/sbin/hastd/primary.c index 3363fcbb051a..d8eb664740cb 100644 --- a/sbin/hastd/primary.c +++ b/sbin/hastd/primary.c @@ -904,7 +904,7 @@ hastd_primary(struct hast_resource *res) init_ggate(res); init_environment(res); - if (drop_privs(true) != 0) { + if (drop_privs(res) != 0) { cleanup(res); exit(EX_CONFIG); } diff --git a/sbin/hastd/secondary.c b/sbin/hastd/secondary.c index 5d7df68981fe..58b8f696edf0 100644 --- a/sbin/hastd/secondary.c +++ b/sbin/hastd/secondary.c @@ -436,7 +436,7 @@ hastd_secondary(struct hast_resource *res, struct nv *nvin) init_local(res); init_environment(); - if (drop_privs(true) != 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 ea84e2a9da92..29f33e7d32c4 100644 --- a/sbin/hastd/subr.c +++ b/sbin/hastd/subr.c @@ -32,9 +32,10 @@ __FBSDID("$FreeBSD$"); #include <sys/capability.h> -#include <sys/types.h> +#include <sys/param.h> #include <sys/disk.h> #include <sys/ioctl.h> +#include <sys/jail.h> #include <sys/stat.h> #include <errno.h> @@ -147,13 +148,15 @@ role2str(int role) } int -drop_privs(bool usecapsicum) +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; + bool capsicum, jailed; /* * According to getpwnam(3) we have to clear errno before calling the @@ -173,10 +176,34 @@ drop_privs(bool usecapsicum) 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; @@ -197,15 +224,10 @@ drop_privs(bool usecapsicum) return (-1); } - capsicum = false; - if (usecapsicum) { - if (cap_enter() == 0) { - capsicum = true; - } else { - pjdlog_errno(LOG_WARNING, - "Unable to sandbox using capsicum"); - } - } + if (res == NULL || res->hr_role != HAST_ROLE_PRIMARY) + capsicum = (cap_enter() == 0); + else + capsicum = false; /* * Better be sure that everything succeeded. @@ -223,8 +245,8 @@ drop_privs(bool usecapsicum) PJDLOG_VERIFY(gidset[0] == pw->pw_gid); pjdlog_debug(1, - "Privileges successfully dropped using %schroot+setgid+setuid.", - capsicum ? "capsicum+" : ""); + "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 c04a242c5fe4..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(bool usecapsicum); +int drop_privs(struct hast_resource *res); #endif /* !_SUBR_H_ */ |