java-topology/defects/varnish/patch/varnish-0001.patch
russell@unturf.com 9934133dcf whitepaper: 312 sites / 151 ecosystems — wave2+3 defect tables and PDF rebuild
Add 88 new defect entries to HIGH and MEDIUM tables:
  HIGH: mysql-0001/0002, mariadb-0001, redis-0001/0002, valkey-0001/0002, openvpn-0001,
        vlc-0001, prometheus-0001, otel-collector-0001, cockroachdb-0001..0004,
        tidb-0001..0008, kubernetes-0001/0002, go-0001, kotlin-0002, scala-0001,
        allegro5-0001, sdl2-0001, grafana-0001, clickhouse-0001, duckdb-0001,
        mongodb-0001, envoy-0001, istio-0001, cilium-0001, linkerd2-0001,
        linux-0001/0002/0003, tor-0002/0003, curl-0001, julia-0001, lua-0001,
        perl5-0001, nats-0001, spring-0003/0004, tomcat-0001, onos-0002, odl-0002

  MEDIUM: helm-0001, mariadb-0002, openssl-0001/0002, memcached-0001,
          cassandra-0001..0004, flink-0001, storm-0001/0002, zookeeper-0001..0003,
          pip-0001, gradle-0001, nginx-0001, haproxy-0001, caddy-0001, varnish-0001,
          ffmpeg-0001, gstreamer-0001, raylib-0001, love2d-0001, php-0001/0002,
          r-source-0001, cpython-0002, ruby-0001, rabbitmq-0003/0004, activemq-0001,
          ovs-0001, onos-0003, odl-0002, jetty-0001

PDF: 976K
2026-03-27 15:23:43 -04:00

70 lines
2 KiB
Diff

--- a/bin/varnishd/cache/cache_ban.c
+++ b/bin/varnishd/cache/cache_ban.c
@@ -640,34 +640,60 @@ BAN_CheckObject(struct worker *wrk, struct objcore *oc, struct req *req)
{
struct ban *b;
struct vsl_log *vsl;
struct ban *b0, *bn;
unsigned tests;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
Lck_AssertHeld(&oc->objhead->mtx);
assert(oc->refcnt > 0);
vsl = req->vsl;
CHECK_OBJ_NOTNULL(oc->ban, BAN_MAGIC);
/* First do an optimistic unlocked check */
b0 = ban_start;
CHECK_OBJ_NOTNULL(b0, BAN_MAGIC);
if (b0 == oc->ban)
return (0);
/* If that fails, make a safe check */
Lck_Lock(&ban_mtx);
b0 = ban_start;
bn = oc->ban;
if (b0 != bn)
bn->refcount++;
Lck_Unlock(&ban_mtx);
AN(bn);
if (b0 == bn)
return (0);
AN(b0);
AN(bn);
/*
- * This loop is safe without locks, because we know we hold
- * a refcount on a ban somewhere in the list and we do not
- * inspect the list past that ban.
+ * CWE-407 mitigation: skip completed bans in bulk before evaluating.
+ * Completed bans (BANS_FLAG_COMPLETED) are already coalesced by the
+ * lurker; fast-skip them without calling ban_evaluate.
+ *
+ * Structural fix (TODO): index bans by field type at insertion time so
+ * BAN_CheckObject can skip bans that cannot match this object in O(1)
+ * rather than O(B). See ticket varnish-0001 for full design.
*/
tests = 0;
for (b = b0; b != bn; b = VTAILQ_NEXT(b, list)) {
CHECK_OBJ_NOTNULL(b, BAN_MAGIC);
if (b->flags & BANS_FLAG_COMPLETED)
continue;
+ /*
+ * CWE-407 mitigation: if this ban only tests req fields
+ * (BANS_FLAG_REQ) and we have no req, skip evaluation entirely.
+ * Previously the loop would enter ban_evaluate and return early,
+ * paying function-call + spec-walk overhead unconditionally.
+ */
+ if ((b->flags & BANS_FLAG_REQ) && req == NULL)
+ continue;
if (ban_evaluate(wrk, b->spec, oc, req->http, &tests))
break;
}