Actions
Bug #2843
closedlighttpd segfault if /var/tmp is full
ASK QUESTIONS IN Forums:
Description
I have a cgi script which creates a tarball and sent it back. The output is 50-200MB huge. I noticed that at some point the script crashed, returned truncated data and that lighttpd died with a SIGSEGV
It turns out that on my machine /var/tmp was full and lighttpd wanted to write /var/tmp/lighttpd-upload-* and could not write.
How to repeat:
Install lighttpd-1.4.45 (or lighttpd-1.4.48) on debian9 # create a small /var/tmp/ filesystem: $ sudo mount -t tmpfs none -o size=1k /var/tmp fill up /var/tmp $ date > /var/tmp/date # install the cgi script tar.cgi #!/bin/sh echo "Content-type: application/x-tgz" echo "" tar czf - /usr/bin # run the cgi script $ curl http://localhost:8080/cgi/tar.cgi | wc Segmentation fault (core dumped)
strace output:
getpid() = 16128 open("/var/tmp/lighttpd-upload-V1KMfW", O_RDWR|O_CREAT|O_EXCL, 0600) = 20 fcntl(20, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE) fcntl(20, F_SETFL, O_RDWR|O_APPEND|O_LARGEFILE) = 0 fcntl(20, F_SETFD, FD_CLOEXEC) = 0 write(20, "\326&\16\241@T\375Zsx\335p\22>-\350o\360\301\264n\244-\324\224\232\320\327:\340\317,"..., 16384) = -1 ENOSPC (No space left on device) stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=127, ...}) = 0 write(5, "2017-11-25 15:46:23: (chunk.c.58"..., 94) = -1 ENOSPC (No space left on device) unlink("/var/tmp/lighttpd-upload-V1KMfW") = 0 close(20) = 0 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x58} --- +++ killed by SIGSEGV +++
gdb -core output:
Reading symbols from ./tmp/lighttpd-1.4.48/src/lighttpd...done. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x000056550a189dae in chunkqueue_remove_empty_chunks (cq=0x56550c06dfb0) at chunk.c:744 744 for (c = cq->first; c->next; c = c->next) { (gdb) bt #0 0x000056550a189dae in chunkqueue_remove_empty_chunks (cq=0x56550c06dfb0) at chunk.c:744 #1 chunkqueue_append_mem_to_tempfile (srv=srv@entry=0x56550c009010, dest=dest@entry=0x56550c06dfb0, mem=mem@entry=0x56550c0d0300 "[...]", len=len@entry=16384) at chunk.c:604 #2 0x000056550a18a59f in http_chunk_append_to_tempfile (con=0x56550c06d9e0, con=0x56550c06d9e0, len=16384, mem=0x56550c0d0300 “[...]", srv=0x56550c009010) at http_chunk.c:112 #3 http_chunk_append_data (srv=0x56550c009010, con=0x56550c06d9e0, b=<optimized out>, mem=<optimized out>, len=16384) at http_chunk.c:142 #4 0x000056550a19d490 in http_response_read (srv=srv@entry=0x56550c009010, con=0x56550c06d9e0, opts=opts@entry=0x56550c0bd7f8, b=0x56550c0bd850, fd=12, fde_ndx=fde_ndx@entry=0x56550c0bd7cc) at http-header-glue.c:1286 #5 0x00007f9edd684cc5 in cgi_recv_response (srv=0x56550c009010, hctx=0x56550c0bd7c0) at mod_cgi.c:388 #6 0x00007f9edd685623 in cgi_handle_fdevent (srv=0x56550c009010, ctx=0x56550c0bd7c0, revents=1) at mod_cgi.c:415 #7 0x000056550a179833 in server_main (srv=0x56550c009010, argc=<optimized out>, argv=<optimized out>) at server.c:1977 #8 0x000056550a17752e in main (argc=4, argv=0x7ffe986caa58) at server.c:2044
Updated by gstrauss about 7 years ago
- Category set to core
- Status changed from New to Patch Pending
- Target version changed from 1.4.x to 1.4.49
Thank you very much for the thorough test case. Just from reviewing the code, I see that if the chunkqueue is not empty, but the last chunk is empty, then a NULL pointer dereference can occur. I'll test this further, but expect the following patch to fix it:
--- a/src/chunk.c +++ b/src/chunk.c @@ -741,7 +741,7 @@ static void chunkqueue_remove_empty_chunks(chunkqueue *cq) { chunkqueue_remove_finished_chunks(cq); if (chunkqueue_is_empty(cq)) return; - for (c = cq->first; c->next; c = c->next) { + for (c = cq->first; c && c->next; c = c->next) { if (0 == chunk_remaining_length(c->next)) { chunk *empty = c->next; c->next = empty->next;
Updated by gstrauss about 7 years ago
- Status changed from Patch Pending to Fixed
- % Done changed from 0 to 100
Applied in changeset bed37796179686e13eb2c05bcd8d4bb14d85d4e0.
Actions
Also available in: Atom