BUG/MEDIUM: http-ana: Fix memleak in redirect rules with ignore-empty option
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 26 Apr 2022 18:34:38 +0000 (20:34 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 26 Apr 2022 18:47:22 +0000 (20:47 +0200)
A memory leak was introduced when ignore-empty option was added to redirect
rules. If there is no location, when this option is set, the redirection is
aborted and the processing continues. But when this happened, the trash buffer
allocated to format the redirect response was not released.

The bug was introduced by commit bc1223be7 ("MINOR: http-rules: add a new
"ignore-empty" option to redirects.").

This patch should fix the issue #1675. It must be backported to 2.5.

src/http_ana.c

index 187b881..7a987a5 100644 (file)
@@ -2348,7 +2348,7 @@ int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struc
        struct buffer *chunk;
        struct ist status, reason, location;
        unsigned int flags;
-       int close = 0; /* Try to keep the connection alive byt default */
+       int ret = 1, close = 0; /* Try to keep the connection alive byt default */
 
        chunk = alloc_trash_chunk();
        if (!chunk) {
@@ -2483,8 +2483,10 @@ int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struc
                                int len = build_logline(s, chunk->area + chunk->data,
                                                        chunk->size - chunk->data,
                                                        &rule->rdr_fmt);
-                               if (!len && rule->flags & REDIRECT_FLAG_IGNORE_EMPTY)
-                                       return 2;
+                               if (!len && rule->flags & REDIRECT_FLAG_IGNORE_EMPTY) {
+                                       ret = 2;
+                                       goto out;
+                               }
 
                                chunk->data += len;
                        }
@@ -2571,15 +2573,16 @@ int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s, struc
        if (!(s->flags & SF_FINST_MASK))
                s->flags |= ((rule->flags & REDIRECT_FLAG_FROM_REQ) ? SF_FINST_R : SF_FINST_H);
 
+  out:
        free_trash_chunk(chunk);
-       return 1;
+       return ret;
 
   fail:
        /* If an error occurred, remove the incomplete HTTP response from the
         * buffer */
        channel_htx_truncate(res, htxbuf(&res->buf));
-       free_trash_chunk(chunk);
-       return 0;
+       ret = 0;
+       goto out;
 }
 
 /* Replace all headers matching the name <name>. The header value is replaced if