Re: haproxy 1.7.5 segfault on cookie/header parsing.

2017-06-11 Thread Willy Tarreau
Hi Jean,

I finally found it by carefully unrolling the execution based on your core.
It's a regression introduced in 1.7 while fixing a problem of missing cookies
in logs when doing a tarpit... I could finally reproduce it and fix it with
the attached patch.

Thanks a lot for all the details you provided!

Willy
>From 6a0bca9e7862984b0edf8fc1e1edc54295a7a5e2 Mon Sep 17 00:00:00 2001
From: Willy Tarreau 
Date: Sun, 11 Jun 2017 17:56:27 +0200
Subject: BUG/MAJOR: http: call manage_client_side_cookies() before erasing
 the buffer

Jean Lubatti reported a crash on haproxy using a config involving cookies
and tarpit rules. It just happens that since 1.7-dev3 with commit 83a2c3d
("BUG/MINOR : allow to log cookie for tarpit and denied request"), function
manage_client_side_cookies() was called after erasing the request buffer in
case of a tarpit action. The problem is that this function must absolutely
not be called with an empty buffer since it moves parts of it. A typical
reproducer consists in sending :

"GET / HTTP/1.1\r\nCookie: S=1\r\n\r\n"

On such a config :

listen crash
bind :8001
mode http
reqitarpit .
cookie S insert indirect
server s1 127.0.0.1:8000 cookie 1

The fix simply consists in moving the call to the function before the call
to buffer_erase().

Many thanks to Jean for testing instrumented code and providing a usable
core.

This fix must be backported to all stable versions since the fix introducing
this bug was backported as well.
---
 src/proto_http.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/proto_http.c b/src/proto_http.c
