[master] fb6f3c5 Add parameter vcc_unsafe_path which allows '/' in include "..." and 'import ... from ...'. Default is on (= no change)
Poul-Henning Kamp
phk at varnish-cache.org
Sat Apr 28 18:41:39 CEST 2012
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