#311 closed defect (duplicate)
Nginx segmentation fault on uploading file via DAV after Expect: 100-continue
Reported by: | Nelson Benítez León | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-core | Version: | 1.3.x |
Keywords: | Cc: | ||
uname -a: | Linux localhost.localdomain 3.6.10-4.fc18.i686 #1 SMP Tue Dec 11 18:24:49 UTC 2012 i686 i686 i386 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.2.5
built by gcc 4.7.2 20121109 (Red Hat 4.7.2-8) (GCC) TLS SNI support enabled configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-mail_ssl_module --with-cc-opt='-O2 -g -march=i386 -mtune=i686' --with-ld-opt=' -Wl,-E' |
Description
Hi, I can reliably reproduce a crash in nginx when uploading a file via default DAV module, the client program which triggers this behaviour is Cyberduck ( http://cyberduck.ch/ ) which is an open source ftp/dav client available for windows and mac os x.
I've investigated the issue by installing a custom build of nginx on fedora and printf debugging, this is what I've gather:
- Cyberduck issues a PUT command with Expect: 100-continue header. See complete request below:
PUT /davsite/directorio/index.html HTTP/1.1
Expect: 100-continue
Content-Length: 6359
Content-Type: text/html
Host: 10.47.128.91
Connection: Keep-Alive
User-Agent: Cyberduck/4.2.1 (9350) (Windows XP/5.1) (x86)
- Above request reaches ngx_http_test_expect() function in http://tinyurl.com/dy6ton7 which sends to the client a "100 Continue" status.
- Then cyberduck after receiving the "100 continue" from nginx, it sends the file, nginx crashes after receiving the file, following this trace:
post_handler(r);
is executed on http://tinyurl.com/ck5tdox because r->request_body
is TRUE, this is in ngx_http_read_client_request_body() of ngx_request_body.c
Above post_handler(r)
is in turn a call to ngx_http_dav_put_handler()
in ngx_http_dav_module.c , link http://tinyurl.com/cuygo7d , at the start of that function you have:
ngx_str_t *temp; ... temp = &r->request_body->temp_file->file.name;
and above line is the problem, because a little down on that function temp
is passed to ngx_ext_rename_file()
here:
if (ngx_ext_rename_file(temp, &path, &ext) != NGX_OK) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; }
and then nginx crashes when trying to access temp->data
inside ngx_ext_rename_file()
, which the first of that cases is
if (ngx_change_file_access(src->data, ext->access) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno, ngx_change_file_access_n " \"%s\" failed", src->data); err = 0; goto failed; }
If you need some more debugging I can try patches in my nginx build, but the bug is easily reproducible by anyone downloading and installing cyberduck.
My dav site nginx.conf below:
http { include /etc/nginx/mime.types; default_type application/octet-stream; client_max_body_size 50m; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; server { listen 80; listen 10.47.128.91:80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } location ^~ /davsite/ { root /usr/share/nginx; error_log /usr/share/nginx/davsite/error_log warn; dav_methods PUT DELETE MKCOL; #dav_access group:rw all:r; create_full_put_path on; autoindex on; autoindex_exact_size off; # Variables necessary for proper execution of the PHP script used below. include /etc/nginx/fastcgi_params; fastcgi_param SCRIPT_FILENAME /etc/nginx/webdav-extensions.php; fastcgi_param DEPTH $http_depth; fastcgi_param HOST $host; fastcgi_param DESTINATION $http_destination; fastcgi_param OVERWRITE $http_overwrite; fastcgi_param REQUEST_METHOD $request_method; # NGINX WebDAV support is incomplete and somewhat too strict. We handle # a few WebDAV methods manually in a PHP script to fill out the cracks. if ($request_method ~ ^(PROPFIND|OPTIONS|COPY|MOVE)$) { fastcgi_pass 127.0.0.1:9000; break; } # NGINX WebDAV requires trailing slashes on directories, yet certain # common WebDAV clients don't support them. Do rewrites to fix it, if (-d $request_filename) { rewrite ^(.*[^/])$ $1/ break; } if ($request_method = MKCOL) { rewrite ^(.*[^/])$ $1/ break; } } } }
A not very useful GDB backtrace, could try to provide one with more symbols but it will show my above analysis anyway:
Reading symbols from /usr/sbin/nginx...(no debugging symbols found)...done. [New LWP 9141] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/libthread_db.so.1". Core was generated by `nginx: worker pr'. Program terminated with signal 11, Segmentation fault. #0 0x0806043b in ngx_ext_rename_file () Missing separate debuginfos, use: debuginfo-install nginx-1.2.5-1.fc18.i386 (gdb) bt #0 0x0806043b in ngx_ext_rename_file () #1 0x080c382d in ngx_http_dav_put_handler () #2 0x0809a23b in ngx_http_read_client_request_body () #3 0x080c33e8 in ngx_http_dav_handler () #4 0x08086a9b in ngx_http_core_content_phase () #5 0x08085c31 in ngx_http_core_run_phases () #6 0x08091b37 in ngx_http_request_handler () #7 0x0807d08f in ngx_epoll_process_events () #8 0x08071d09 in ngx_process_events_and_timers () #9 0x0807b34d in ngx_worker_process_cycle () #10 0x08078a76 in ngx_spawn_process () #11 0x0807a88e in ngx_start_worker_processes () #12 0x0807a133 in ngx_master_process_cycle () #13 0x08054e93 in main ()
Change History (3)
comment:1 by , 12 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
comment:2 by , 12 years ago
Thanks for the quick response! :-).
Can I ask if the real fix on http://trac.nginx.org/nginx/ticket/284 can be backported to the stable 1.2.x branch? because otherwise a reliable dav server cannot be run on a stable nginx, and there is no server distros(rhel,debian 6,etc) which are packaging 1.3.x versions..
comment:3 by , 12 years ago
Real fix isn't backported due to concerns that it might break some 3rd party modules.
Looks like another variant to trigger segfault reported in ticket #238 (already fixed). See also ticket #284, which has some additional info (in short: problem is completely fixed in 1.3.9+, and there is no segfault in 1.2.6+).