BUG/MEDIUM: protobuf: adjust sample size capacity after pointer shift
This bug impacts "protobuf" and "ungrpc" sample fetches.
When extracting fields from a payload, the data pointer
"smp->data.u.str.area" is forwarded to point directly onto the decoded
sub-field data. However, the sample's maximum capacity size tracking property
"smp->data.u.str.size" was left untouched, remaining set to the total
original buffer size (e.g., tune.bufsize).
This creates an architectural size mismatch. Subsequent processing layers or
converters (such as stick-tables executing padding mechanisms via memset())
may assume that the original total capacity is still fully available starting
from the new forwarded offset. In specific configurations involving writable
cloned buffers (e.g., combining "lower" and "protobuf" converters before
tracking key storage), this logical flaw can easily lead to out-of-bounds
heap memory corruption or crashes.
Under rare conditions, depending on the specific combination of frontend
configurations (e.g., use of wait-for-body rules) and the alignment of
incoming HTTP requests containing specific chunked or large payload patterns,
this out-of-bounds write could lead to an immediate haproxy process crash
or data corruption.
Fix this by introducing "protobuf_adjust_smp_size()". This inline function
safely computes the consumed byte offset after each pointer shift and
decrements the sample's residual capacity size accordingly before updating
the payload reference. All "protobuf_smp_store_*" callbacks are updated.
Many thanks to Red Hat and AISLE Research for reporting this.