Project

General

Profile

Actions

Bug #2923

closed

SIGSEGV on file upload

Added by rgenoud about 6 years ago. Updated about 6 years ago.

Status:
Fixed
Priority:
Normal
Category:
mod_fastcgi
Target version:
ASK QUESTIONS IN Forums:

Description

Since commit a1b527e47374 ("[PATCH] [multiple] reduce initial buffer sz if large POST (fixes #2922)")

Uploading a file immediately leads to a SIGSEGV
The configuration is the same as #2922 plus :
server.stream-request-body = 2

GDB:

Starting program: /usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf

Program received signal SIGSEGV, Segmentation fault.
0xb6c05a84 in fcgi_stdin_append (srv=0x6a008, hctx=0xb0ea0) at mod_fastcgi.c:190
190            hctx->wb->first->type == MEM_CHUNK /* else FILE_CHUNK for temp file */
(gdb) bt
#0  0xb6c05a84 in fcgi_stdin_append (srv=0x6a008, hctx=0xb0ea0) at mod_fastcgi.c:190
#1  0x0003a508 in gw_handle_subrequest (srv=0x6a008, con=0x85558, p_d=0x77fb8) at gw_backend.c:2003
#2  0x0003e024 in plugins_call_handle_subrequest (srv=0x6a008, con=0x85558) at plugin.c:338
#3  0x000158e4 in http_response_prepare (srv=0x6a008, con=0x85558) at response.c:695
#4  0x00018790 in connection_state_machine (srv=0x6a008, con=0x85558) at connections.c:1157
#5  0x000138d0 in server_main (srv=0x6a008, argc=4, argv=0xbef9bc94) at server.c:2037
#6  0x00013b34 in main (argc=4, argv=0xbef9bc94) at server.c:2091

strace:

open("/var/www/lns_ihm/controller/chargeFMW.php", O_RDONLY|O_LARGEFILE) = 8
close(8)                                = 0
gettimeofday({1545042217, 899612}, NULL) = 0
open("/var/tmp/lighttpd-upload-Ikt0jd", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 8
fcntl64(8, F_GETFL)                     = 0x20002 (flags O_RDWR|O_LARGEFILE)
fcntl64(8, F_SETFL, O_RDWR|O_APPEND|O_LARGEFILE) = 0
fcntl64(8, F_SETFD, FD_CLOEXEC)         = 0
write(8, "-----------------------------181"..., 93477) = 93477
socket(PF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 9
connect(9, {sa_family=AF_LOCAL, sun_path="/tmp/php.socket-0"}, 19) = 0
getsockname(7, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.168.5.1")}, [16]) = 0
epoll_ctl(6, EPOLL_CTL_ADD, 9, {EPOLLIN|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=9, u64=9}}) = 0
writev(9, [{"\1\1\0\1\0\10\0\0\0\1\0\0\0\0\0\0\1\4\0\1\0042\0\0\16\10CONTEN"..., 1114}], 1) = 1114
open("/var/tmp/lighttpd-upload-Ikt0jd", O_RDONLY|O_NOCTTY|O_LARGEFILE|O_CLOEXEC) = 10
fstat64(10, {st_mode=S_IFREG|0600, st_size=93477, ...}) = 0
_llseek(10, 0, [0], SEEK_SET)           = 0
read(10, "-----------------------------181"..., 65535) = 65535
write(9, "-----------------------------181"..., 65535) = 65535
close(10)                               = 0
writev(9, [{"\1\5\0\1m&\0\0", 8}], 1)   = 8
_llseek(8, 65535, [65535], SEEK_SET)    = 0
read(8, "\275\205\310\326\360\1\331D\24\241\240\360\21\211@\343\320\342}\213\230\233\35)7\344\5\0T\335\302\314"..., 27942) = 27942
write(9, "\275\205\310\326\360\1\331D\24\241\240\360\21\211@\343\320\342}\213\230\233\35)7\344\5\0T\335\302\314"..., 27942) = 27942
unlink("/var/tmp/lighttpd-upload-Ikt0jd") = 0
close(8)                                = 0
epoll_ctl(6, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=7, u64=7}}) = 0
accept4(4, 0xbec5e818, [112], SOCK_CLOEXEC|SOCK_NONBLOCK) = -1 EAGAIN (Resource temporarily unavailable)
gettimeofday({1545042217, 955984}, NULL) = 0
epoll_wait(6, {{EPOLLIN, {u32=7, u64=7}}}, 2049, 1000) = 1
ioctl(7, FIONREAD, [70952])             = 0
brk(0xf9000)                            = 0xf9000
read(7, "\301\2316\374ZcO\242P\274\365\341\346\335\233\245\343\272sD\362\2\364gS>\351\6\346\37=\306"..., 73727) = 70952
gettimeofday({1545042217, 997909}, NULL) = 0
open("/var/tmp/lighttpd-upload-4QaOvn", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 8
fcntl64(8, F_GETFL)                     = 0x20002 (flags O_RDWR|O_LARGEFILE)
fcntl64(8, F_SETFL, O_RDWR|O_APPEND|O_LARGEFILE) = 0
fcntl64(8, F_SETFD, FD_CLOEXEC)         = 0
write(8, "\301\2316\374ZcO\242P\274\365\341\346\335\233\245\343\272sD\362\2\364gS>\351\6\346\37=\306"..., 70952) = 70952
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x4} ---
+++ killed by SIGSEGV +++

Actions #1

Updated by gstrauss about 6 years ago

I need to write a test case for large POST with server.stream-request-body = 2

Untested, but a likely fix follows. I'll try to find time to test later tonight.

--- a/src/mod_fastcgi.c
+++ b/src/mod_fastcgi.c
@@ -187,7 +187,7 @@ static handler_t fcgi_stdin_append(server *srv, handler_ctx *hctx) {
                }

                fcgi_header(&(header), FCGI_STDIN, request_id, weWant, 0);
-               hctx->wb->first->type == MEM_CHUNK /* else FILE_CHUNK for temp file */
+               (chunkqueue_is_empty(hctx->wb) || hctx->wb->first->type == MEM_CHUNK) /* else FILE_CHUNK for temp file */
                  ? chunkqueue_append_mem(hctx->wb, (const char *)&header, sizeof(header))
                  : chunkqueue_append_mem_min(hctx->wb, (const char *)&header, sizeof(header));
                chunkqueue_steal(hctx->wb, req_cq, weWant);
Actions #2

Updated by gstrauss about 6 years ago

  • Category changed from core to mod_fastcgi
  • Status changed from New to Patch Pending
  • Target version changed from 1.4.x to 1.4.53
Actions #3

Updated by gstrauss about 6 years ago

I was able to reproduce this manually, and the patch above addresses the issue. Thanks for reporting it.
It requires both server.stream-request-body=2 and a delay between sending request headers and pieces of the request body.

I could not (quickly) reproduce this with pauses between packets in the existing lighttpd test framework, so I've added an item to my todo list.

Actions #4

Updated by gstrauss about 6 years ago

  • Status changed from Patch Pending to Fixed
  • % Done changed from 0 to 100
Actions #5

Updated by rgenoud about 6 years ago

gstrauss wrote:

Applied in changeset fe3dc1796894d22ad60da24d2bfc25fbf612861c.

Thanks,
It's working !

Actions

Also available in: Atom