Opened 12 years ago

Closed 12 years ago

#238 closed defect (fixed)

segfault in DAV module during PUT processing

Reported by: vl Owned by: somebody
Priority: minor Milestone:
Component: nginx-module Version: 1.3.x
Keywords: dav put Cc:
uname -a: Linux vlpc 3.3.8-gentoo #2 SMP Thu Aug 2 16:02:48 MSK 2012 x86_64 Intel(R) Core(TM) i5-3450 CPU @ 3.10GHz GenuineIntel GNU/Linux
nginx -V: nginx version: nginx/1.3.8
built by gcc 4.5.4 (Gentoo 4.5.4 p1.0, pie-0.4.7)
configure arguments: --prefix=/home/vl/tasks/0034-doc-dav/nginx --with-http_dav_module --with-debug

Description

Issuing DAV PUT request in some scenarios can lead to the segfault.

The error log contains:

2012/10/30 15:12:49 [debug] 32408#0: *7 http request line: "PUT /sni_tests.diff HTTP/1.1"
..........
2012/10/30 15:12:49 [debug] 32408#0: *7 http read client request body
2012/10/30 15:12:49 [debug] 32408#0: *7 recv: fd:3 -1 of 4775
2012/10/30 15:12:49 [debug] 32408#0: *7 recv() not ready (11: Resource temporarily unavailable)
2012/10/30 15:12:49 [debug] 32408#0: *7 http client request body recv -2
2012/10/30 15:12:49 [debug] 32408#0: *7 http client request body rest 4775
.....
2012/10/30 15:12:49 [debug] 32408#0: *7 http run request: "/sni_tests.diff?"
2012/10/30 15:12:49 [debug] 32408#0: *7 content phase: 11
2012/10/30 15:12:49 [debug] 32408#0: *7 http put filename: "/home/vl/tasks/0034-doc-dav/nginx/dav/sni_tests.diff"
2012/10/30 15:12:49 [alert] 32400#0: worker process 32408 exited on signal 11 (core dumped)

The backtrace is:

Core was generated by `nginx: worker'.
Program terminated with signal 11, Segmentation fault.
#0 ngx_ext_rename_file (src=0x8, to=0x7fffc9968c90, ext=0x7fffc9968bd0) at src/core/ngx_file.c:545
545 if (ngx_change_file_access(src->data, ext->access) == NGX_FILE_ERROR) {
(gdb) bt
#0 ngx_ext_rename_file (src=0x8, to=0x7fffc9968c90, ext=0x7fffc9968bd0) at src/core/ngx_file.c:545
#1 0x0000000000454cb0 in ngx_http_dav_put_handler (r=0x6b1730) at src/http/modules/ngx_http_dav_module.c:261
#2 0x000000000043839d in ngx_http_read_client_request_body (r=0x6b1730, post_handler=0x454af1 <ngx_http_dav_put_handler>) at src/http/ngx_http_request_body.c:43
#3 0x0000000000454327 in ngx_http_dav_handler (r=0x6b1730) at src/http/modules/ngx_http_dav_module.c:172
#4 0x000000000042c18d in ngx_http_core_content_phase (r=0x6b1730, ph=0x6ccf98) at src/http/ngx_http_core_module.c:1410
#5 0x00000000004271a3 in ngx_http_core_run_phases (r=0x6b1730) at src/http/ngx_http_core_module.c:884
#6 0x0000000000430f38 in ngx_http_request_handler (ev=0x6f15b0) at src/http/ngx_http_request.c:1871
#7 0x00000000004237f6 in ngx_epoll_process_events (cycle=0x6abb50, timer=<optimized out>, flags=<optimized out>) at src/event/modules/ngx_epoll_module.c:714
#8 0x000000000041ac00 in ngx_process_events_and_timers (cycle=0x6abb50) at src/event/ngx_event.c:247
#9 0x0000000000421dab in ngx_worker_process_cycle (cycle=0x6abb50, data=<optimized out>) at src/os/unix/ngx_process_cycle.c:810
#10 0x000000000042053f in ngx_spawn_process (cycle=0x6abb50, proc=0x421cb7 <ngx_worker_process_cycle>, data=0x0, name=0x471c24 "worker process", respawn=0)

at src/os/unix/ngx_process.c:198

#11 0x0000000000422a25 in ngx_reap_children (cycle=0x6abb50) at src/os/unix/ngx_process_cycle.c:624
#12 ngx_master_process_cycle (cycle=0x6abb50) at src/os/unix/ngx_process_cycle.c:181
#13 0x0000000000404750 in main (argc=<optimized out>, argv=<optimized out>) at src/core/nginx.c:412

How to reproduce:

use attached nginx.conf and setup FastCGI server using attached php script that implementis
DAV extensions which nginx doesn't understand.

the client used is Nautilus 2.32.2.1 (gvfs/1.12.3) file manager on linux host.
Attempt to copy some files (looks like not too small, attached) into the DAV share served
by nginx leads to it's segfault.

Attachments (3)

nginx.conf (1.2 KB ) - added by vl 12 years ago.
nginx configuration
webdav-extensions.php (13.9 KB ) - added by vl 12 years ago.
PHP script for webdav
sni_tests.diff (4.8 KB ) - added by vl 12 years ago.

Download all attachments as: .zip

Change History (7)

by vl, 12 years ago

Attachment: nginx.conf added

nginx configuration

by vl, 12 years ago

Attachment: webdav-extensions.php added

PHP script for webdav

by vl, 12 years ago

Attachment: sni_tests.diff added

comment:1 by Maxim Dounin, 12 years ago

Please try the following patch:

# HG changeset patch
# User Maxim Dounin <mdounin@mdounin.ru>
# Date 1351766870 -14400
# Node ID 61873b4e4d7e6eea545bfabeb46f4d6f75383303
# Parent  6367ad17fa6b1815215238c562903c0fd6e1abe5
Dav: fixed segfault on PUT if body was already read (ticket #238).

If request body reading happens with different options it's possible
that there will be no r->request_body->temp_file available (or even
no r->request_body available if body was discarded).  Return internal
server error in this case instead of committing suicide by dereferencing
a null pointer.

diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -209,6 +209,11 @@ ngx_http_dav_put_handler(ngx_http_reques
     ngx_ext_rename_file_t     ext;
     ngx_http_dav_loc_conf_t  *dlcf;
 
+    if (r->request_body == NULL || r->request_body->temp_file == NULL) {
+        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return;
+    }
+
     ngx_http_map_uri_to_path(r, &path, &root, 0);
 
     path.len--;

comment:2 by vl, 12 years ago

The patch fixess the issue - no more segfaults, internal server error is returned.

comment:3 by Maxim Dounin, 12 years ago

In 4919/nginx:

Dav: fixed segfault on PUT if body was already read (ticket #238).

If request body reading happens with different options it's possible
that there will be no r->request_body->temp_file available (or even
no r->request_body available if body was discarded). Return internal
server error in this case instead of committing suicide by dereferencing
a null pointer.

comment:4 by Maxim Dounin, 12 years ago

Resolution: fixed
sensitive: 0
Status: newclosed

Fix committed.

Note: See TracTickets for help on using tickets.