[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