[master] 0060ee941 Found a sneaky way to tests VCC's vmod-tasting code.

Poul-Henning Kamp phk at FreeBSD.org
Fri May 17 08:14:11 UTC 2019


commit 0060ee9410e0fa1d8ca9785761b790abdab7d656
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri May 17 08:12:44 2019 +0000

    Found a sneaky way to tests VCC's vmod-tasting code.

diff --git a/bin/varnishtest/tests/m00003.vtc b/bin/varnishtest/tests/m00003.vtc
index e2f6dccab..4e5a60ff4 100644
--- a/bin/varnishtest/tests/m00003.vtc
+++ b/bin/varnishtest/tests/m00003.vtc
@@ -14,7 +14,7 @@ varnish v1 -arg "-pvmod_path=${topbuild}/lib/libvmod_std/.libs/" \
 
 varnish v1 -cliok "param.set vmod_path /nonexistent"
 
-varnish v1 -errvcl {Could not load VMOD std} {
+varnish v1 -errvcl {Could not find VMOD std} {
 	import std;
 }
 
@@ -23,3 +23,35 @@ varnish v1 -cliok "param.set vmod_path ${topbuild}/lib/libvmod_std/.libs/"
 varnish v1 -vcl+backend {
 	import std;
 }
+
+varnish v1 -cliok "param.set vmod_path ${tmpdir}"
+
+shell "true > ${tmpdir}/libvmod_wrong.so"
+
+varnish v1 -errvcl {Could not open VMOD wrong} {
+	import wrong;
+}
+
+shell "cp ${topbuild}/lib/libvmod_debug/.libs/libvmod_debug.so ${tmpdir}/libvmod_wrong.so"
+
+varnish v1 -errvcl {Malformed VMOD wrong} {
+	import wrong;
+}
+
+varnish v1 -errvcl {Incompatible VMOD wrong0} {
+	import wrong0 from "${tmpdir}/libvmod_wrong.so";
+}
+
+varnish v1 -errvcl {Incompatible VMOD wrong1} {
+	import wrong1 from "${tmpdir}/libvmod_wrong.so";
+}
+
+varnish v1 -errvcl {Mangled VMOD wrong2} {
+	import wrong2 from "${tmpdir}/libvmod_wrong.so";
+}
+
+varnish v1 -errvcl {Wrong file for VMOD wrong3} {
+	import wrong3 from "${tmpdir}/libvmod_wrong.so";
+}
+
+shell "rm -f ${tmpdir}/libvmod_wrong.so"
diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index 6b0ac88a6..c0ffc19ba 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -769,6 +769,7 @@ VCC_New(void)
 	VTAILQ_INIT(&tl->sources);
 	VTAILQ_INIT(&tl->procs);
 	VTAILQ_INIT(&tl->sym_objects);
+	VTAILQ_INIT(&tl->sym_vmods);
 
 	tl->nsources = 0;
 
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index f164a9e92..58eb570c6 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -258,6 +258,7 @@ struct vcc {
 	const char		*default_probe;
 
 	VTAILQ_HEAD(, symbol)	sym_objects;
+	VTAILQ_HEAD(, symbol)	sym_vmods;
 
 	unsigned		unique;
 	unsigned		vmod_count;
diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c
index 6eadd44dc..ff4831198 100644
--- a/lib/libvcc/vcc_vmod.c
+++ b/lib/libvcc/vcc_vmod.c
@@ -40,19 +40,26 @@
 #include "vmod_abi.h"
 #include "vsb.h"
 
+struct vmod_open {
+	unsigned		magic;
+#define VMOD_OPEN_MAGIC		0x9995b1f3
+	void			*hdl;
+	const char		*err;
+};
+
 static int
 vcc_path_dlopen(void *priv, const char *fn)
 {
-	void *hdl, **pp;
+	struct vmod_open *vop;
 
-	AN(priv);
+	CAST_OBJ_NOTNULL(vop, priv, VMOD_OPEN_MAGIC);
 	AN(fn);
 
-	hdl = dlopen(fn, RTLD_NOW | RTLD_LOCAL);
-	if (hdl == NULL)
+	vop->hdl = dlopen(fn, RTLD_NOW | RTLD_LOCAL);
+	if (vop->hdl == NULL) {
+		vop->err = dlerror();
 		return (-1);
-	pp = priv;
-	*pp = hdl;
+	}
 	return (0);
 }
 
@@ -156,7 +163,6 @@ vcc_json_wildcard(struct vcc *tl, struct symbol *msym, struct symbol *tsym)
 void
 vcc_ParseImport(struct vcc *tl)
 {
-	void *hdl;
 	char fn[1024], *fnp, *fnpx;
 	char buf[256];
 	const char *p;
@@ -166,14 +172,17 @@ vcc_ParseImport(struct vcc *tl)
 	const struct vmod_data *vmd;
 	struct vjsn *vj;
 	int again = 0;
+	struct vmod_open vop[1];
 
+	INIT_OBJ(vop, VMOD_OPEN_MAGIC);
 	t1 = tl->t;
 	SkipToken(tl, ID);		/* "import" */
 
 
 	ExpectErr(tl, ID);
 	mod = tl->t;
-	msym = VCC_SymbolGet(tl, SYM_NONE, SYMTAB_NOERR, XREF_NONE);
+	vcc_NextToken(tl);
+	msym = VCC_SymbolGetTok(tl, SYM_NONE, SYMTAB_NOERR, XREF_NONE, mod);
 
 	if (msym != NULL && msym->kind != SYM_VMOD) {
 		/*
@@ -188,13 +197,16 @@ vcc_ParseImport(struct vcc *tl)
 		again = 1;
 	} else {
 
-		msym = VCC_SymbolGet(tl, SYM_VMOD, SYMTAB_CREATE, XREF_NONE);
+		msym = VCC_SymbolGetTok(tl, SYM_VMOD,
+		    SYMTAB_CREATE, XREF_NONE, mod);
 		ERRCHK(tl);
 		AN(msym);
 		msym->def_b = t1;
 		msym->def_e = tl->t;
 	}
 
+	VTAILQ_INSERT_TAIL(&tl->sym_vmods, msym, sideways);
+
 	if (tl->t->tok == ID) {
 		if (!vcc_IdIs(tl->t, "from")) {
 			VSB_printf(tl->sb, "Expected 'from path ...'\n");
@@ -225,12 +237,17 @@ vcc_ParseImport(struct vcc *tl)
 	if (!again)
 		msym->def_e = tl->t;
 
-
-	if (VFIL_searchpath(tl->vmod_path, vcc_path_dlopen, &hdl, fn, &fnpx)) {
-		VSB_printf(tl->sb, "Could not load VMOD %.*s\n", PF(mod));
-		VSB_printf(tl->sb, "\tFile name: %s\n",
-		    fnpx != NULL ? fnpx : fn);
-		VSB_printf(tl->sb, "\tdlerror: %s\n", dlerror());
+	if (VFIL_searchpath(tl->vmod_path, vcc_path_dlopen, vop, fn, &fnpx)) {
+		if (vop->err == NULL) {
+			VSB_printf(tl->sb,
+			    "Could not find VMOD %.*s\n", PF(mod));
+		} else {
+			VSB_printf(tl->sb,
+			    "Could not open VMOD %.*s\n", PF(mod));
+			VSB_printf(tl->sb, "\tFile name: %s\n",
+			    fnpx != NULL ? fnpx : fn);
+			VSB_printf(tl->sb, "\tdlerror: %s\n", vop->err);
+		}
 		vcc_ErrWhere(tl, mod);
 		free(fnpx);
 		return;
@@ -241,7 +258,7 @@ vcc_ParseImport(struct vcc *tl)
 	free(fnpx);
 
 	bprintf(buf, "Vmod_%.*s_Data", PF(mod));
-	vmd = dlsym(hdl, buf);
+	vmd = dlsym(vop->hdl, buf);
 	if (vmd == NULL) {
 		VSB_printf(tl->sb, "Malformed VMOD %.*s\n", PF(mod));
 		VSB_printf(tl->sb, "\tFile name: %s\n", fnp);
@@ -250,7 +267,7 @@ vcc_ParseImport(struct vcc *tl)
 		return;
 	}
 	if (vmd->vrt_major == 0 && vmd->vrt_minor == 0 &&
-	    strcmp(vmd->abi, VMOD_ABI_Version) != 0) {
+	    (vmd->abi == NULL || strcmp(vmd->abi, VMOD_ABI_Version) != 0)) {
 		VSB_printf(tl->sb, "Incompatible VMOD %.*s\n", PF(mod));
 		VSB_printf(tl->sb, "\tFile name: %s\n", fnp);
 		VSB_printf(tl->sb, "\tABI mismatch, expected <%s>, got <%s>\n",
@@ -282,7 +299,7 @@ vcc_ParseImport(struct vcc *tl)
 	}
 
 	if (!vcc_IdIs(mod, vmd->name)) {
-		VSB_printf(tl->sb, "Wrong VMOD file %.*s\n", PF(mod));
+		VSB_printf(tl->sb, "Wrong file for VMOD %.*s\n", PF(mod));
 		VSB_printf(tl->sb, "\tFile name: %s\n", fnp);
 		VSB_printf(tl->sb, "\tContains vmod \"%s\"\n", vmd->name);
 		vcc_ErrWhere(tl, mod);
@@ -298,7 +315,7 @@ vcc_ParseImport(struct vcc *tl)
 		vcc_ErrWhere2(tl, msym->def_b, msym->def_e);
 	}
 	if (again) {
-		AZ(dlclose(hdl));
+		AZ(dlclose(vop->hdl));
 		return;
 	}
 
diff --git a/lib/libvmod_debug/Makefile.am b/lib/libvmod_debug/Makefile.am
index 4823e1b4d..8c6df5232 100644
--- a/lib/libvmod_debug/Makefile.am
+++ b/lib/libvmod_debug/Makefile.am
@@ -5,8 +5,17 @@ libvmod_debug_la_SOURCES = \
 	vmod_debug_obj.c \
 	vmod_debug_dyn.c
 
+
 include $(srcdir)/automake_boilerplate.am
 
+# Allow Vmod_wrong*_Data to be exported
+libvmod_debug_la_LDFLAGS = \
+	-export-symbols-regex 'Vmod_.*_Data' \
+	$(AM_LDFLAGS) \
+	$(VMOD_LDFLAGS) \
+	@SAN_LDFLAGS@
+
+
 # not --strict
 vmodtoolargs = --boilerplate
 
diff --git a/lib/libvmod_debug/flint.lnt b/lib/libvmod_debug/flint.lnt
index 36d225583..2a43e7057 100644
--- a/lib/libvmod_debug/flint.lnt
+++ b/lib/libvmod_debug/flint.lnt
@@ -1,3 +1,6 @@
 -esym(759, xyzzy_enum_*)         // header declaration for symbol '___' defined at (___)
 -esym(765, xyzzy_enum_*)         // external '___' (___) could be made static
 
+-esym(765, Vmod_wrong*_Data)	// external '___' (___) could be made static
+-esym(714, Vmod_wrong*_Data)	// external '___' (___) could be made static
+-esym(754, foo::bar)		// local struct member not referenced
diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c
index 4dac3f3dc..0d9f9d356 100644
--- a/lib/libvmod_debug/vmod_debug.c
+++ b/lib/libvmod_debug/vmod_debug.c
@@ -134,7 +134,7 @@ xyzzy_rot13_bytes(struct req *req, enum vdp_action act, void **priv,
 		}
 	}
 	if (i >= 0)
-		retval = VDP_bytes(req, VDP_FLUSH, q, i + 1);
+		retval = VDP_bytes(req, VDP_FLUSH, q, i + 1L);
 	return (retval);
 }
 
@@ -854,3 +854,44 @@ xyzzy_sndbuf(VRT_CTX, VCL_BYTES arg)
 	VSLb(ctx->vsl, SLT_Debug, "SO_SNDBUF fd=%d old=%d new=%d actual=%d",
 	    fd, oldbuf, buflen, newbuf);
 }
+
+/**********************************************************************
+ * For testing import code on bad vmod files (m00003.vtc)
+ */
+
+const struct vmod_data Vmod_wrong0_Data = {
+	.vrt_major =    0,
+	.vrt_minor =    0,
+};
+
+//lint -save -e835 A zero has been given as left argument to operatorp'+'
+const struct vmod_data Vmod_wrong1_Data = {
+	.vrt_major =    VRT_MAJOR_VERSION,
+	.vrt_minor =    VRT_MINOR_VERSION + 1,
+};
+//lint -restore
+
+static const struct foo {
+	int bar;
+} foo_struct[1];
+
+const struct vmod_data Vmod_wrong2_Data = {
+	.vrt_major =    VRT_MAJOR_VERSION,
+	.vrt_minor =    VRT_MINOR_VERSION,
+	.name =		"wrongN",
+	.func =		foo_struct,
+	.func_len =	sizeof foo_struct,
+	.func_name =	"foo_struct",
+	.proto =	"blablabla",
+};
+
+const struct vmod_data Vmod_wrong3_Data = {
+	.vrt_major =    VRT_MAJOR_VERSION,
+	.vrt_minor =    VRT_MINOR_VERSION,
+	.name =		"wrongN",
+	.func =		foo_struct,
+	.func_len =	sizeof foo_struct,
+	.func_name =	"foo_struct",
+	.proto =	"blablabla",
+	.abi =		"abiblabla",
+};


More information about the varnish-commit mailing list