index 357401f..a72f302 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -4462,6 +4462,11 @@ int http_process_req_common(struct stream *s, struct 
channel *req, int an_bit, s
return 1;
 
  tarpit:
+   /* Allow cookie logging
+*/
+   if (s->be->cookie_name || sess->fe->capture_name)
+   manage_client_side_cookies(s, req);
+
/* When a connection is tarpitted, we use the tarpit timeout,
 * which may be the same as the connect timeout if unspecified.
 * If unset, then set it to zero because we really want it to
@@ -4474,11 +4479,6 @@ int http_process_req_common(struct stream *s, struct 
channel *req, int an_bit, s
 */
channel_dont_connect(req);
 
-   /* Allow cookie logging
-*/
-   if (s->be->cookie_name || sess->fe->capture_name)
-   manage_client_side_cookies(s, req);
-
txn->status = http_err_codes[deny_status];
 
req->analysers &= AN_REQ_FLT_END; /* remove switching rules etc... */
-- 
1.7.12.1



Re: haproxy 1.7.5 segfault on cookie/header parsing.

2017-05-29 Thread Willy Tarreau
Hi Jean,

On Sun, May 28, 2017 at 10:15:28AM +, Jean LUBATTI wrote:
> There was a tcp-request inspect-delay of 2s in the configuration when running
> the repro, so it should be fine.

OK. However, I totally fail to reproduce the problem here using your config,
the build options I found in your executable, and the captured requests, they
are properly handled and passed. And since the crash happens inside memmove(),
the memory is displaced everywhere and the internal structures are not much
analyzable.

Could you please try again with the attached patch ? It's supposed to provoke
a segfault before the bogus call to memmove(), resulting in a "clean" core.

Thanks,
Willy
diff --git a/src/buffer.c b/src/buffer.c
index 4f8f647..70a01dd 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -87,6 +87,9 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, 
const char *str, int
return 0;  /* no space left before wrapping data */
 
/* first, protect the end of the buffer */
+   if (bi_end(b) < end)
+   *(volatile int *)0 = 0;
+
memmove(end + delta, end, bi_end(b) - end);
 
/* now, copy str over pos */


Re: haproxy 1.7.5 segfault on cookie/header parsing.

2017-05-28 Thread Jean LUBATTI
There was a tcp-request inspect-delay of 2s in the configuration when running 
the repro, so it should be fine.


Sent from my iPhone

> On 28 May 2017, at 11:41, Willy Tarreau  wrote:
>
> Hi Jean,
>
>> On Sun, May 28, 2017 at 09:15:56AM +, Jean LUBATTI wrote:
>> Hi Willy,
>>
>> I just tried the line  "tcp-request content capture req.hdrs_bin len 2000" 
>> in the config but I get:
>>
>> [ALERT] 147/073131 (13352) : parsing [/etc/haproxy/haproxy.cfg:42] : 
>> 'tcp-request content capture' : unknown fetch method 'req.hdrs_bin'
>> [ALERT] 147/073131 (13352) : Error(s) found in configuration file : 
>> /etc/haproxy/haproxy.cfg
>> [ALERT] 147/073131 (13352) : Fatal errors found in configuration.
>> Errors found in configuration file, check it with 'haproxy check'.
>
> Sorry, this one is only in 1.8-dev.
>
>> I changed it to :
>>
>> tcp-request content capture req.payload(0,2000) len 2000
>>
>> but I  don't think it works (at least not when inspecting the core on 
>> s->req).
>
> Ah, I forgot to mention you need to allow a delay for the request to arrive,
> you need to add this :
>
>tcp-request inspect-delay 10s
>
> (for example)
>
>> Here is the output of haproxy running under gdb when the attack happens:
>>
>> 01d7:ft_appmarket_preprod_services_ingenico_com_443.clireq[0027:]:
>>  GET /wp-content/uploads/ HTTP/1.1
>> 01d7:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0027:]:
>>  Host: 185.139.245.111
>> 01d7:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0027:]:
>>  User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:40.0) Gecko/20100101 
>> Firefox/40.0
>> 01d7:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0027:]:
>>  Cookie: SERVERID=ppmktplportals01fe
>> 01d7:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0027:]:
>>  Accept-Encoding: gzip
>> 01d8:ft_appmarket_preprod_services_ingenico_com_443.clireq[0028:]:
>>  GET /wp-content/uploads/2015/ HTTP/1.1
>> 01d8:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0028:]:
>>  Host: 185.139.245.111
>> 01d8:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0028:]:
>>  User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:40.0) Gecko/20100101 
>> Firefox/40.0
>> 01d8:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0028:]:
>>  Cookie: SERVERID=ppmktplportals01fe
>> 01d8:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0028:]:
>>  Accept-Encoding: gzip
>> 01d7:appmarket_preprod_services_ingenico_com_8443.srvrep[0027:0029]: 
>> HTTP/1.1 404 Not Found
>> 01d7:appmarket_preprod_services_ingenico_com_8443.srvhdr[0027:0029]: 
>> Server: Apache-Coyote/1.1
>> 01d7:appmarket_preprod_services_ingenico_com_8443.srvhdr[0027:0029]: 
>> Content-Length: 0
>> 01d7:appmarket_preprod_services_ingenico_com_8443.srvhdr[0027:0029]: 
>> Date: Sun, 28 May 2017 09:03:04 GMT
>> 01d7:appmarket_preprod_services_ingenico_com_8443.srvhdr[0027:0029]: 
>> Connection: close
>> 01d8:appmarket_preprod_services_ingenico_com_8443.srvrep[0028:002a]: 
>> HTTP/1.1 404 Not Found
>> 01d8:appmarket_preprod_services_ingenico_com_8443.srvhdr[0028:002a]: 
>> Server: Apache-Coyote/1.1
>> 01d8:appmarket_preprod_services_ingenico_com_8443.srvhdr[0028:002a]: 
>> Content-Length: 0
>> 01d8:appmarket_preprod_services_ingenico_com_8443.srvhdr[0028:002a]: 
>> Date: Sun, 28 May 2017 09:03:04 GMT
>> 01d8:appmarket_preprod_services_ingenico_com_8443.srvhdr[0028:002a]: 
>> Connection: close
>> 01d9:ft_appmarket_preprod_services_ingenico_com_443.clireq[0025:]:
>>  GET /language/en-GB/en-GB.xml HTTP/1.1
>> 01d9:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0025:]:
>>  Host: 185.139.245.111
>> 01d9:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0025:]:
>>  User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:40.0) Gecko/20100101 
>> Firefox/40.0
>> 01d9:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0025:]:
>>  Cookie: SERVERID=ppmktplportals01fe
>> 01d9:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0025:]:
>>  Accept-Encoding: gzip
>>
>> Program received signal SIGSEGV, Segmentation fault.
>> _wordcopy_fwd_dest_aligned (dstp=14712784, srcp=14712832, 
>> len=2305843009213203548) at wordcopy.c:196
>> 196   a0 = ((op_t *) srcp)[0];
>> (gdb)
>>
>> Attaching to the mail the core and the binary.
>
> Thanks for all this, I think I should be able to reproduce it with all this,
> otherwise I'll recontact you :-)
>
> Thanks!
> Willy
This email and its content belong to Ingenico Group. The enclosed information 
is confidential and may not be disclosed to any unauthorized person. If you 
have received it by mistake do not forward it and delete it from your system. 
Cet email et son contenu sont la propriété du Groupe Ingenico. L’information 
qu’il contient est confidentielle et ne peut être communiquée à des 

