]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: sample: Fix freeing of conv_exprs in release_sample_expr
authorTim Duesterhus <tim@bastelstu.be>
Sat, 4 Jul 2020 09:49:39 +0000 (11:49 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 7 Jul 2020 14:52:35 +0000 (16:52 +0200)
Instead of just calling release_sample_arg(conv_expr->arg_p) we also must
free() the conv_expr itself (after removing it from the list).

Given the following example configuration:

    frontend foo
     bind *:8080
     mode http
     http-request set-var(txn.foo) str(bar)
     acl is_match str(foo),strcmp(txn.hash) -m bool

Running a configuration check within valgrind reports:

    ==1431== 32 bytes in 1 blocks are definitely lost in loss record 20 of 43
    ==1431==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==1431==    by 0x4C39B5: sample_parse_expr (sample.c:982)
    ==1431==    by 0x56B410: parse_acl_expr (acl.c:319)
    ==1431==    by 0x56BA7F: parse_acl (acl.c:697)
    ==1431==    by 0x48D225: cfg_parse_listen (cfgparse-listen.c:816)
    ==1431==    by 0x4797C3: readcfgfile (cfgparse.c:2167)
    ==1431==    by 0x52943D: init (haproxy.c:2021)
    ==1431==    by 0x41F382: main (haproxy.c:3133)

After this patch is applied the leak is gone as expected.

This is a fairly minor leak that can only be observed if samples need to be
freed, which is not something that should occur during normal processing and
most likely only during shut down. Thus no backport should be needed.

src/sample.c

index e09b4c09fdeff3327d79c2b3a3fef78bd0f3e074..650b6d5de699ed5abe21944ee1cc8f6e37afed78 100644 (file)
@@ -1424,8 +1424,12 @@ void release_sample_expr(struct sample_expr *expr)
        if (!expr)
                return;
 
-       list_for_each_entry_safe(conv_expr, conv_exprb, &expr->conv_exprs, list)
+       list_for_each_entry_safe(conv_expr, conv_exprb, &expr->conv_exprs, list) {
+               LIST_DEL(&conv_expr->list);
                release_sample_arg(conv_expr->arg_p);
+               free(conv_expr);
+       }
+
        release_sample_arg(expr->arg_p);
        free(expr);
 }