From 300deb04761cfc1f28b40ab36b6231fe8cd00a57 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Thu, 23 Jul 2026 04:16:42 +0000 Subject: [PATCH] Reject an unanswered show_mappings instead of reading it as zero The mapping-reclaimed check expects zero mappings, and read the count with `r.get('data',{}).get('mappings',[])`. An error response carries no data field, so it parsed to zero and satisfied the check without the gateway having answered at all. The expected value and the failure value were the same number, which is the shape that lets an assertion pass without asking anything. Require the key to exist and be a list, and exit non-zero otherwise, so the existing fallback turns an unanswered or malformed response into a failure. The gateway always emits the key on success, including for an empty set, so a genuine zero still reads as zero; confirmed against the running gateway, where the reclamation check passes. The earlier show_mappings poll shares the parse and is left alone: it waits for a positive two, which no error response can produce. The hazard was already documented there, and this is the call site that was exposed to it. --- testing/static/scripts/gateway-test.sh | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/testing/static/scripts/gateway-test.sh b/testing/static/scripts/gateway-test.sh index 1491039..16fc9c2 100755 --- a/testing/static/scripts/gateway-test.sh +++ b/testing/static/scripts/gateway-test.sh @@ -410,10 +410,26 @@ docker exec "$GATEWAY" conntrack -F 2>/dev/null || true echo " Waiting 25s for TTL + grace period to expire (two tick cycles)..." sleep 25 -# Query gateway control socket for mapping count +# Query gateway control socket for mapping count. +# +# The expected value here is zero, so the reader must not be able to +# produce a zero from a failed query: an error response carries no `data` +# field, and `r.get('data',{}).get('mappings',[])` would report that as +# zero mappings and pass this check without the gateway having answered. +# The same hazard is documented at the show_mappings poll above, which is +# safe only because it waits for a positive "2". Require the key to exist +# and exit non-zero if it does not, so the `|| echo "error"` fallback +# fires and the check reds. MAPPING_COUNT=$(docker exec "$GATEWAY" bash -c \ 'echo "{\"command\":\"show_mappings\"}" | nc -U -w1 /run/fips/gateway.sock 2>/dev/null' \ - | python3 -c "import sys,json; r=json.load(sys.stdin); print(len(r.get('data',{}).get('mappings',[])))" 2>/dev/null || echo "error") + | python3 -c " +import sys, json +r = json.load(sys.stdin) +data = r.get('data') +if not isinstance(data, dict) or not isinstance(data.get('mappings'), list): + sys.exit(1) +print(len(data['mappings'])) +" 2>/dev/null || echo "error") if [ "$MAPPING_COUNT" = "0" ]; then check "Mapping reclaimed after TTL+grace" 0 else