Opened 14 years ago

Closed 14 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 14 years ago.
nginx configuration
webdav-extensions.php​ (13.9 KB ) - added by vl 14 years ago.
PHP script for webdav
sni_tests.diff​ (4.8 KB ) - added by vl 14 years ago.

Download all attachments as: .zip

Change History (7)

by vl, 14 years ago

Attachment: nginx.conf​ added

nginx configuration

by vl, 14 years ago

Attachment: webdav-extensions.php​ added

PHP script for webdav

by vl, 14 years ago

Attachment: sni_tests.diff​ added

comment:1 by Maxim Dounin, 14 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, 14 years ago

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

comment:3 by Maxim Dounin, 14 years ago

In 4919/nginx:

(The changeset message doesn't reference this ticket)

comment:4 by Maxim Dounin, 14 years ago

Resolution: → fixed
sensitive: → 0
Status: new → closed

Fix committed.

Note: See TracTickets for help on using tickets.