[master] 8282cff4b Give struct vrt_blob a magic value

Nils Goroll nils.goroll at uplex.de
Mon Jul 21 13:53:05 UTC 2025


commit 8282cff4b31dce12e100d4d6c78d30b1f4689dd3
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Wed Jul 9 15:42:34 2025 +0200

    Give struct vrt_blob a magic value
    
    On 64bit, this basically comes for free because len is already aligned on 8
    bytes.
    
    Motivated by the void pointer type VCL_BODY, which is basically a union of a
    blob and a struct strands pointer.
    
    Magic checks follow the rule:
    
    - If a function accesses the object, add a check
    - If a function only passes on the object, don't
    
    before:
    
    (gdb) ptype /o struct vrt_blob
    /* offset      |    size */  type = struct vrt_blob {
    /*      0      |       4 */    unsigned int type;
    /* XXX  4-byte hole      */
    /*      8      |       8 */    size_t len;
    /*     16      |       8 */    const void *blob;
    
                                   /* total size (bytes):   24 */
                                 }
    
    after:
    
    (gdb) ptype /o struct vrt_blob
    /* offset      |    size */  type = struct vrt_blob {
    /*      0      |       4 */    unsigned int magic;
    /*      4      |       4 */    unsigned int type;
    /*      8      |       8 */    size_t len;
    /*     16      |       8 */    const void *blob;
    
                                   /* total size (bytes):   24 */
                                 }

diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index 645207b39..bdb6fefd7 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -788,6 +788,7 @@ via_endpoint(const struct vrt_endpoint *vep, const struct suckaddr *sa,
 	preamble = VSB_new_auto();
 	AN(preamble);
 	VPX_Format_Proxy(preamble, 2, client_bogo, sa, auth);
+	INIT_OBJ(blob, VRT_BLOB_MAGIC);
 	blob->blob = VSB_data(preamble);
 	blob->len = VSB_len(preamble);
 	nvep->preamble = blob;
diff --git a/bin/varnishd/cache/cache_conn_pool.c b/bin/varnishd/cache/cache_conn_pool.c
index 1e846e0f8..5dd02723a 100644
--- a/bin/varnishd/cache/cache_conn_pool.c
+++ b/bin/varnishd/cache/cache_conn_pool.c
@@ -430,6 +430,7 @@ VCP_Open(struct conn_pool *cp, vtim_dur tmo, VCL_IP *ap, int *err)
 
 	if (r >= 0 && errno == 0 && cp->endpoint->preamble != NULL &&
 	     cp->endpoint->preamble->len > 0) {
+		CHECK_OBJ(cp->endpoint->preamble, VRT_BLOB_MAGIC);
 		if (write(r, cp->endpoint->preamble->blob,
 		    cp->endpoint->preamble->len) !=
 		    cp->endpoint->preamble->len) {
@@ -800,6 +801,7 @@ VCP_Ref(const struct vrt_endpoint *vep, const char *ident)
 			VSHA256_Update(cx, vep->ipv6, vsa_suckaddr_len);
 		}
 	}
+	CHECK_OBJ_ORNULL(vep->preamble, VRT_BLOB_MAGIC);
 	if (vep->preamble != NULL && vep->preamble->len > 0) {
 		VSHA256_Update(cx, "PRE", 4); // include \0
 		VSHA256_Update(cx, vep->preamble->blob, vep->preamble->len);
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index 5484f75aa..e2bd090d8 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -60,6 +60,7 @@ const struct strands *const vrt_null_strands = &(struct strands){
 	.p = (const char *[1]){NULL}
 };
 const struct vrt_blob *const vrt_null_blob = &(struct vrt_blob){
+	.magic = VRT_BLOB_MAGIC,
 	.type = VRT_NULL_BLOB_TYPE,
 	.len = 0,
 	.blob = "\0"
@@ -881,6 +882,7 @@ VRT_synth_blob(VRT_CTX, VCL_BLOB b)
 	struct vsb *vsb;
 	CAST_OBJ_NOTNULL(vsb, ctx->specific, VSB_MAGIC);
 
+	CHECK_OBJ_NOTNULL(b, VRT_BLOB_MAGIC);
 	if (b->len > 0 && b->blob != NULL)
 		VSB_bcat(vsb, b->blob, b->len);
 }
@@ -1102,6 +1104,7 @@ VRT_blob(VRT_CTX, const char *err, const void *src, size_t len, unsigned type)
 		return (NULL);
 	}
 
+	INIT_OBJ(p, VRT_BLOB_MAGIC);
 	p->type = type;
 	p->len = len;
 	p->blob = src;
@@ -1182,9 +1185,11 @@ VRT_Endpoint_Clone(const struct vrt_endpoint * const vep)
 	if (vep->preamble != NULL && vep->preamble->len) {
 		/* Before uds because we need p to be aligned still */
 		blob = (void*)p;
+		INIT_OBJ(blob, VRT_BLOB_MAGIC);
 		p += sizeof(*blob);
 		nvep->preamble = blob;
 		memcpy(p, vep->preamble->blob, vep->preamble->len);
+		blob->type = 0x70ea5b1e;
 		blob->len = vep->preamble->len;
 		blob->blob = p;
 		p += vep->preamble->len;
diff --git a/bin/varnishd/cache/cache_vrt_var.c b/bin/varnishd/cache/cache_vrt_var.c
index 24c69cbfc..bf44efca8 100644
--- a/bin/varnishd/cache/cache_vrt_var.c
+++ b/bin/varnishd/cache/cache_vrt_var.c
@@ -1079,6 +1079,7 @@ VRT_l_##which##_body(VRT_CTX, enum lbody_e type,		\
 	if (type == LBODY_SET_BLOB || type == LBODY_ADD_BLOB) {	\
 		AZ(str);					\
 		b = body;					\
+		CHECK_OBJ_NOTNULL(b, VRT_BLOB_MAGIC);		\
 		VSB_bcat(vsb, b->blob, b->len);			\
 		return;						\
 	}							\
diff --git a/include/vrt.h b/include/vrt.h
index dabc33c47..26f5aa8d6 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -86,6 +86,7 @@
  *	VRT_AddVDP() removed
  *	VRT_RemoveVFP() removed
  *	VRT_RemoveVDP() removed
+ *	struct vrt_blob magic added
  * 21.0 (2025-03-17)
  *	VRT_u_req_grace() added
  *	VRT_u_req_ttl() added
@@ -407,6 +408,8 @@ extern const struct strands *const vrt_null_strands;
  */
 
 struct vrt_blob {
+	unsigned	magic;
+#define VRT_BLOB_MAGIC	0xe114db9e
 	unsigned	type;
 	size_t		len;
 	const void	*blob;
diff --git a/lib/libvcc/vcc_token.c b/lib/libvcc/vcc_token.c
index 268d5d4a7..4aeaee991 100644
--- a/lib/libvcc/vcc_token.c
+++ b/lib/libvcc/vcc_token.c
@@ -629,6 +629,7 @@ vcc_Lexer(struct vcc *tl, struct source *sp)
 			Fh(tl, 0,
 			    "\nstatic const struct vrt_blob %s[1] = {{\n",
 			    namebuf);
+			Fh(tl, 0, "\t.magic =\tVRT_BLOB_MAGIC,\n");
 			Fh(tl, 0, "\t.len =\t%zd,\n", VSB_len(vsb));
 			Fh(tl, 0, "\t.blob =\t%s_data,\n", namebuf);
 			Fh(tl, 0, "}};\n");
diff --git a/vmod/vmod_blob.c b/vmod/vmod_blob.c
index c9f675eb5..122a97c5b 100644
--- a/vmod/vmod_blob.c
+++ b/vmod/vmod_blob.c
@@ -208,6 +208,7 @@ vmod_blob__init(VRT_CTX, struct vmod_blob_blob **blobp, const char *vcl_name,
 	*blobp = b;
 	AZ(pthread_mutex_init(&b->lock, NULL));
 
+	b->blob.magic = VRT_BLOB_MAGIC;
 	b->blob.type = VMOD_BLOB_TYPE;
 
 	len = decode_l(dec, strings);
@@ -246,6 +247,7 @@ vmod_blob_get(VRT_CTX, struct vmod_blob_blob *b)
 {
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(b, VMOD_BLOB_MAGIC);
+	CHECK_OBJ(&b->blob, VRT_BLOB_MAGIC);
 	return (&b->blob);
 }
 
@@ -259,6 +261,7 @@ vmod_blob_encode(VRT_CTX, struct vmod_blob_blob *b, VCL_ENUM encs,
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	CHECK_OBJ_NOTNULL(b, VMOD_BLOB_MAGIC);
+	CHECK_OBJ(&b->blob, VRT_BLOB_MAGIC);
 
 	if (!check_enc_case(ctx, encs, case_s, enc, kase))
 		return (NULL);
@@ -309,6 +312,7 @@ vmod_blob__fini(struct vmod_blob_blob **blobp)
 	int i, j;
 
 	TAKE_OBJ_NOTNULL(b, blobp, VMOD_BLOB_MAGIC);
+	CHECK_OBJ(&b->blob, VRT_BLOB_MAGIC);
 
 	if (b->freeptr != NULL) {
 		free(b->freeptr);
@@ -379,6 +383,7 @@ encode(VRT_CTX, enum encoding enc, enum case_e kase, VCL_BLOB b)
 	if (b == NULL)
 		return (NULL);
 
+	CHECK_OBJ(b, VRT_BLOB_MAGIC);
 	CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC);
 	space = WS_ReserveAll(ctx->ws);
 	buf = WS_Reservation(ctx->ws);
@@ -454,6 +459,7 @@ vmod_transcode(VRT_CTX, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s,
 		return (NULL);
 	}
 
+	b.magic = VRT_BLOB_MAGIC;
 	b.len = len;
 	b.blob = buf;
 
@@ -485,6 +491,8 @@ vmod_same(VRT_CTX, VCL_BLOB b1, VCL_BLOB b2)
 		return (1);
 	if (b1 == NULL || b2 == NULL)
 		return (0);
+	CHECK_OBJ(b1, VRT_BLOB_MAGIC);
+	CHECK_OBJ(b2, VRT_BLOB_MAGIC);
 	return (b1->len == b2->len && b1->blob == b2->blob);
 }
 
@@ -497,6 +505,8 @@ vmod_equal(VRT_CTX, VCL_BLOB b1, VCL_BLOB b2)
 		return (1);
 	if (b1 == NULL || b2 == NULL)
 		return (0);
+	CHECK_OBJ(b1, VRT_BLOB_MAGIC);
+	CHECK_OBJ(b2, VRT_BLOB_MAGIC);
 	if (b1->len != b2->len)
 		return (0);
 	if (b1->blob == b2->blob)
@@ -513,6 +523,7 @@ vmod_length(VRT_CTX, VCL_BLOB b)
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 	if (b == NULL)
 		return (0);
+	CHECK_OBJ(b, VRT_BLOB_MAGIC);
 	return (b->len);
 }
 
@@ -524,6 +535,7 @@ vmod_sub(VRT_CTX, VCL_BLOB b, VCL_BYTES n, VCL_BYTES off)
 	assert(n >= 0);
 	assert(off >= 0);
 
+	CHECK_OBJ_ORNULL(b, VRT_BLOB_MAGIC);
 	if (b == NULL || b->len == 0 || b->blob == NULL) {
 		ERR(ctx, "blob is empty in blob.sub()");
 		return (NULL);
diff --git a/vmod/vmod_debug_acl.c b/vmod/vmod_debug_acl.c
index fadc6cea6..fa8990a31 100644
--- a/vmod/vmod_debug_acl.c
+++ b/vmod/vmod_debug_acl.c
@@ -226,6 +226,7 @@ xyzzy_sweep_acl(VRT_CTX, VCL_ACL acl, VCL_IP ip0, VCL_IP ip1, VCL_INT step)
 	b = WS_Alloc(ctx->ws, sizeof *b + sizeof digest);
 	if (b != NULL) {
 		memcpy(b + 1, digest, sizeof digest);
+		b->magic = VRT_BLOB_MAGIC;
 		b->blob = b + 1;
 		b->len = sizeof digest;
 	}
diff --git a/vmod/vmod_debug_filters.c b/vmod/vmod_debug_filters.c
index cb1dd2bd0..9dc692151 100644
--- a/vmod/vmod_debug_filters.c
+++ b/vmod/vmod_debug_filters.c
@@ -702,7 +702,7 @@ xyzzy_chksha256(VRT_CTX, VCL_BLOB blob, VCL_ENUM mode_e)
 	size_t l;
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
-	AN(blob);
+	CHECK_OBJ_NOTNULL(blob, VRT_BLOB_MAGIC);
 	XXXAN(blob->blob);
 	XXXAN(blob->len);
 
diff --git a/vmod/vmod_directors_shard.c b/vmod/vmod_directors_shard.c
index cb70c67f4..2467ce291 100644
--- a/vmod/vmod_directors_shard.c
+++ b/vmod/vmod_directors_shard.c
@@ -454,7 +454,7 @@ shard_blob_key(VCL_BLOB key_blob)
 	const uint8_t *b;
 	size_t i, ki;
 
-	AN(key_blob);
+	CHECK_OBJ_NOTNULL(key_blob, VRT_BLOB_MAGIC);
 	AN(key_blob->blob);
 	assert(key_blob->len > 0);
 
@@ -546,6 +546,7 @@ shard_param_args(VRT_CTX,
 			    func, by_s);
 			return (NULL);
 		}
+		CHECK_OBJ_ORNULL(key_blob, VRT_BLOB_MAGIC);
 		if (key_blob == NULL || key_blob->len == 0 ||
 		    key_blob->blob == NULL) {
 			shard_err(ctx->vsl, p->vcl_name,
@@ -1092,6 +1093,7 @@ shard_param_blob(VCL_BLOB blob)
 {
 	const struct vmod_directors_shard_param *p;
 
+	CHECK_OBJ_ORNULL(blob, VRT_BLOB_MAGIC);
 	if (blob && blob->type == VMOD_SHARD_SHARD_PARAM_BLOB &&
 	    blob->blob != NULL &&
 	    blob->len == sizeof(struct vmod_directors_shard_param)) {
diff --git a/vmod/vmod_std_fileread.c b/vmod/vmod_std_fileread.c
index 39543abf0..e3909ca95 100644
--- a/vmod/vmod_std_fileread.c
+++ b/vmod/vmod_std_fileread.c
@@ -132,6 +132,7 @@ find_frfile(struct vmod_priv *priv, VCL_STRING file_name)
 		REPLACE(frf->file_name, file_name);
 		frf->refcount = 1;
 		frf->contents = s;
+		frf->blob->magic = VRT_BLOB_MAGIC;
 		frf->blob->blob = s;
 		frf->blob->len = (size_t)sz;
 		priv->methods = frfile_methods;


More information about the varnish-commit mailing list