Call for testing: OpenSSH 7.2
Darren Tucker
dtucker at zip.com.au
Thu Feb 18 12:41:11 AEDT 2016
On Wed, Feb 17, 2016 at 04:20:36PM -0800, Alex Wilson wrote:
[...]
> That patch looks nicer to me, too. It compiles on S10 and Illumos, but I
> haven't fully tested it yet (the S10 box I found currently has a broken
> OpenSSL which I'm trying to figure out)
>
> For older S10 I've also had to add this patch (below), since it seems
> PRIV_NET_ACCESS is also a newer addition (it came in sometime in the
> osol era apparently)
[...]
> +# if defined(PRIV_NET_ACCESS)
> + if (priv_delset(npset, PRIV_NET_ACCESS) != 0)
> + fatal("priv_delset: %s", strerror(errno));
> +# endif
Since this is logically part of the "delete these privs" code above, I
actually prefer inlining these.
I also changed solaris_basic_privset to return NULL on failure which
allows sandbox failures to be non-fatal (matching current behaviour;
I'm not sure if that's sensible or not). Diff is untested.
I considered changing solaris_basic_privset to
solaris_restricted_privset and doing the priv removals in common code
there. This is less overall code, but it means the set of privileges in
effect is not immediately obvious so I'm not sure that's a win. Maybe
something for later (ie after release :-) consideration.
diff --git a/configure.ac b/configure.ac
index b4c0aaa..d910f53 100644
--- a/configure.ac
+++ b/configure.ac
@@ -898,6 +898,7 @@ mips-sony-bsd|mips-sony-newsos4)
fi
AC_CHECK_FUNC([setppriv],
[ AC_CHECK_HEADERS([priv.h], [
+ AC_CHECK_FUNCS([priv_basicset])
SOLARIS_PRIVS="yes"
])
])
diff --git a/openbsd-compat/port-solaris.c b/openbsd-compat/port-solaris.c
index 962cd16..e36e412 100644
--- a/openbsd-compat/port-solaris.c
+++ b/openbsd-compat/port-solaris.c
@@ -233,6 +233,26 @@ solaris_set_default_project(struct passwd *pw)
# include <priv.h>
# endif
+priv_set_t *
+solaris_basic_privset(void)
+{
+ priv_set_t *pset;
+
+#ifdef HAVE_PRIV_BASICSET
+ if ((pset = priv_allocset()) == NULL) {
+ error("priv_allocset: %s", strerror(errno));
+ return NULL;
+ }
+ priv_basicset(pset);
+#else
+ if ((pset = priv_str_to_set("basic", ",", NULL)) == NULL) {
+ error("priv_str_to_set: %s", strerror(errno));
+ return NULL;
+ }
+#endif
+ return pset;
+}
+
void
solaris_drop_privs_pinfo_net_fork_exec(void)
{
@@ -254,11 +274,10 @@ solaris_drop_privs_pinfo_net_fork_exec(void)
* etc etc).
*/
- if ((pset = priv_allocset()) == NULL ||
- (npset = priv_allocset()) == NULL)
+ if ((pset = priv_allocset()) == NULL)
fatal("priv_allocset: %s", strerror(errno));
-
- priv_basicset(npset);
+ if ((npset = solaris_basic_privset()) == NULL)
+ fatal("solaris_basic_privset: %s", strerror(errno));
if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 ||
priv_addset(npset, PRIV_FILE_DAC_READ) != 0 ||
@@ -268,7 +287,9 @@ solaris_drop_privs_pinfo_net_fork_exec(void)
fatal("priv_addset: %s", strerror(errno));
if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 ||
+#ifdef PRIV_NET_ACCESS
priv_delset(npset, PRIV_NET_ACCESS) != 0 ||
+#endif
priv_delset(npset, PRIV_PROC_EXEC) != 0 ||
priv_delset(npset, PRIV_PROC_FORK) != 0 ||
priv_delset(npset, PRIV_PROC_INFO) != 0 ||
@@ -294,14 +315,14 @@ solaris_drop_privs_root_pinfo_net(void)
{
priv_set_t *pset = NULL;
- if ((pset = priv_allocset()) == NULL)
- fatal("priv_allocset: %s", strerror(errno));
-
/* Start with "basic" and drop everything we don't need. */
- priv_basicset(pset);
+ if ((pset = solaris_basic_privset()) == NULL)
+ fatal("solaris_basic_privset: %s", strerror(errno));
if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
+#ifdef PRIV_NET_ACCESS
priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
+#endif
priv_delset(pset, PRIV_PROC_INFO) != 0 ||
priv_delset(pset, PRIV_PROC_SESSION) != 0)
fatal("priv_delset: %s", strerror(errno));
@@ -319,14 +340,15 @@ solaris_drop_privs_root_pinfo_net_exec(void)
{
priv_set_t *pset = NULL;
- if ((pset = priv_allocset()) == NULL)
- fatal("priv_allocset: %s", strerror(errno));
/* Start with "basic" and drop everything we don't need. */
- priv_basicset(pset);
+ if ((pset = solaris_basic_privset()) == NULL)
+ fatal("solaris_basic_privset: %s", strerror(errno));
if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 ||
+#ifdef PRIV_NET_ACCESS
priv_delset(pset, PRIV_NET_ACCESS) != 0 ||
+#endif
priv_delset(pset, PRIV_PROC_EXEC) != 0 ||
priv_delset(pset, PRIV_PROC_INFO) != 0 ||
priv_delset(pset, PRIV_PROC_SESSION) != 0)
diff --git a/openbsd-compat/port-solaris.h b/openbsd-compat/port-solaris.h
index b077e18..3a41ea8 100644
--- a/openbsd-compat/port-solaris.h
+++ b/openbsd-compat/port-solaris.h
@@ -26,8 +26,11 @@ void solaris_contract_pre_fork(void);
void solaris_contract_post_fork_child(void);
void solaris_contract_post_fork_parent(pid_t pid);
void solaris_set_default_project(struct passwd *);
+# ifdef USE_SOLARIS_PRIVS
+priv_set_t *solaris_basic_privset(void);
void solaris_drop_privs_pinfo_net_fork_exec(void);
void solaris_drop_privs_root_pinfo_net(void);
void solaris_drop_privs_root_pinfo_net_exec(void);
+# endif /* USE_SOLARIS_PRIVS */
#endif
diff --git a/sandbox-solaris.c b/sandbox-solaris.c
index 98714e1..343a010 100644
--- a/sandbox-solaris.c
+++ b/sandbox-solaris.c
@@ -48,19 +48,20 @@ ssh_sandbox_init(struct monitor *monitor)
struct ssh_sandbox *box = NULL;
box = xcalloc(1, sizeof(*box));
- box->pset = priv_allocset();
+
+ /* Start with "basic" and drop everything we don't need. */
+ box->pset = solaris_basic_privset();
if (box->pset == NULL) {
free(box);
return NULL;
}
- /* Start with "basic" and drop everything we don't need. */
- priv_basicset(box->pset);
-
/* Drop everything except the ability to use already-opened files */
if (priv_delset(box->pset, PRIV_FILE_LINK_ANY) != 0 ||
+#ifdef PRIV_NET_ACCESS
priv_delset(box->pset, PRIV_NET_ACCESS) != 0 ||
+#endif
priv_delset(box->pset, PRIV_PROC_EXEC) != 0 ||
priv_delset(box->pset, PRIV_PROC_FORK) != 0 ||
priv_delset(box->pset, PRIV_PROC_INFO) != 0 ||
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
More information about the openssh-unix-dev
mailing list