[experimental-ims] fb6f3c5 Add parameter vcc_unsafe_path which allows '/' in include "..." and 'import ... from ...'. Default is on (= no change)

Poul-Henning Kamp phk at FreeBSD.org
Thu Dec 18 10:27:45 CET 2014


commit fb6f3c54177d7aa85a59d10da3bb9b549c0b9aa8
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Sat Apr 28 16:03:17 2012 +0000

    Add parameter vcc_unsafe_path which allows '/' in include "..."
    and 'import ... from ...'.  Default is on (= no change)

diff --git a/bin/varnishd/mgt/mgt.h b/bin/varnishd/mgt/mgt.h
index 0ad01de..65dbc02 100644
--- a/bin/varnishd/mgt/mgt.h
+++ b/bin/varnishd/mgt/mgt.h
@@ -106,6 +106,7 @@ extern const char *mgt_vcl_dir;
 extern const char *mgt_vmod_dir;
 extern unsigned mgt_vcc_err_unref;
 extern unsigned mgt_vcc_allow_inline_c;
+extern unsigned mgt_vcc_unsafe_path;
 
 #define REPORT0(pri, fmt)				\
 	do {						\
diff --git a/bin/varnishd/mgt/mgt_param.c b/bin/varnishd/mgt/mgt_param.c
index b72b0df..885d2ce 100644
--- a/bin/varnishd/mgt/mgt_param.c
+++ b/bin/varnishd/mgt/mgt_param.c
@@ -1188,6 +1188,11 @@ static const struct parspec input_parspec[] = {
 		0,
 		"on", "bool" },
 
+	{ "vcc_unsafe_path", tweak_bool, &mgt_vcc_unsafe_path, 0, 0,
+		"Allow '/' in vmod & include paths.\n"
+		"Allow 'import ... from ...'.\n",
+		0,
+		"on", "bool" },
 
 	{ "pcre_match_limit", tweak_uint,
 		&mgt_param.vre_limits.match,
diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c
index 269a453..9b46da3 100644
--- a/bin/varnishd/mgt/mgt_vcc.c
+++ b/bin/varnishd/mgt/mgt_vcc.c
@@ -64,6 +64,7 @@ const char *mgt_vcl_dir;
 const char *mgt_vmod_dir;
 unsigned mgt_vcc_err_unref;
 unsigned mgt_vcc_allow_inline_c;
+unsigned mgt_vcc_unsafe_path;
 
 static struct vcc *vcc;
 
@@ -141,6 +142,7 @@ run_vcc(void *priv)
 	VCC_VMOD_dir(vcc, mgt_vmod_dir);
 	VCC_Err_Unref(vcc, mgt_vcc_err_unref);
 	VCC_Allow_InlineC(vcc, mgt_vcc_allow_inline_c);
+	VCC_Unsafe_Path(vcc, mgt_vcc_unsafe_path);
 	csrc = VCC_Compile(vcc, sb, vp->vcl);
 	AZ(VSB_finish(sb));
 	if (VSB_len(sb))
diff --git a/bin/varnishtest/tests/c00052.vtc b/bin/varnishtest/tests/c00052.vtc
new file mode 100644
index 0000000..e640230
--- /dev/null
+++ b/bin/varnishtest/tests/c00052.vtc
@@ -0,0 +1,51 @@
+varnishtest "Test disabling inline C code"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 
+
+varnish v1 -cliok "param.show vcc_allow_inline_c"
+
+varnish v1 -vcl+backend {
+	C{ getpid(); }C
+} 
+
+varnish v1 -cliok "param.set vcc_allow_inline_c false"
+
+varnish v1 -badvcl {
+	backend default {
+		.host = "${s1_sock}";
+	}
+	C{ getpid(); }C
+}
+
+varnish v1 -badvcl {
+	backend default {
+		.host = "${s1_sock}";
+	}
+	sub vcl_recv {
+		C{ getpid(); }C
+	}
+}
+
+varnish v1 -cliok "param.set vcc_allow_inline_c true"
+
+varnish v1 -vcl+backend {
+	sub vcl_recv {
+		C{ getpid(); }C
+	}
+}
+
+varnish v1 -vcl+backend {
+	C{ extern int getpid(); }C
+}
+
+varnish v1 -start
+
+client c1 {
+	txreq
+	rxresp
+} -run
diff --git a/bin/varnishtest/tests/c00053.vtc b/bin/varnishtest/tests/c00053.vtc
new file mode 100644
index 0000000..c326293
--- /dev/null
+++ b/bin/varnishtest/tests/c00053.vtc
@@ -0,0 +1,29 @@
+varnishtest "Test inclide vs. unsafe_path"
+
+server s1 {
+	rxreq 
+	txresp -hdr "foo: bAr" -hdr "bar: fOo" -bodylen 4
+} -start
+
+shell "echo > ${pwd}/_.c00053"
+
+varnish v1 -vcl+backend {
+	include "${pwd}/_.c00053";
+}
+
+varnish v1 -cliok "param.set vcc_unsafe_path off"
+
+varnish v1 -badvcl {
+	backend default {
+		.host = "${s1_sock}";
+	}
+	include "${pwd}/_.c00053";
+}
+
+varnish v1 -cliok "param.set vcl_dir ${pwd}"
+
+varnish v1 -vcl+backend {
+	include "_.c00053";
+}
+
+shell "rm -f ${pwd}/_.c00053"
diff --git a/bin/varnishtest/tests/m00008.vtc b/bin/varnishtest/tests/m00008.vtc
new file mode 100644
index 0000000..3d1d665
--- /dev/null
+++ b/bin/varnishtest/tests/m00008.vtc
@@ -0,0 +1,23 @@
+varnishtest "Test std vmod vs. unsafe_path"
+
+server s1 {
+	rxreq 
+	txresp -hdr "foo: bAr" -hdr "bar: fOo" -bodylen 4
+} -start
+
+varnish v1 -vcl+backend {
+	import std from "${topbuild}/lib/libvmod_std/.libs/libvmod_std.so" ;
+}
+
+varnish v1 -cliok "param.set vcc_unsafe_path off"
+
+varnish v1 -badvcl {
+	backend default { .host = "${s1_sock}"; }
+	import std from "${topbuild}/lib/libvmod_std/.libs/libvmod_std.so" ;
+}
+
+varnish v1 -cliok "param.set vmod_dir ${topbuild}/lib/libvmod_std/.libs/"
+
+varnish v1 -vcl+backend {
+	import std;
+}
diff --git a/include/libvcl.h b/include/libvcl.h
index e046db9..5c50c34 100644
--- a/include/libvcl.h
+++ b/include/libvcl.h
@@ -35,5 +35,7 @@ void VCC_Default_VCL(struct vcc *, const char *str);
 void VCC_VCL_dir(struct vcc *, const char *str);
 void VCC_VMOD_dir(struct vcc *, const char *str);
 void VCC_Err_Unref(struct vcc *tl, unsigned u);
+void VCC_Allow_InlineC(struct vcc *tl, unsigned u);
+void VCC_Unsafe_Path(struct vcc *tl, unsigned u);
 
 char *VCC_Compile(const struct vcc *, struct vsb *sb, const char *b);
diff --git a/lib/libvcl/vcc_compile.c b/lib/libvcl/vcc_compile.c
index 66d89f5..c9fe573 100644
--- a/lib/libvcl/vcc_compile.c
+++ b/lib/libvcl/vcc_compile.c
@@ -411,6 +411,10 @@ vcc_file_source(const struct vcc *tl, struct vsb *sb, const char *fn)
 	char *f;
 	struct source *sp;
 
+	if (!tl->unsafe_path && strchr(fn, '/') != NULL) {
+		VSB_printf(sb, "Include path is unsafe '%s'\n", fn);
+		return (NULL);
+	}
 	f = VFIL_readfile(tl->vcl_dir, fn, NULL);
 	if (f == NULL) {
 		VSB_printf(sb, "Cannot read file '%s': %s\n",
@@ -487,6 +491,8 @@ vcc_NewVcc(const struct vcc *tl0)
 		REPLACE(tl->vmod_dir, tl0->vmod_dir);
 		tl->vars = tl0->vars;
 		tl->err_unref = tl0->err_unref;
+		tl->allow_inline_c = tl0->allow_inline_c;
+		tl->unsafe_path = tl0->unsafe_path;
 	} else {
 		tl->err_unref = 1;
 	}
@@ -763,7 +769,7 @@ VCC_VMOD_dir(struct vcc *tl, const char *str)
 }
 
 /*--------------------------------------------------------------------
- * Configure default
+ * Configure settings
  */
 
 void
@@ -773,3 +779,19 @@ VCC_Err_Unref(struct vcc *tl, unsigned u)
 	CHECK_OBJ_NOTNULL(tl, VCC_MAGIC);
 	tl->err_unref = u;
 }
+
+void
+VCC_Allow_InlineC(struct vcc *tl, unsigned u)
+{
+
+	CHECK_OBJ_NOTNULL(tl, VCC_MAGIC);
+	tl->allow_inline_c = u;
+}
+
+void
+VCC_Unsafe_Path(struct vcc *tl, unsigned u)
+{
+
+	CHECK_OBJ_NOTNULL(tl, VCC_MAGIC);
+	tl->unsafe_path = u;
+}
diff --git a/lib/libvcl/vcc_compile.h b/lib/libvcl/vcc_compile.h
index b64564e..c85af5b 100644
--- a/lib/libvcl/vcc_compile.h
+++ b/lib/libvcl/vcc_compile.h
@@ -193,6 +193,8 @@ struct vcc {
 	unsigned		nvmodpriv;
 
 	unsigned		err_unref;
+	unsigned		allow_inline_c;
+	unsigned		unsafe_path;
 };
 
 struct var {
diff --git a/lib/libvcl/vcc_parse.c b/lib/libvcl/vcc_parse.c
index d8e74a4..1b7ee88 100644
--- a/lib/libvcl/vcc_parse.c
+++ b/lib/libvcl/vcc_parse.c
@@ -153,10 +153,16 @@ vcc_Compound(struct vcc *tl)
 			Fb(tl, 1, "}\n");
 			return;
 		case CSRC:
-			Fb(tl, 1, "%.*s\n",
-			    (int) (tl->t->e - (tl->t->b + 2)),
-			    tl->t->b + 1);
-			vcc_NextToken(tl);
+			if (tl->allow_inline_c) {
+				Fb(tl, 1, "%.*s\n",
+				    (int) (tl->t->e - (tl->t->b + 2)),
+				    tl->t->b + 1);
+				vcc_NextToken(tl);
+			} else {
+				VSB_printf(tl->sb,
+				    "Inline-C not allowed");
+				vcc_ErrWhere(tl, tl->t);
+			}
 			break;
 		case EOI:
 			VSB_printf(tl->sb,
@@ -273,9 +279,16 @@ vcc_Parse(struct vcc *tl)
 		ERRCHK(tl);
 		switch (tl->t->tok) {
 		case CSRC:
-			Fc(tl, 0, "%.*s\n",
-			    (int) (tl->t->e - (tl->t->b + 4)), tl->t->b + 2);
-			vcc_NextToken(tl);
+			if (tl->allow_inline_c) {
+				Fc(tl, 0, "%.*s\n",
+				    (int) (tl->t->e - (tl->t->b + 4)),
+				    tl->t->b + 2);
+				vcc_NextToken(tl);
+			} else {
+				VSB_printf(tl->sb,
+				    "Inline-C not allowed");
+				vcc_ErrWhere(tl, tl->t);
+			}
 			break;
 		case EOI:
 			break;
diff --git a/lib/libvcl/vcc_vmod.c b/lib/libvcl/vcc_vmod.c
index bd9f366..4ce4f95 100644
--- a/lib/libvcl/vcc_vmod.c
+++ b/lib/libvcl/vcc_vmod.c
@@ -56,7 +56,6 @@ vcc_ParseImport(struct vcc *tl)
 
 	ExpectErr(tl, ID);
 	mod = tl->t;
-
 	vcc_NextToken(tl);
 
 	osym = VCC_FindSymbol(tl, mod, SYM_NONE);
@@ -83,6 +82,14 @@ vcc_ParseImport(struct vcc *tl)
 	sym->def_e = tl->t;
 
 	if (tl->t->tok == ID) {
+		if (!tl->unsafe_path) {
+			VSB_printf(tl->sb,
+			    "'import ... from path...'"
+			    " not allowed.\nAt:");
+			vcc_ErrToken(tl, tl->t);
+			vcc_ErrWhere(tl, tl->t);
+			return;
+		}
 		if (!vcc_IdIs(tl->t, "from")) {
 			VSB_printf(tl->sb, "Expected 'from path...' at ");
 			vcc_ErrToken(tl, tl->t);



More information about the varnish-commit mailing list