]> git.kaiwu.me - haproxy.git/commit
BUG/MEDIUM: peers: check the available room before encoding dict values
authorMatt Suiche <matt@tolmo.com>
Tue, 28 Jul 2026 13:51:09 +0000 (15:51 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 28 Jul 2026 15:00:54 +0000 (17:00 +0200)
commit3db607707f59e25de1280745e9a7795d07267956
tree53ef3c32326718de9459c7ca5629c0b3ce2ad411
parentae819a08e73d076fddebfc94196dbedb887f4901
BUG/MEDIUM: peers: check the available room before encoding dict values

peer_prepare_updatemsg() encodes stick-table entries into an update
message of <size> bytes but never checks that the encoded data actually
fits (the function still carries its "TODO: check size" comment). For
entries holding a server_key, the dictionary value, up to ~16 KB, is
copied unconditionally:

    /* Encode the length of the dictionary entry data */
    value_len = de->len;
    intencode(value_len, &end);
    /* Copy the data */
    memcpy(end, de->value.key, value_len);

The peers protocol is plaintext and unauthenticated, so a remote peer
can plant an entry whose server_key is larger than the room left in the
buffer. When the victim later teaches that entry, the memcpy() above
writes past the end of the 16384-byte trash buffer; this was confirmed
under ASan as a heap-buffer-overflow WRITE of size 16360, and it fires
again on every teach retry at the same address.

Let's verify that the value fits in the buffer before copying it, and
return 0 ("unable to encode the message") when it does not, which is
how the function already reports its other encoding failures.

This must be backported to all supported versions (server_key in
stick-tables dates back to 2.4).
src/peers.c