You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

59 lines
2.4 KiB

From 8ba50128832bb31e95f06fe4cb2bd172f2b945fe Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Tue, 18 Nov 2014 18:49:19 +0100
Subject: [PATCH 6/6] BUG/MAJOR: frontend: initialize capture pointers earlier
Denys Fedoryshchenko reported and diagnosed a nasty bug caused by TCP
captures, introduced in late 1.5-dev by commit 18bf01e ("MEDIUM: tcp:
add a new tcp-request capture directive"). The problem is that we're
using the array of capture pointers initially designed for HTTP usage
only, and that this array was only reset when starting to process an
HTTP request. In a tcp-only frontend, the pointers are not reset, and
if the capture pool is shared, we can very well point to whatever other
memory location, resulting in random crashes when tcp-request content
captures are processed.
The fix simply consists in initializing these pointers when the pools
are prepared.
A workaround for existing versions consists in either disabling TCP
captures in tcp-only frontends, or in forcing the frontends to work in
HTTP mode.
Thanks to Denys for the amount of testing and detailed reports.
This fix must be backported to 1.5.
(cherry picked from commit 9654e57fac86c773091b892f42015ba2ba56be5a)
---
src/frontend.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/frontend.c b/src/frontend.c
index 3f80774..2928047 100644
--- a/src/frontend.c
+++ b/src/frontend.c
@@ -106,11 +106,17 @@ int frontend_accept(struct session *s)
if (global.tune.client_rcvbuf)
setsockopt(cfd, SOL_SOCKET, SO_RCVBUF, &global.tune.client_rcvbuf, sizeof(global.tune.client_rcvbuf));
- if (unlikely(s->fe->nb_req_cap > 0 && (s->txn.req.cap = pool_alloc2(s->fe->req_cap_pool)) == NULL))
- goto out_return; /* no memory */
+ if (unlikely(s->fe->nb_req_cap > 0)) {
+ if ((s->txn.req.cap = pool_alloc2(s->fe->req_cap_pool)) == NULL)
+ goto out_return; /* no memory */
+ memset(s->txn.req.cap, 0, s->fe->nb_req_cap * sizeof(void *));
+ }
- if (unlikely(s->fe->nb_rsp_cap > 0 && (s->txn.rsp.cap = pool_alloc2(s->fe->rsp_cap_pool)) == NULL))
- goto out_free_reqcap; /* no memory */
+ if (unlikely(s->fe->nb_rsp_cap > 0)) {
+ if ((s->txn.rsp.cap = pool_alloc2(s->fe->rsp_cap_pool)) == NULL)
+ goto out_free_reqcap; /* no memory */
+ memset(s->txn.rsp.cap, 0, s->fe->nb_rsp_cap * sizeof(void *));
+ }
if (s->fe->http_needed) {
/* we have to allocate header indexes only if we know
--
2.0.4