[master] 7fd3aa3 Don't let the form of the argument to hash_data() leak into the production of the hash-key.
Poul-Henning Kamp
phk at varnish-cache.org
Wed May 1 15:14:02 CEST 2013
commit 7fd3aa3f8fdf97185af22ce9e71c338933ee1cc0
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed May 1 13:13:16 2013 +0000
Don't let the form of the argument to hash_data() leak into the
production of the hash-key.
Fixes #1296
diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index eab4907..3f4fb79 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -155,20 +155,15 @@ HSH_DeleteObjHead(struct dstat *ds, struct objhead *oh)
}
void
-HSH_AddString(struct req *req, const char *str)
+HSH_AddString(const struct req *req, const char *str)
{
- int l;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
- if (str == NULL)
- str = "";
- l = strlen(str);
-
AN(req->sha256ctx);
- SHA256_Update(req->sha256ctx, str, l);
- SHA256_Update(req->sha256ctx, "#", 1);
-
- VSLb(req->vsl, SLT_Hash, "%s", str);
+ if (str != NULL)
+ SHA256_Update(req->sha256ctx, str, strlen(str));
+ else
+ SHA256_Update(req->sha256ctx, &str, sizeof str);
}
/*---------------------------------------------------------------------
diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index a298ad7..8d0ee46 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -257,7 +257,7 @@ VRT_handling(const struct vrt_ctx *ctx, unsigned hand)
}
/*--------------------------------------------------------------------
- * Add an element to the array/list of hash bits.
+ * Feed data into the hash calculation
*/
void
@@ -275,7 +275,13 @@ VRT_hashdata(const struct vrt_ctx *ctx, const char *str, ...)
if (p == vrt_magic_string_end)
break;
HSH_AddString(ctx->req, p);
+ VSLb(ctx->vsl, SLT_Hash, "%s", str);
}
+ /*
+ * Add a 'field-separator' to make it more difficult to
+ * manipulate the hash.
+ */
+ HSH_AddString(ctx->req, NULL);
}
/*--------------------------------------------------------------------*/
diff --git a/bin/varnishd/hash/hash_slinger.h b/bin/varnishd/hash/hash_slinger.h
index 8a3d08b..3c36b4d 100644
--- a/bin/varnishd/hash/hash_slinger.h
+++ b/bin/varnishd/hash/hash_slinger.h
@@ -69,7 +69,7 @@ enum lookup_e HSH_Lookup(struct req *, struct objcore **, struct objcore **,
void HSH_Ref(struct objcore *o);
void HSH_Drop(struct worker *, struct object **);
void HSH_Init(const struct hash_slinger *slinger);
-void HSH_AddString(struct req *, const char *str);
+void HSH_AddString(const struct req *, const char *str);
void HSH_Insert(struct worker *, const void *hash, struct objcore *);
void HSH_Purge(struct req *, struct objhead *, double ttl, double grace);
void HSH_config(const char *h_arg);
diff --git a/bin/varnishtest/tests/r01296.vtc b/bin/varnishtest/tests/r01296.vtc
new file mode 100644
index 0000000..f9f8de4
--- /dev/null
+++ b/bin/varnishtest/tests/r01296.vtc
@@ -0,0 +1,30 @@
+varnishtest "hash key depends on argument form to hash_data()"
+
+server s1 {
+ rxreq
+ txresp -hdr "OK: yes"
+ rxreq
+ txresp -hdr "OK: no"
+} -start
+
+varnish v1 -vcl+backend {
+
+ sub vcl_hash {
+ if (req.http.foo == "1") {
+ hash_data("123");
+ } else {
+ hash_data("1" + req.http.foo + "3");
+ }
+ return (hash);
+ }
+} -start
+
+client c1 {
+ txreq -hdr "foo: 1"
+ rxresp
+ expect resp.http.ok == "yes"
+
+ txreq -hdr "foo: 2"
+ rxresp
+ expect resp.http.ok == "yes"
+} -run
More information about the varnish-commit
mailing list