[master] 45c8694 Convert (and retire) the sandbox code to the new jail framework.

Poul-Henning Kamp phk at FreeBSD.org
Mon Feb 16 12:21:40 CET 2015


commit 45c8694e657539e7e86673f85a44d963001ab8dd
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Feb 16 11:17:43 2015 +0000

    Convert (and retire) the sandbox code to the new jail framework.
    
    The retires the -u and -g arguments, and the user/group/group_cc
    parameters, so that the jail-setup cannot be manipulated from CLI at all.
    
    $user and group_cc are now sub-arguments to -junix, for instance:
    
    	-junix,user=varnish1,ccgroup=ccowner
    
    There is no group= subargument, the group information is taken
    from the user id in question.
    
    If no -j argument is specified, attempt:
    
    	-junix,user=varnish
    
    but fail silently if not possible.
    
    The "vident" now contains information about jail-config.
    
    Sandbox_solaris is not converted yet, (I'm hoping that Nils will
    help with that.

diff --git a/bin/varnishd/Makefile.am b/bin/varnishd/Makefile.am
index 0982aec..1aebc43 100644
--- a/bin/varnishd/Makefile.am
+++ b/bin/varnishd/Makefile.am
@@ -65,6 +65,7 @@ varnishd_SOURCES = \
 	mgt/mgt_child.c \
 	mgt/mgt_cli.c \
 	mgt/mgt_jail.c \
+	mgt/mgt_jail_unix.c \
 	mgt/mgt_main.c \
 	mgt/mgt_param.c \
 	mgt/mgt_param_tbl.c \
@@ -72,8 +73,6 @@ varnishd_SOURCES = \
 	mgt/mgt_param_tcp.c \
 	mgt/mgt_param_tweak.c \
 	mgt/mgt_pool.c \
-	mgt/mgt_sandbox.c \
-	mgt/mgt_sandbox_solaris.c \
 	mgt/mgt_shmem.c \
 	mgt/mgt_vcc.c \
 	storage/stevedore.c \
diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h
index d045349..4aa707d 100644
--- a/bin/varnishd/mgt/mgt.h
+++ b/bin/varnishd/mgt/mgt.h
@@ -65,11 +65,10 @@ void mgt_cli_close_all(void);
 /* mgt_jail.c */
 
 enum jail_subproc_e {
-	JAIL_SP_TESTING,
-	JAIL_SP_VCC,
-	JAIL_SP_CC,
-	JAIL_SP_VCLLOAD,
-	JAIL_SP_WORKER,
+	JAIL_SUBPROC_VCC,
+	JAIL_SUBPROC_CC,
+	JAIL_SUBPROC_VCLLOAD,
+	JAIL_SUBPROC_WORKER,
 };
 
 enum jail_master_e {
@@ -94,6 +93,8 @@ void VJ_Init(const char *j_arg);
 void VJ_master(enum jail_master_e jme);
 void VJ_subproc(enum jail_subproc_e jse);
 
+extern const struct jail_tech jail_tech_unix;
+
 /* mgt_main.c */
 extern struct VSC_C_mgt	*VSC_C_mgt;
 extern struct VSC_C_mgt static_VSC_C_mgt;
@@ -118,24 +119,6 @@ extern struct params mgt_param;
 /* mgt_param_tcp.c */
 void MCF_TcpParams(void);
 
-/* mgt_sandbox.c */
-enum sandbox_e {
-	SANDBOX_TESTING,
-	SANDBOX_VCC,
-	SANDBOX_CC,
-	SANDBOX_VCLLOAD,
-	SANDBOX_WORKER,
-};
-
-typedef void mgt_sandbox_f(enum sandbox_e);
-extern mgt_sandbox_f *mgt_sandbox;
-void mgt_sandbox_init(void);
-
-/* mgt_sandbox_solaris.c */
-#ifdef HAVE_SETPPRIV
-mgt_sandbox_f mgt_sandbox_solaris;
-#endif
-
 /* mgt_shmem.c */
 void mgt_SHM_Init(void);
 void mgt_SHM_static_alloc(const void *, ssize_t size,
diff --git a/bin/varnishd/mgt/mgt_child.c b/bin/varnishd/mgt/mgt_child.c
index 7c777de..5a0220e 100644
--- a/bin/varnishd/mgt/mgt_child.c
+++ b/bin/varnishd/mgt/mgt_child.c
@@ -421,7 +421,7 @@ mgt_launch_child(struct cli *cli)
 		(void)signal(SIGINT, SIG_DFL);
 		(void)signal(SIGTERM, SIG_DFL);
 
-		mgt_sandbox(SANDBOX_WORKER);
+		VJ_subproc(JAIL_SUBPROC_WORKER);
 
 		child_main();
 
diff --git a/bin/varnishd/mgt/mgt_jail.c b/bin/varnishd/mgt/mgt_jail.c
index 4be41fc..00afa89 100644
--- a/bin/varnishd/mgt/mgt_jail.c
+++ b/bin/varnishd/mgt/mgt_jail.c
@@ -33,9 +33,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <syslog.h>
-#include <string.h>
-#include <unistd.h>
 
 #include "mgt/mgt.h"
 #include "vav.h"
@@ -47,8 +44,8 @@
 static int __match_proto__(jail_init_f)
 vjn_init(char **args)
 {
-	if (*args != NULL)
-		ARGV_ERR("-Jnone takes no arguments.\n");
+	if (args != NULL && *args != NULL)
+		ARGV_ERR("-jnone takes no arguments.\n");
 	return (0);
 }
 
@@ -77,6 +74,7 @@ static const struct jail_tech jail_tech_none = {
 static const struct jail_tech *vjt;
 
 static const struct choice vj_choice[] = {
+	{ "unix",	&jail_tech_unix },
 	{ "none",	&jail_tech_none },
 	{ NULL,		NULL },
 };
@@ -96,22 +94,21 @@ VJ_Init(const char *j_arg)
 			ARGV_ERR("-j argument is emtpy\n");
 		vjt = pick(vj_choice, av[1], "jail");
 		CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
-		vjt->init(av + 2);
+		(void)vjt->init(av + 2);
 		VAV_Free(av);
 	} else {
 		/*
 		 * Go through list of jail technologies until one
 		 * succeeds, falling back to "none".
 		 */
-		av = VAV_Parse("", NULL, ARGV_COMMA);
 		for (i = 0; vj_choice[i].name != NULL; i++) {
 			vjt = vj_choice[i].ptr;
 			CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
-			if (!vjt->init(av + 1))
+			if (!vjt->init(NULL))
 				break;
 		}
-		VAV_Free(av);
 	}
+	VSB_printf(vident, ",-j%s", vjt->name);
 }
 
 void
diff --git a/bin/varnishd/mgt/mgt_jail_unix.c b/bin/varnishd/mgt/mgt_jail_unix.c
new file mode 100644
index 0000000..49eb073
--- /dev/null
+++ b/bin/varnishd/mgt/mgt_jail_unix.c
@@ -0,0 +1,174 @@
+/*-
+ * Copyright (c) 2006-2015 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Jailing processes the UNIX way, using setuid(2) etc.
+ */
+
+#include "config.h"
+
+#include <pwd.h>
+#include <grp.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "mgt/mgt.h"
+
+#ifdef __linux__
+#include <sys/prctl.h>
+#endif
+
+static uid_t vju_uid;
+static gid_t vju_gid;
+static const char *vju_user;
+static gid_t vju_cc_gid;
+static int vju_cc_gid_set;
+
+#ifndef JAIL_USER
+#define JAIL_USER "varnish"
+#endif
+
+#ifndef NGID
+#define NGID 2000
+#endif
+
+static int
+vju_getuid(const char *arg)
+{
+	struct passwd *pw;
+
+	pw = getpwnam(arg);
+	if (pw != NULL) {
+		vju_user = strdup(arg);
+		AN(vju_user);
+		vju_uid = pw->pw_uid;
+		vju_gid = pw->pw_gid;
+	}
+	endpwent();
+	return (pw == NULL ? -1 : 0);
+}
+
+static int
+vju_getccgid(const char *arg)
+{
+	struct group *gr;
+
+	gr = getgrnam(arg);
+	if (gr != NULL) {
+		vju_cc_gid_set = 1;
+		vju_cc_gid = gr->gr_gid;
+	}
+	endgrent();
+	return (gr == NULL ? -1 : 0);
+}
+
+/**********************************************************************
+ */
+
+static int __match_proto__(jail_init_f)
+vju_init(char **args)
+{
+	if (args == NULL) {
+		/* Autoconfig */
+		if (geteuid() != 0)
+			return (1);
+		if (vju_getuid(JAIL_USER))
+			return (1);
+		return (0);
+	}
+
+	if (geteuid() != 0)
+		ARGV_ERR("Unix Jail: Must be root.\n");
+
+	for (;*args != NULL; args++) {
+		if (!strncmp(*args, "user=", 5)) {
+			if (vju_getuid((*args) + 5)) {
+				ARGV_ERR("Unix jail: %s user not found.\n",
+				    (*args) + 5);
+			}
+			continue;
+		}
+		if (!strncmp(*args, "ccgroup=", 8)) {
+			if (vju_getccgid((*args) + 8)) {
+				ARGV_ERR("Unix jail: %s group not found.\n",
+				    (*args) + 8);
+			}
+			continue;
+		}
+		ARGV_ERR("Unix jail: unknown sub-argument '%s'\n", *args);
+	}
+
+	if (vju_user == NULL && vju_getuid(JAIL_USER))
+		ARGV_ERR("Unix jail: %s user not found.\n", JAIL_USER);
+
+	return (0);
+}
+
+static void __match_proto__(jail_master_f)
+vju_master(enum jail_master_e jme)
+{
+	(void)jme;
+}
+
+static void __match_proto__(jail_subproc_f)
+vju_subproc(enum jail_subproc_e jse)
+{
+	int i;
+	gid_t gid_list[NGID];
+
+	AZ(setgid(vju_gid));
+	AZ(initgroups(vju_user, vju_gid));
+
+	if (jse == JAIL_SUBPROC_CC && vju_cc_gid_set) {
+		/* Add the optional extra group for the C-compiler access */
+		i = getgroups(NGID, gid_list);
+		assert(i >= 0);
+		gid_list[i++] = vju_cc_gid;
+		AZ(setgroups(i, gid_list));
+	}
+
+	AZ(setuid(vju_uid));
+
+#ifdef __linux__
+	/*
+	 * On linux mucking about with uid/gid disables core-dumps,			 * reenable them again.
+	 */
+	if (prctl(PR_SET_DUMPABLE, 1) != 0) {
+		REPORT0(LOG_INFO,
+		    "Could not set dumpable bit.  Core dumps turned off\n");
+	}
+#endif
+}
+
+const struct jail_tech jail_tech_unix = {
+	.magic =	JAIL_TECH_MAGIC,
+	.name =		"unix",
+	.init =		vju_init,
+	.master =	vju_master,
+	.subproc =	vju_subproc,
+};
diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c
index b8624bc..f8d358b 100644
--- a/bin/varnishd/mgt/mgt_main.c
+++ b/bin/varnishd/mgt/mgt_main.c
@@ -147,7 +147,6 @@ usage(void)
 	fprintf(stderr, FMT, "-d", "debug");
 	fprintf(stderr, FMT, "-f file", "VCL script");
 	fprintf(stderr, FMT, "-F", "Run in foreground");
-	fprintf(stderr, FMT, "-g group", "Privilege separation group id");
 	fprintf(stderr, FMT, "-h kind[,hashoptions]", "Hash specification");
 	fprintf(stderr, FMT, "", "  -h critbit [default]");
 	fprintf(stderr, FMT, "", "  -h simple_list");
@@ -181,7 +180,6 @@ usage(void)
 	fprintf(stderr, FMT, "-T address:port",
 	    "Telnet listen address and port");
 	fprintf(stderr, FMT, "-t", "Default TTL");
-	fprintf(stderr, FMT, "-u user", "Privilege separation user id");
 	fprintf(stderr, FMT, "-V", "version");
 #undef FMT
 	exit(1);
@@ -429,11 +427,6 @@ main(int argc, char * const *argv)
 	SHA256_Test();
 
 	/*
-	 * Find out if we can sandbox
-	 */
-	mgt_sandbox_init();
-
-	/*
 	 * Create a cli for convenience in otherwise CLI functions
 	 */
 
@@ -450,7 +443,7 @@ main(int argc, char * const *argv)
 	cli_check(cli);
 
 	while ((o = getopt(argc, argv,
-	    "a:b:Cdf:Fg:h:i:j:l:M:n:P:p:r:S:s:T:t:u:Vx:")) != -1) {
+	    "a:b:Cdf:Fh:i:j:l:M:n:P:p:r:S:s:T:t:Vx:")) != -1) {
 		/*
 		 * -j must be the first argument if specified, because
 		 * it (may) affect subsequent argument processing.
@@ -487,9 +480,6 @@ main(int argc, char * const *argv)
 		case 'F':
 			F_flag = 1 - F_flag;
 			break;
-		case 'g':
-			MCF_ParamSet(cli, "group", optarg);
-			break;
 		case 'h':
 			h_arg = optarg;
 			break;
@@ -550,9 +540,6 @@ main(int argc, char * const *argv)
 			else
 				T_arg = NULL;
 			break;
-		case 'u':
-			MCF_ParamSet(cli, "user", optarg);
-			break;
 		case 'V':
 			/* XXX: we should print the ident here */
 			VCS_Message("varnishd");
diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c
index c8b7fe9..4d33fcb 100644
--- a/bin/varnishd/mgt/mgt_param.c
+++ b/bin/varnishd/mgt/mgt_param.c
@@ -416,12 +416,12 @@ mcf_wash_param(struct cli *cli, const struct parspec *pp, const char **val,
 
 	AN(*val);
 	VSB_clear(vsb);
-	VSB_printf(vsb, "FAILED to set %s for param %s = %s\n",
+	VSB_printf(vsb, "FAILED to set %s for param %s:\n\t%s",
 	    name, pp->name, *val);
 	err = pp->func(vsb, pp, *val);
 	AZ(VSB_finish(vsb));
 	if (err) {
-		VCLI_Out(cli, "%s", VSB_data(vsb));
+		VCLI_Out(cli, "%s\n", VSB_data(vsb));
 		VCLI_SetResult(cli, CLIS_CANT);
 		return;
 	}
diff --git a/bin/varnishd/mgt/mgt_sandbox.c b/bin/varnishd/mgt/mgt_sandbox.c
index 340a0bc..df7eadb 100644
--- a/bin/varnishd/mgt/mgt_sandbox.c
+++ b/bin/varnishd/mgt/mgt_sandbox.c
@@ -42,6 +42,8 @@
  *	FreeBSD: capsicum
  */
 
+#if 0
+
 #include "config.h"
 
 #ifdef __linux__
@@ -312,3 +314,5 @@ mgt_sandbox_init(void)
 	}
 	endgrent();
 }
+
+#endif
diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c
index 34be631..e181f74 100644
--- a/bin/varnishd/mgt/mgt_vcc.c
+++ b/bin/varnishd/mgt/mgt_vcc.c
@@ -155,7 +155,7 @@ run_vcc(void *priv)
 	int fd, i, l;
 
 	CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC);
-	mgt_sandbox(SANDBOX_VCC);
+	VJ_subproc(JAIL_SUBPROC_VCC);
 	sb = VSB_new_auto();
 	XXXAN(sb);
 	VCC_VCL_dir(vcc, mgt_vcl_dir);
@@ -199,7 +199,7 @@ run_cc(void *priv)
 	int pct;
 	char *p;
 
-	mgt_sandbox(SANDBOX_CC);
+	VJ_subproc(JAIL_SUBPROC_CC);
 	CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC);
 
 	sb = VSB_new_auto();
@@ -248,7 +248,7 @@ run_dlopen(void *priv)
 	struct VCL_conf const *cnf;
 	struct vcc_priv *vp;
 
-	mgt_sandbox(SANDBOX_VCLLOAD);
+	VJ_subproc(JAIL_SUBPROC_VCLLOAD);
 	CAST_OBJ_NOTNULL(vp, priv, VCC_PRIV_MAGIC);
 
 	/* Try to load the object into this sub-process */



More information about the varnish-commit mailing list