summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@joyent.com>2015-02-28 06:29:17 +0000
committerRobert Mustacchi <rm@joyent.com>2015-03-04 19:04:12 +0000
commit8ce3da0d5975d90204fdb9c1701caeddb3c4fd8e (patch)
tree0bd73b5877c78d3aec8f47b3106afdaa65b4fb76 /usr/src
parentddad37b43d5105132274139a7555f343237cfd58 (diff)
downloadillumos-joyent-8ce3da0d5975d90204fdb9c1701caeddb3c4fd8e.tar.gz
OS-3960 varpd should drop privs
OS-3973 overlay_target_ioct_list overdoes its copyout
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/varpd/varpd.c77
-rw-r--r--usr/src/uts/common/io/overlay/overlay_target.c2
2 files changed, 58 insertions, 21 deletions
diff --git a/usr/src/cmd/varpd/varpd.c b/usr/src/cmd/varpd/varpd.c
index 6613864639..02e46b4277 100644
--- a/usr/src/cmd/varpd/varpd.c
+++ b/usr/src/cmd/varpd/varpd.c
@@ -57,6 +57,7 @@
#include <sys/wait.h>
#include <unistd.h>
#include <thread.h>
+#include <priv.h>
#define VARPD_EXIT_REQUESTED 0
#define VARPD_EXIT_FATAL 1
@@ -133,19 +134,27 @@ varpd_plugin_walk_cb(varpd_handle_t *vph, const char *name, void *unused)
return (0);
}
-static void
+static int
varpd_dir_setup(void)
{
int fd;
if (mkdir(VARPD_RUNDIR, 0700) != 0) {
if (errno != EEXIST)
- varpd_fatal("failed to create %s", VARPD_RUNDIR);
+ varpd_fatal("failed to create %s: %s", VARPD_RUNDIR,
+ strerror(errno));
}
fd = open(VARPD_RUNDIR, O_RDONLY);
if (fd < 0)
- varpd_fatal("failed to open %s", VARPD_RUNDIR);
+ varpd_fatal("failed to open %s: %s", VARPD_RUNDIR,
+ strerror(errno));
+
+ if (fchown(fd, UID_NETADM, GID_NETADM) != 0)
+ varpd_fatal("failed to chown %s: %s\n", VARPD_RUNDIR,
+ strerror(errno));
+
+ return (fd);
}
/*
@@ -160,9 +169,10 @@ varpd_fd_setup(void)
closefrom(STDERR_FILENO + 1);
dupfd = open(_PATH_DEVNULL, O_RDONLY);
if (dupfd < 0)
- varpd_fatal("failed to open %s", _PATH_DEVNULL);
+ varpd_fatal("failed to open %s: %s", _PATH_DEVNULL,
+ strerror(errno));
if (dup2(dupfd, STDIN_FILENO) == -1)
- varpd_fatal("failed to dup out stdin");
+ varpd_fatal("failed to dup out stdin: %s", strerror(errno));
}
/*
@@ -171,13 +181,14 @@ varpd_fd_setup(void)
* before we say that we're good to go.
*/
static int
-varpd_daemonize(void)
+varpd_daemonize(int dirfd)
{
char path[PATH_MAX];
struct rlimit rlim;
sigset_t set, oset;
int estatus, pfds[2];
pid_t child;
+ priv_set_t *pset;
/*
* Set a per-process core path to be inside of /var/run/varpd. Make sure
@@ -202,19 +213,9 @@ varpd_daemonize(void)
/*
* chdir /var/run/varpd
*/
- if (chdir(VARPD_RUNDIR) != 0)
+ if (fchdir(dirfd) != 0)
varpd_fatal("failed to chdir to %s", VARPD_RUNDIR);
- /*
- * Drop privileges here some day soon.
- *
- * We should make sure we keep around PRIV_NET_PRIVADDR and
- * PRIV_SYS_DLCONFIG, but drop everything else; however, keep basic
- * privs and have our child drop them.
- *
- * We should also run as netadm:netadm and drop all of our groups.
- */
-
/*
* At this point block all signals going in so we don't have the parent
@@ -249,6 +250,42 @@ varpd_daemonize(void)
_exit(VARPD_EXIT_FATAL);
}
+ /*
+ * Drop privileges here.
+ *
+ * We should make sure we keep around PRIV_NET_PRIVADDR and
+ * PRIV_SYS_DLCONFIG, but drop everything else; however, keep basic
+ * privs and have our child drop them.
+ *
+ * We should also run as netadm:netadm and drop all of our groups.
+ */
+ if (setgroups(0, NULL) != 0)
+ abort();
+ if (setgid(GID_NETADM) == -1 || seteuid(UID_NETADM) == -1)
+ abort();
+ if ((pset = priv_allocset()) == NULL)
+ abort();
+ priv_basicset(pset);
+ if (priv_delset(pset, PRIV_PROC_EXEC) == -1 ||
+ priv_delset(pset, PRIV_PROC_INFO) == -1 ||
+ priv_delset(pset, PRIV_PROC_FORK) == -1 ||
+ priv_delset(pset, PRIV_PROC_SESSION) == -1 ||
+ priv_delset(pset, PRIV_FILE_LINK_ANY) == -1 ||
+ priv_addset(pset, PRIV_SYS_DL_CONFIG) == -1 ||
+ priv_addset(pset, PRIV_NET_PRIVADDR) == -1) {
+ abort();
+ }
+ /*
+ * Remove privs from the permitted set. That will cause them to be
+ * removed from the effective set. We want to make sure that in the case
+ * of a vulnerability, something can't get back in here and wreak more
+ * havoc.
+ */
+ if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) == -1)
+ abort();
+
+ priv_freeset(pset);
+
if (close(pfds[0]) != 0)
abort();
if (setsid() == -1)
@@ -303,7 +340,7 @@ varpd_cleanup(void)
int
main(int argc, char *argv[])
{
- int err, c, dfd, i;
+ int err, c, dirfd, dfd, i;
const char *doorpath = VARPD_DEFAULT_DOOR;
sigset_t set;
struct sigaction act;
@@ -353,11 +390,11 @@ main(int argc, char *argv[])
}
}
- varpd_dir_setup();
+ dirfd = varpd_dir_setup();
(void) libvarpd_plugin_walk(varpd_handle, varpd_plugin_walk_cb, NULL);
- dfd = varpd_daemonize();
+ dfd = varpd_daemonize(dirfd);
/*
* Now that we're in the child, go ahead and load all of our plug-ins.
diff --git a/usr/src/uts/common/io/overlay/overlay_target.c b/usr/src/uts/common/io/overlay/overlay_target.c
index f3cf91aede..17d2cb8c91 100644
--- a/usr/src/uts/common/io/overlay/overlay_target.c
+++ b/usr/src/uts/common/io/overlay/overlay_target.c
@@ -1044,7 +1044,7 @@ overlay_target_list_copyout(void *ubuf, void *buf, size_t bufsize, int flags)
if (ddi_copyout(otl->otli_ents,
(void *)((uintptr_t)ubuf +
offsetof(overlay_targ_list_t, otl_ents)),
- sizeof (uint32_t *) * otl->otli_nents,
+ sizeof (uint32_t) * otl->otli_nents,
flags & FKIOCTL) != 0)
return (EFAULT);
}