Commit fb6f3c54 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Add parameter vcc_unsafe_path which allows '/' in include "..."

and 'import ... from ...'.  Default is on (= no change)
parent 2b623eaf
......@@ -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 { \
......
......@@ -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,
......
......@@ -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))
......
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
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"
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;
}
......@@ -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);
......@@ -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;
}
......@@ -193,6 +193,8 @@ struct vcc {
unsigned nvmodpriv;
unsigned err_unref;
unsigned allow_inline_c;
unsigned unsafe_path;
};
struct var {
......
......@@ -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;
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment