]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: sample: fix NULL dereference in the ltime/utime converters
authorMartin Mirchev <mirchevmartin2203@gmail.com>
Wed, 28 Oct 2026 14:33:16 +0000 (22:33 +0800)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 30 Oct 2026 09:33:13 +0000 (10:33 +0100)
conv_time_common() returns NULL when alloc_trash_chunk() fails, and when
the format string expanded for "%N" does not fit in the trash chunk. Its
four callers, sample_conv_us_ltime(), sample_conv_ms_ltime(),
sample_conv_us_utime() and sample_conv_ms_utime(), dereference the
result without checking it.

A configuration using one of these converters with a long format, e.g.
ms_ltime("%N%N%N...") expanding to more than bufsize, is accepted by
"haproxy -c", and the first request evaluating it crashes the process
with a NULL dereference. A failed allocation at runtime has the same
effect with an ordinary format.

Let's make the converter fail instead, like on its other error paths.

This fixes GitHub issue #3545.

This must be backported to all stable versions up to 3.0, as commit
5e63e1636 introduced the first version of conv_time_common() with a
possible NULL return.

src/sample.c

index efdd8138db470fa3030f3eada6c6271ae025800f..ba50695df50fb1aacf7bf32528e88c707476ab5b 100644 (file)
@@ -2732,6 +2732,8 @@ static int sample_conv_us_ltime(const struct arg *args, struct sample *smp, void
        ns = (date % 1000000) * 1000; /*  us part to ns */
 
        temp = conv_time_common(args[0].data.str.area, curr_date, ns, 1);
+       if (!temp)
+               return 0;
        smp->data.u.str = *temp;
        smp->data.type = SMP_T_STR;
        return 1;
@@ -2755,6 +2757,8 @@ static int sample_conv_ms_ltime(const struct arg *args, struct sample *smp, void
        ns = (date % 1000) * 1000000; /*  ms part to ns */
 
        temp = conv_time_common(args[0].data.str.area, curr_date, ns, 1);
+       if (!temp)
+               return 0;
        smp->data.u.str = *temp;
        smp->data.type = SMP_T_STR;
        return 1;
@@ -2814,6 +2818,8 @@ static int sample_conv_us_utime(const struct arg *args, struct sample *smp, void
        ns = (date % 1000000) * 1000; /*  us part to ns */
 
        temp = conv_time_common(args[0].data.str.area, curr_date, ns, 0);
+       if (!temp)
+               return 0;
        smp->data.u.str = *temp;
        smp->data.type = SMP_T_STR;
        return 1;
@@ -2837,6 +2843,8 @@ static int sample_conv_ms_utime(const struct arg *args, struct sample *smp, void
        ns = (date % 1000) * 1000000; /*  ms part to ns */
 
        temp = conv_time_common(args[0].data.str.area, curr_date, ns, 0);
+       if (!temp)
+               return 0;
        smp->data.u.str = *temp;
        smp->data.type = SMP_T_STR;
        return 1;