[master] 11d55148a Put some serious red tape on VCL_STRANDS
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Tue Nov 19 17:27:06 UTC 2019
commit 11d55148abcaa64e843df0dceca6c7371c0a018a
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Tue Nov 19 18:09:27 2019 +0100
Put some serious red tape on VCL_STRANDS
I started suspecting that we need this clarification during the review
of #3123 [1] and was able to verify it with a simple test case. First I
needed a function I put in vmod_debug:
$Function STRANDS hoard_strands(PRIV_TASK, STRANDS s)
Return the first value of s for the rest of the task.
The implementation is very straightforward:
struct hoarder {
VCL_STRANDS s;
};
VCL_STRANDS
xyzzy_hoard_strands(VRT_CTX, struct vmod_priv *priv, VCL_STRANDS s)
{
struct hoarder *h;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(priv);
if (priv->priv == NULL) {
h = malloc(sizeof *h);
AN(h);
h->s = s;
priv->priv = h;
priv->free = free;
}
return (priv->priv);
}
And then the following test case results in a panic on my system, but I
suspect this is generally undefined behavior and other nasty results may
occur under different circumstances:
varnishtest "Beware of STRANDS"
varnish v1 -vcl {
import debug;
backend be none;
sub vcl_recv {
debug.hoard_strands("recv: " + req.url);
}
sub vcl_miss {
debug.hoard_strands("miss: " + req.url);
return (synth(200));
}
sub vcl_synth {
set resp.body = debug.hoard_strands("synth: " + req.url);
return (deliver);
}
} -start
client c1 {
txreq
rxresp
expect resp.body ~ recv
} -run
This also begs the following question: can it ever be safe to let a VMOD
function return a STRANDS? Maybe it should be banned from return types.
[1] https://github.com/varnishcache/varnish-cache/pull/3123#discussion_r345617108
diff --git a/include/vrt.h b/include/vrt.h
index 70a153bf3..863e60f65 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -180,6 +180,22 @@ struct vsl_log;
struct ws;
struct VSC_main;
+/*
+ * VCL_STRANDS:
+ *
+ * An argc+argv type of data structure where n indicates the number of strings
+ * in the p array. Individual components of a strands may be null.
+ *
+ * A STRANDS allows you to work on a strings concatenation with the option to
+ * collect it into a single STRING, or if possible work directly on individual
+ * parts.
+ *
+ * The memory management is very strict: a VMOD function receiving a STRANDS
+ * argument should keep no reference after the function returns. Retention of
+ * a STRANDS further in the ongoing task is undefined behavior and may result
+ * in a panic or data corruption.
+ */
+
struct strands {
int n;
const char **p;
More information about the varnish-commit
mailing list