]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: sample: limit the be2hex converter's chunk size
authorWilly Tarreau <w@1wt.eu>
Sat, 23 May 2026 17:59:31 +0000 (19:59 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 25 May 2026 08:57:13 +0000 (10:57 +0200)
In 2.5, commit da0264a96 ("MINOR: sample: Add be2hex converter")
introduced the be2hex() converter, which reads input data of a given
chunk size, processes it as a big endian block and turns it to hex
output.

There's an issue if the configured chunk_size (2nd argument) is larger
than tune.bufsize/2, because the max_size calculation will underflow,
and the later loop will always match since it compares a size_t to an
int (BTW, compilers love to annoy us with useless warnings but I never
found how to see some for these ones). This can result in overflowing
the output trash if  the input sample is at least as large as half a
buffer.

Let's add an explicit check for this, and change the max_size type to
size_t so that the comparison is always right. While we're at it, let's
ask the trash buffer to be twice as large, just like bin2hex() does, as
it may result in offering a larger buffer in 3.4. thanks to the large
buffers support.

Despite the risk, this is marked as minor because a config with that
large an argument in the converter makes absolutely no sense.

This should be backported to 2.6. The *2 for the trash allocation will
conflict and have to be dropped in stable versions, which is safe.

src/sample.c

index f032ec4bbe7949bcbae1ea65012626a057f42378..7b636129a113b501f1526e8b818495c14f2f0ee6 100644 (file)
@@ -2150,11 +2150,11 @@ static int sample_conv_be2hex_check(struct arg *args, struct sample_conv *conv,
  */
 static int sample_conv_be2hex(const struct arg *args, struct sample *smp, void *private)
 {
-       struct buffer *trash = get_trash_chunk_sz(smp->data.u.str.data);
+       struct buffer *trash = get_trash_chunk_sz(smp->data.u.str.data * 2);
        int chunk_size = args[1].data.sint;
        const int last = args[2].data.sint ? smp->data.u.str.data - chunk_size + 1 : smp->data.u.str.data;
        int i;
-       int max_size;
+       size_t max_size;
        int ptr = 0;
        unsigned char c;
 
@@ -2163,7 +2163,9 @@ static int sample_conv_be2hex(const struct arg *args, struct sample *smp, void *
        trash->data = 0;
        if (args[0].data.str.data == 0 && args[2].data.sint == 0)
                chunk_size = smp->data.u.str.data;
-       max_size = trash->size - 2 * chunk_size;
+       if (2 * (size_t)chunk_size > trash->size)
+               return 0;
+       max_size = trash->size - 2 * (size_t)chunk_size;
 
        while (ptr < last && trash->data <= max_size) {
                if (ptr) {