Re: haproxy 1.7.5 segfault on cookie/header parsing.

2017-05-28 Thread Willy Tarreau
Hi Jean,

On Sun, May 28, 2017 at 09:15:56AM +, Jean LUBATTI wrote:
> Hi Willy,
> 
> I just tried the line  "tcp-request content capture req.hdrs_bin len 2000" in 
> the config but I get:
> 
> [ALERT] 147/073131 (13352) : parsing [/etc/haproxy/haproxy.cfg:42] : 
> 'tcp-request content capture' : unknown fetch method 'req.hdrs_bin'
> [ALERT] 147/073131 (13352) : Error(s) found in configuration file : 
> /etc/haproxy/haproxy.cfg
> [ALERT] 147/073131 (13352) : Fatal errors found in configuration.
> Errors found in configuration file, check it with 'haproxy check'.

Sorry, this one is only in 1.8-dev.

> I changed it to :
> 
> tcp-request content capture req.payload(0,2000) len 2000
> 
> but I  don't think it works (at least not when inspecting the core on s->req).

Ah, I forgot to mention you need to allow a delay for the request to arrive,
you need to add this :

tcp-request inspect-delay 10s

(for example)

> Here is the output of haproxy running under gdb when the attack happens:
> 
> 01d7:ft_appmarket_preprod_services_ingenico_com_443.clireq[0027:]:
>  GET /wp-content/uploads/ HTTP/1.1
> 01d7:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0027:]:
>  Host: 185.139.245.111
> 01d7:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0027:]:
>  User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:40.0) Gecko/20100101 
> Firefox/40.0
> 01d7:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0027:]:
>  Cookie: SERVERID=ppmktplportals01fe
> 01d7:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0027:]:
>  Accept-Encoding: gzip
> 01d8:ft_appmarket_preprod_services_ingenico_com_443.clireq[0028:]:
>  GET /wp-content/uploads/2015/ HTTP/1.1
> 01d8:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0028:]:
>  Host: 185.139.245.111
> 01d8:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0028:]:
>  User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:40.0) Gecko/20100101 
> Firefox/40.0
> 01d8:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0028:]:
>  Cookie: SERVERID=ppmktplportals01fe
> 01d8:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0028:]:
>  Accept-Encoding: gzip
> 01d7:appmarket_preprod_services_ingenico_com_8443.srvrep[0027:0029]: 
> HTTP/1.1 404 Not Found
> 01d7:appmarket_preprod_services_ingenico_com_8443.srvhdr[0027:0029]: 
> Server: Apache-Coyote/1.1
> 01d7:appmarket_preprod_services_ingenico_com_8443.srvhdr[0027:0029]: 
> Content-Length: 0
> 01d7:appmarket_preprod_services_ingenico_com_8443.srvhdr[0027:0029]: 
> Date: Sun, 28 May 2017 09:03:04 GMT
> 01d7:appmarket_preprod_services_ingenico_com_8443.srvhdr[0027:0029]: 
> Connection: close
> 01d8:appmarket_preprod_services_ingenico_com_8443.srvrep[0028:002a]: 
> HTTP/1.1 404 Not Found
> 01d8:appmarket_preprod_services_ingenico_com_8443.srvhdr[0028:002a]: 
> Server: Apache-Coyote/1.1
> 01d8:appmarket_preprod_services_ingenico_com_8443.srvhdr[0028:002a]: 
> Content-Length: 0
> 01d8:appmarket_preprod_services_ingenico_com_8443.srvhdr[0028:002a]: 
> Date: Sun, 28 May 2017 09:03:04 GMT
> 01d8:appmarket_preprod_services_ingenico_com_8443.srvhdr[0028:002a]: 
> Connection: close
> 01d9:ft_appmarket_preprod_services_ingenico_com_443.clireq[0025:]:
>  GET /language/en-GB/en-GB.xml HTTP/1.1
> 01d9:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0025:]:
>  Host: 185.139.245.111
> 01d9:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0025:]:
>  User-Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:40.0) Gecko/20100101 
> Firefox/40.0
> 01d9:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0025:]:
>  Cookie: SERVERID=ppmktplportals01fe
> 01d9:ft_appmarket_preprod_services_ingenico_com_443.clihdr[0025:]:
>  Accept-Encoding: gzip
> 
> Program received signal SIGSEGV, Segmentation fault.
> _wordcopy_fwd_dest_aligned (dstp=14712784, srcp=14712832, 
> len=2305843009213203548) at wordcopy.c:196
> 196   a0 = ((op_t *) srcp)[0];
> (gdb)
> 
> Attaching to the mail the core and the binary.

