Hi again Thierry,

Le 18/08/2015 22:28, Cyril Bonté a écrit :
Hi Thierry,

Le 18/08/2015 12:33, Thierry a écrit :
Hi,

How can I reproduce the segfault ?

While I tried to simplify the test to its minimal form, I could see that
the segfault doesn't occur in "http-keep-alive" mode, but does in
"httpclose" or "http-server-close" mode.

Here is the minimal configuration to reproduce the segfault :
haproxy.cfg :
global
     lua-load bug.lua

listen test
     bind :9000
     mode http
     option httpclose
     http-request lua closebug

bug.lua :
function closebug(txn)
     txn:close()
end

Well, to complete the test case, using httpclose or http-server-close, it will segfault only if it requires to change the "Connection" header in the response.

$ echo -ne "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n" | nc localhost 9000
=> segfault

Backtrace associated :
...
#1 0x0000000000410bc7 in buffer_insert_line2 (b=0x732c00, pos=0x732c35 "\r\nache-Control: no-cache\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n<html><body><h1>503 Service Unavailable</h1>\nNo server is available to handle this request.\n</body></html>\n",
str=0x4b23bf "Connection: close", len=len@entry=17) at src/buffer.c:126
#2 0x000000000044653f in http_header_add_tail2 (msg=msg@entry=0x724a50, hdr_idx=hdr_idx@entry=0x7249f0, text=<optimized out>, len=17) at src/proto_http.c:508 #3 0x00000000004496c0 in http_change_connection_header (txn=txn@entry=0x7249f0, msg=msg@entry=0x724a50, wanted=4194304) at src/proto_http.c:1984 #4 0x000000000045147f in http_process_request (s=s@entry=0x724670, req=req@entry=0x724680, an_bit=an_bit@entry=512) at src/proto_http.c:4689 #5 0x000000000047bcf6 in process_stream (t=<optimized out>) at src/stream.c:1741
#6 0x0000000000415665 in process_runnable_tasks () at src/task.c:238
#7 0x000000000040c0c0 in run_poll_loop () at src/haproxy.c:1528
#8 0x0000000000408f66 in main (argc=<optimized out>, argv=<optimized out>) at src/haproxy.c:1887

$ echo -ne "GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n" | nc localhost 9000
=> OK

It won't segfault exactly in the same manner as Marc-Antoine, but it shows that haproxy tries to process the HTTP request and response after txn.close() is called.

How about completely removing txn:close() and check a return value for lua function ? 0 : haproxy go to the next steps ; <> 0 : haproxy stops immediately the session.
This could prevent such use cases :
        txn:close()
        txn.res:send("test\r\n")
        txn.http:res_add_header("header", "value")


--
Cyril Bonté

Reply via email to