Opened 11 years ago

Closed 11 years ago

#269 closed defect (wontfix)

DAV crash if reading body would block

Reported by: Bryan Berg Owned by:
Priority: minor Milestone:
Component: nginx-module Version: 1.2.x
Keywords: dav put Cc:
uname -a: Linux gelid-goose 3.2.0-35-generic #55-Ubuntu SMP Wed Dec 5 17:42:16 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.2.6
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-debug --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6 --with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl --with-mail --with-mail_ssl_module --add-module=/home/andrew/packages/nginx/nginx-1.2.6/debian/modules/nginx-auth-pam --add-module=/home/andrew/packages/nginx/nginx-1.2.6/debian/modules/nginx-echo --add-module=/home/andrew/packages/nginx/nginx-1.2.6/debian/modules/nginx-upstream-fair --add-module=/home/andrew/packages/nginx/nginx-1.2.6/debian/modules/nginx-dav-ext-module --add-module=/home/andrew/packages/nginx/nginx-1.2.6/debian/modules/nginx-upload-module

Description

I think I've found a bug in the DAV module related to body reads. Under 1.2.5, this causes a segfault in the worker handling the request. The patch in 1.2.6 fixes the segfault, but nginx returns a 500 when the PUT could reasonably complete. Applying the supplied patch causes the PUT to complete without issue.

I've attached a sample config as well as a script which can reproduce the issue. The appearance of the bug is sensitive to timing, so generating some load on the server under test can raise the odds that you experience it. (In my VM, PUTing over the network while running a tcpdump is good enough.)

First, open a connection and GET a file. Then, on the same connection, PUT a file. The code to read the body doesn't properly handle the case in which the body is not immediately available. If the read() call returns NGX_AGAIN while reading the body, ngx_http_dav_handler() swallows the return code and returns NGX_DONE. This leaves the request in an inconsistent state (where r->request_body->temp_file is NULL or garbage) and causes the crash or 500. If instead ngx_http_dav_handler() recognizes the return code and returns NGX_AGAIN, the read event gets properly scheduled and the upload completes.

We've been running this patch in production for a little while now, and it seems to work fine.

I haven't had a chance to test this against [4938] as it doesn't look like it was merged back to 1.2.

Attachments (3)

webdav-bug.py (352 bytes ) - added by Bryan Berg 11 years ago.
webdav-bug.py
webdav (332 bytes ) - added by Bryan Berg 11 years ago.
webdav.conf
ngx_again.patch (407 bytes ) - added by Bryan Berg 11 years ago.
ngx_again.patch

Download all attachments as: .zip

Change History (4)

by Bryan Berg, 11 years ago

Attachment: webdav-bug.py added

webdav-bug.py

by Bryan Berg, 11 years ago

Attachment: webdav added

webdav.conf

by Bryan Berg, 11 years ago

Attachment: ngx_again.patch added

ngx_again.patch

comment:1 by Maxim Dounin, 11 years ago

Resolution: wontfix
Status: newclosed

Correct fix is [4938], but it wasn't merged to stable as it theoretically might break 3rd party modules. If you are forced to use stable, you may want to try

keepalive_timeout 0;

as a workaround.

Note: See TracTickets for help on using tickets.