Thanks for all this, I think I should be able to reproduce it with all this,
otherwise I'll recontact you :-)

Thanks!
Willy



Re: haproxy 1.7.5 segfault on cookie/header parsing.

2017-05-26 Thread Willy Tarreau
Hello Jean,

On Fri, May 26, 2017 at 01:00:17PM +, Jean LUBATTI wrote:
> Hello,
> 
> When using a vulnerability scanner on haproxy 1.7.5, we discovered a scenario
> under which the haproxy segfaults.
> 
> Unfortunately, this is a "bundled" scanner whith no access to the exact
> requests, and the haproxy terminates the SSL for https, so not easy to
> capture the actual traffic, but we managed to gather a core of haproxy.

You could run haproxy with "-d", it will dump to stdout/stderr each header
line it receives. I even think we could get a complete capture of the whole
request like this :

   tcp-request content capture req.hdrs_bin len 2000

It will then appear in the core in s->req_cap.

> This happens only when using the cookie SERVERID for session stickiness:

We've had similar issues a very long time ago, I hoped they were fixed :-/

> The backtrace is as follow:
> 
> I believe the scanner injects a screwed up header and/or cookie. The result 
> appears to be the incorrect memmove of the last header line :
> 
> (gdb) bt full
> #0  _wordcopy_fwd_dest_aligned (dstp=14237664, srcp=14237696, 
> len=2305843009213653720) at wordcopy.c:196
> a0 = 
> a1 = 
> a2 = 0
> a3 = 0
> sh_1 = 40
> sh_2 = 24
> #1  0x003727a838be in memmove (dest=0xd4575d, src=, 
> len=18446744073709551439) at memmove.c:73
> dstp = 
> srcp = 
> #2  0x00411217 in buffer_replace2 (b=0xd456b0, pos=0xd4575d 
> "Accept-Encoding: gzip\r\n\r\n.32.31\r\nConnection: close\r\n\r\nre\r\n\r\n", 
> end=, str=0x0, len=0) at src/buffer.c:90
> delta = -21
> #3  0x0045de02 in manage_client_side_cookies (s=0xcfa800, 
> req=0xcfa810) at src/proto_http.c:7976
> delta = 
> cur_hdr = 0xcfac6c
> val = 
> txn = 
> sess = 0xc1c930
> preserve_hdr = 0
> cur_idx = 3
> old_idx = 2
> hdr_beg = 0xd4575d "Accept-Encoding: 
> gzip\r\n\r\n.32.31\r\nConnection: close\r\n\r\nre\r\n\r\n"
> hdr_end = 0xd45770 "ip\r\n\r\n.32.31\r\nConnection: 
> close\r\n\r\nre\r\n\r\n"
> hdr_next = 0xd45772 "\r\n\r\n.32.31\r\nConnection: 
> close\r\n\r\nre\r\n\r\n"
> del_from = 0xd45763 "-Encoding: gzip\r\n\r\n.32.31\r\nConnection: 
> close\r\n\r\nre\r\n\r\n"
> prev = 
> att_beg = 
> att_end = 
> equal = 
> val_beg = 
> val_end = 
> next = 
> #4  0x00460a86 in http_process_req_common (s=0xcfa800, req=0xcfa810, 
> an_bit=256, px=0x86a650) at src/proto_http.c:4474
> sess = 0xc1c930
> txn = 0xcfab50
> msg = 0xcfabb0
> rule = 
> wl = 
> verdict = 
> deny_status = 2
> #5  0x00486d0e in process_stream (t=0xb8fa70) at src/stream.c:1798
> max_loops = 199
> ana_list = 2304
> ana_back = 2304
> flags = 2
> srv = 
> s = 0xcfa800
> sess = 0xc1c930
> rqf_last = 
> rpf_last = 2147745792
> rq_prod_last = 
> rq_cons_last = 
> rp_cons_last = 7
> rp_prod_last = 0
> req_ana_back = 
> req = 0xcfa810
> res = 0xcfa850
> si_f = 0xcfaa38
> si_b = 0xcfaa60
> #6  0x00415ac0 in process_runnable_tasks () at src/task.c:238
> t = 
> max_processed = 
> #7  0x00407028 in run_poll_loop () at src/haproxy.c:1724
> next = 
> #8  0x0040a308 in main (argc=, argv= optimized out>) at src/haproxy.c:2105
> err = 
> retry = 
> limit = {rlim_cur = 4091, rlim_max = 4091}
> errmsg = 
> "\000\347K\000\000\000\000\000\b\300n\000\000\000\000\000\020\340\377\377\377\177\000\000\000\300n\000\000\000\000\000\006\000\000\000\000\000\000\000H\341\377\377\377\177\000\000\200\341\377\377\377\177\000\000XpA\000\000\000\000\000\000\300n\000\000\000\000\000\226\070K\000\000\000\000\000\340\070\370/7\000\000\000\340\067K\000\000\000\000\000\000\000\000"
> 
> 
> Basically, the memove in #1 is called with len=18446744073709551439 from
> buffer_replace2, which is a negative value.
> 
> I am not sure exactly in which case this is possible (last line of the header
> incorrect or something), but bi_end(b) is < to end, so the unsigned size_t
> expected by memmove is incorrect.

