]> git.kaiwu.me - haproxy.git/commit
BUG/MEDIUM: connection: fix an infinite loop in the fc_pp_tlv() fetch
authorWilly Tarreau <w@1wt.eu>
Fri, 21 Aug 2026 15:59:02 +0000 (17:59 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 25 Aug 2026 16:40:15 +0000 (18:40 +0200)
commitfaabedec2330e5307dccadf02d2b4a8b73e8a645
tree4c873e497842000f781a530cdeb002c052b57ce2
parentf572cc242759e521f5f6425c9b9e73a3034ebabf
BUG/MEDIUM: connection: fix an infinite loop in the fc_pp_tlv() fetch

fc_pp_tlv() is a multi-value fetch: it reports one TLV per call, sets
SMP_F_NOT_LAST and stores the TLV it returned in smp->ctx.p so that the next
call resumes from there. But it resumes *on* that TLV rather than after it,
and list_for_each_entry_from() starts on the element it is given, so the same
TLV matches again and is returned again, with SMP_F_NOT_LAST set again.

The ACL engine asks for the next occurrence as long as the fetch reports one
(the "fetch_next" retry in acl_exec_cond()), so an ACL whose pattern does not
match a TLV which is present never terminates: the thread spins at 100% and
the request is never answered. A configuration as simple as

    http-request deny if { fc_pp_tlv(0xE0) -m str nomatch }

hangs as soon as a client sends that TLV on any frontend accepting PROXY
protocol v2.

The same mistake also means the fetch never walked the list at all: only the
first matching TLV was ever visible, so a rule matching any later occurrence
of a repeated TLV silently never matched.

Resume from the element following the one returned previously. When it was
the last one, the resulting pointer is the list head and the loop stops right
away, as it should.

The regtest now sends the same TLV type three times and matches on the last
one, and checks that a pattern matching none of the occurrences terminates.
Without this patch that test hangs until the client times out.

This should fix GitHub issue #3482. Thanks to Annika Wickert for reporting
it!

This should be backported to all stable branches where fc_pp_tlv() exists.
reg-tests/sample_fetches/tlvs.vtc
src/connection.c