Opened 2 years ago

Closed 2 years ago

#1576 closed defect (fixed)

When the file is overwritten by the COPY method under the following conditions, content of copied file is not correct.

Reported by: 373kwsk@… Owned by:
Priority: minor Milestone:
Component: nginx-module Version: 1.12.x
Keywords: WebDAV Cc:
uname -a: Linux vm-search-004.fcxlocal 3.10.0-693.21.1.el7.x86_64 #1 SMP Wed Mar 7 19:03:37 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.12.2
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'

Description

When the file is overwritten by the COPY method under the following conditions, content of copied file is not correct.

  • OS: CentOS 7.4
  • Nginx Version: 1.12.2
# nginx
# ps auxf | grep nginx
root     18826  0.0  0.0 112660   972 pts/1    S+   02:45   0:00  |                       \_ grep --color=auto nginx
root     18797  0.0  0.0  46432   988 ?        Ss   02:17   0:00 nginx: master process nginx
nginx    18798  0.0  0.1  46840  2212 ?        S    02:17   0:00  \_ nginx: worker process
# cd /var/lib/nginx
# ls -l
total 0
lrwxrwxrwx. 1 root  root  14 May 15 07:50 dest -> /ext_disk/dest
drwxr-xr-x. 2 nginx nginx 22 May 15 07:59 source
drwxr-xr-x. 2 nginx nginx  6 May 15 07:35 tmp
# ls -l source/.
total 4
-rw-r--r--. 1 nginx nginx 5 May 15 07:40 copy.txt
# cat source/copy.txt
copy
# ls -l dest/.
total 4
-rw-rw-r--. 1 nginx nginx 31 May 16 02:08 copy.txt
# cat dest/copy.txt
123456789012345678901234567890
# curl -XCOPY http://localhost:8080/source/copy.txt -H Destination:/dest/copy.txt
# ls -l source/.
total 4
-rw-r--r--. 1 nginx nginx 5 May 15 07:40 copy.txt
# cat source/copy.txt
copy
# ls -l dest/.
total 4
-rw-rw-r--. 1 nginx nginx 31 May 15 07:40 copy.txt
# cat dest/copy.txt
copy
6789012345678901234567890

I have attached the configuration file, the access log, and the error log at the debug level.

The Overwrite header is not specified (The superscription has been permitted).
I expected that the content of "source/copy.txt" and "dest/copy.txt" were equal as a result of COPY.

However, the top part of "dest/copy.txt" is only replaced by "source/copy.txt" .
What should I do to get the expected result?

Attachments (3)

access.log (104 bytes ) - added by 373kwsk@… 2 years ago.
error.log (6.3 KB ) - added by 373kwsk@… 2 years ago.
my-nginx.conf (334 bytes ) - added by 373kwsk@… 2 years ago.

Download all attachments as: .zip

Change History (6)

by 373kwsk@…, 2 years ago

Attachment: access.log added

by 373kwsk@…, 2 years ago

Attachment: error.log added

by 373kwsk@…, 2 years ago

Attachment: my-nginx.conf added

comment:1 by Maxim Dounin, 2 years ago

The following patch should fix this:

# HG changeset patch
# User Maxim Dounin <mdounin@mdounin.ru>
# Date 1531147912 -10800
#      Mon Jul 09 17:51:52 2018 +0300
# Node ID a1668faa205aa6ee0ce7936bdbb15e4e600b3931
# Parent  54683f650cbdcd73f7f8d845c843295978da5a85
Fixed ngx_copy_file() to truncate destination file.

Previously, ngx_open_file(NGX_FILE_CREATE_OR_OPEN) was used, resulting
in destination file being partially rewritten if exists.  Notably,
this affected WebDAV COPY command (ticket #1576).

diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -839,8 +839,7 @@ ngx_copy_file(u_char *from, u_char *to, 
         goto failed;
     }
 
-    nfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN,
-                        cf->access);
+    nfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_TRUNCATE, cf->access);
 
     if (nfd == NGX_INVALID_FILE) {
         ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno,

comment:2 by Maxim Dounin <mdounin@…>, 2 years ago

In 7328:3c357206a3b8/nginx:

Dav: fixed ngx_copy_file() to truncate destination file.

Previously, ngx_open_file(NGX_FILE_CREATE_OR_OPEN) was used, resulting
in destination file being partially rewritten if exists. Notably,
this affected WebDAV COPY command (ticket #1576).

comment:3 by Maxim Dounin, 2 years ago

Resolution: fixed
Status: newclosed

Fix committed, thanks for reporting this.

Note: See TracTickets for help on using tickets.