For sure there's a bug there. However I'd be very interested in understanding
in which case it can happen, as it will reveal the root cause of this bug.
We know that this part is tricky and I'd rather be sure we don't miss a
single case.

> I recompiled haproxy with the patch below and now it survives the
> vulnerability scanner, but it might not be at the proper place of the code
> (maybe the logic fault is better addressed above in
> manage_client_side_cookies... ):

This obviously confirms that it's where it dies, but it doesn't explain
what the problem really is. Would you happen to have an exploitable core
with the associated executable ? I 

haproxy 1.7.5 segfault on cookie/header parsing.

2017-05-26 Thread Jean LUBATTI
Hello,

When using a vulnerability scanner on haproxy 1.7.5, we discovered a scenario 
under which the haproxy segfaults.

Unfortunately, this is a "bundled" scanner whith no access to the exact 
requests, and the haproxy terminates the SSL for https, so not easy to capture 
the actual traffic, but we managed to gather a core of haproxy.

This happens only when using the cookie SERVERID for session stickiness:

The backtrace is as follow:

I believe the scanner injects a screwed up header and/or cookie. The result 
appears to be the incorrect memmove of the last header line :

(gdb) bt full
#0  _wordcopy_fwd_dest_aligned (dstp=14237664, srcp=14237696, 
len=2305843009213653720) at wordcopy.c:196
a0 = 
a1 = 
a2 = 0
a3 = 0
sh_1 = 40
sh_2 = 24
#1  0x003727a838be in memmove (dest=0xd4575d, src=, 
len=18446744073709551439) at memmove.c:73
dstp = 
srcp = 
#2  0x00411217 in buffer_replace2 (b=0xd456b0, pos=0xd4575d 
"Accept-Encoding: gzip\r\n\r\n.32.31\r\nConnection: close\r\n\r\nre\r\n\r\n", 
end=, str=0x0, len=0) at src/buffer.c:90
delta = -21
#3  0x0045de02 in manage_client_side_cookies (s=0xcfa800, req=0xcfa810) 
at src/proto_http.c:7976
delta = 
cur_hdr = 0xcfac6c
val = 
txn = 
sess = 0xc1c930
preserve_hdr = 0
cur_idx = 3
old_idx = 2
hdr_beg = 0xd4575d "Accept-Encoding: gzip\r\n\r\n.32.31\r\nConnection: 
close\r\n\r\nre\r\n\r\n"
hdr_end = 0xd45770 "ip\r\n\r\n.32.31\r\nConnection: 
close\r\n\r\nre\r\n\r\n"
hdr_next = 0xd45772 "\r\n\r\n.32.31\r\nConnection: 
close\r\n\r\nre\r\n\r\n"
del_from = 0xd45763 "-Encoding: gzip\r\n\r\n.32.31\r\nConnection: 
close\r\n\r\nre\r\n\r\n"
prev = 
att_beg = 
att_end = 
equal = 
val_beg = 
val_end = 
next = 
#4  0x00460a86 in http_process_req_common (s=0xcfa800, req=0xcfa810, 
an_bit=256, px=0x86a650) at src/proto_http.c:4474
sess = 0xc1c930
txn = 0xcfab50
msg = 0xcfabb0
rule = 
wl = 
verdict = 
deny_status = 2
#5  0x00486d0e in process_stream (t=0xb8fa70) at src/stream.c:1798
max_loops = 199
ana_list = 2304
ana_back = 2304
flags = 2
srv = 
s = 0xcfa800
sess = 0xc1c930
rqf_last = 
rpf_last = 2147745792
rq_prod_last = 
rq_cons_last = 
rp_cons_last = 7
rp_prod_last = 0
req_ana_back = 
req = 0xcfa810
res = 0xcfa850
si_f = 0xcfaa38
si_b = 0xcfaa60
#6  0x00415ac0 in process_runnable_tasks () at src/task.c:238
t = 
max_processed = 
#7  0x00407028 in run_poll_loop () at src/haproxy.c:1724
next = 
#8  0x0040a308 in main (argc=, argv=) at src/haproxy.c:2105
err = 
retry = 
limit = {rlim_cur = 4091, rlim_max = 4091}
errmsg = 
"\000\347K\000\000\000\000\000\b\300n\000\000\000\000\000\020\340\377\377\377\177\000\000\000\300n\000\000\000\000\000\006\000\000\000\000\000\000\000H\341\377\377\377\177\000\000\200\341\377\377\377\177\000\000XpA\000\000\000\000\000\000\300n\000\000\000\000\000\226\070K\000\000\000\000\000\340\070\370/7\000\000\000\340\067K\000\000\000\000\000\000\000\000"


Basically, the memove in #1 is called with len=18446744073709551439 from 
buffer_replace2, which is a negative value.

I am not sure exactly in which case this is possible (last line of the header 
incorrect or something), but bi_end(b) is < to end, so the unsigned size_t 
expected by memmove is incorrect.

I recompiled haproxy with the patch below and now it survives the vulnerability 
scanner, but it might not be at the proper place of the code (maybe the logic 
fault is better addressed above in manage_client_side_cookies... ):

diff -uNr haproxy-1.7.5/src/buffer.c haproxy-1.7.5p/src/buffer.c
--- haproxy-1.7.5/src/buffer.c  2017-04-03 10:28:32.0 +0200
+++ haproxy-1.7.5p/src/buffer.c 2017-05-26 13:04:58.225311000 +0200
@@ -87,7 +87,8 @@
return 0;  /* no space left before wrapping data */

/* first, protect the end of the buffer */
-   memmove(end + delta, end, bi_end(b) - end);
+   if ( bi_end(b) > end )
+   memmove(end + delta, end, bi_end(b) - end);

/* now, copy str over pos */
if (len)


the configuration is as follows:



frontend ft_X_443
bind 185.139.245.111:443 ssl crt 
/etc/haproxy/ssl/X.pem   ciphers 
AES256+EECDH:AES256+EDH
bind-process 2 3 4
mode http
option http-buffer-request

http-response set-header Strict-Transport-Security "max-age=1600; 
includeSubDomains; preload;"
http-request del-header Origin

stick-table type ip size 1m expire 1m store gpc0,conn_rate(1s)

tcp-request connection track-sc1