Summary: | Internal Server Error (500) on COPY | ||
---|---|---|---|
Product: | Apache httpd-2 | Reporter: | Julian Reschke <julian.reschke> |
Component: | mod_dav | Assignee: | Apache HTTPD Bugs Mailing List <bugs> |
Status: | RESOLVED LATER | ||
Severity: | normal | CC: | basant.kukreja, taffy-tyler6464 |
Priority: | P2 | Keywords: | FixedInTrunk, MassUpdate, PatchAvailable |
Version: | 2.0.55 | ||
Target Milestone: | --- | ||
Hardware: | Other | ||
OS: | Linux | ||
URL: | http://www.webdav.org/neon/litmus/ | ||
Attachments: |
Fix for wrong HTTP return code.
Revised patch. Revised Patch revised patch without additional apr_stat mobile device error report |
Description
Julian Reschke
2006-04-13 13:55:13 UTC
I am able to reproduce the bug in 2.2.x branch Created attachment 19581 [details] Fix for wrong HTTP return code. If we send the COPY HTTP request and the destination points to a file whose directory doesn't exist then apache returned 500 error. In this fix, we check the destination directory (do stat on it) and if we failed to stat on the directory then we return 409. Here is the request : COPY /DAVtest/litmus/copysrc HTTP/1.1 Host: lbasantk3.red.iplanet.com:4004 User-Agent: litmus/0.11 neon/0.25.5 Connection: TE TE: trailers Depth: 0 Destination: http://hostname.domainname:4004/DAVtest/litmus/nonesuch/foo Overwrite: F X-Litmus: copymove: 5 (copy_nodestcoll) New response : -------------------------------------------------- HTTP/1.1 409 Conflict Date: Tue, 13 Feb 2007 22:44:16 GMT Server: Apache/2.2.5-dev (Unix) DAV/2 mod_perl/2.0.4-dev Perl/v5.8.8 Content-Length: 509 Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>409 Conflict</title> </head><body> <h1>Conflict</h1> <p>The server encountered an internal error or misconfiguration and was unable to complete your request.</p> <p>Please contact the server administrator, you@example.com and inform them of the time the error occurred, and anything you might have done that may have caused the error.</p> <p>More information about this error may be available in the server error log.</p> </body></html> -------------------------------------------------- Log message in apache log file appears as [Tue Feb 13 14:44:16 2007] [error] [client 192.18.120.216] Could not MOVE/COPY /DAVtest/litmus/copysrc. [409, #0] [Tue Feb 13 14:44:16 2007] [error] [client 192.18.120.216] (2)No such file or directory: /disk/apache/apache2/htdocs/DAVtest/litmus/nonesuch/ [409, #0] -------------------------------------------------- Adding keyword PatchAvailable Suggested fix is incomplete. Here is the another issue (kind of extension to this bug ) related with this : For configuration like : DavLockDB /disk/apache/apache2/var/DAVLockFs <Directory "/disk/apache/apache2/htdocs/DAVtest"> Options Indexes FollowSymLinks AllowOverride None order allow,deny allow from all AuthName "SMA Development server" AuthType Basic DAV On </Directory> If the request is : COPY /DAVtest/litmus/copysrc HTTP/1.1 Host: myhostname.mydomain:4004 User-Agent: litmus/0.11 neon/0.25.5 Connection: TE TE: trailers Depth: 0 Destination: http://myhostname.mydomain:4004/DAVtest1/litmus/nonesuch/foo Overwrite: F X-Litmus: copymove: 5 (copy_nodestcoll) then apache dies. Here is the stack trace : (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1221944416 (LWP 12041)] 0x080bf0e0 in dav_get_resource (r=0x8635d18, label_allowed=0, use_checked_in=0, res_p=0xb72a9224) at mod_dav.c:724 724 err = (*conf->provider->repos->get_resource)(r, conf->dir, (gdb) where 10 #0 0x080bf0e0 in dav_get_resource (r=0x8635d18, label_allowed=0, use_checked_in=0, res_p=0xb72a9224) at mod_dav.c:724 #1 0x080c3012 in dav_method_copymove (r=0x8631d08, is_move=0) at mod_dav.c:2642 #2 0x080c70f7 in dav_handler (r=0x8631d08) at mod_dav.c:4656 #3 0x08080e31 in ap_run_handler (r=0x8631d08) at config.c:157 #4 0x0808157b in ap_invoke_handler (r=0x8631d08) at config.c:372 #5 0x080b767c in ap_process_request (r=0x8631d08) at http_request.c:258 #6 0x080b41fe in ap_process_http_connection (c=0x84d3a40) at http_core.c:184 #7 0x08089373 in ap_run_process_connection (c=0x84d3a40) at connection.c:43 #8 0x08089786 in ap_process_connection (c=0x84d3a40, csd=0x84d3890) at connection.c:178 #9 0x080f25fc in process_socket (p=0x84d3858, sock=0x84d3890, my_child_num=0, my_thread_num=0, bucket_alloc=0x862fcc8) at worker.c:544 (More stack frames follow...) (gdb) p conf $1 = (dav_dir_conf *) 0x84396f8 (gdb) p conf->provider $2 = (const dav_provider *) 0x0 (gdb) The reason is : conf = ap_get_module_config(r->per_dir_config, &dav_module); /* assert: conf->provider != NULL */ /* resolve the resource */ err = (*conf->provider->repos->get_resource)(r, conf->dir, label, use_checked_in, res_p); dav_get_resource doesn't check if there is no provider in conf and try to access the resource. This case also needs to be handled. Removing the keyword PatchAvailable so that we can provide the fix for this issue too. Created attachment 19673 [details] Revised patch. In summary there were two issues with COPY method. (a) If Destination directory doesn't exist but it is still inside the DAV directory, apache returned 500. In this fix if destination directory doesn't exist, we return 409 Conflict. (b) If Destination directory doesn't fall under a DAV provider, apache crashes. In this fix if Destination directory doesn't exist then 403 forbidden is returned. Here are response code suggested by rfc 2518 : http://asg.web.cmu.edu/rfc/rfc2518.html#sec-8.8 Here is how I did the testing : my httpd.conf has following configuration : <Directory "/disk/apache/apache2/htdocs/DAVtest"> Options Indexes FollowSymLinks AllowOverride None order allow,deny allow from all AuthName "SMA Development server" AuthType Basic DAV On </Directory> <Directory "/disk/apache/apache2/htdocs/DAVOtherTest"> Options Indexes FollowSymLinks AllowOverride None order allow,deny allow from all AuthName "SMA Development server" AuthType Basic DAV On </Directory> --------------------------------------- Test 1 : Destination is outside DAV collection. COPY /DAVtest/litmus/copysrc HTTP/1.1 Host: localhost:4004 User-Agent: litmus/0.11 neon/0.25.5 Connection: TE TE: trailers Depth: 0 Destination: http://localhost:4004/DAVtest1/litmus/nonesuch/foo Overwrite: F X-Litmus: copymove: 5 (copy_nodestcoll) Response : Date: Wed, 07 Mar 2007 00:32:52 GMT Server: Apache/2.2.5-dev (Unix) mod_ssl/2.2.5-dev OpenSSL/0.9.8a DAV/2 SVN/1.4.3 mod_perl/2.0.4-dev Perl/v5.8.8 Content-Length: 178 Content-Type: text/html <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>403 Forbidden</title> </head><body> <h1>Forbidden</h1> <p>Destination URI had an error.</p> </body></html> --------------------------------------- Test 2 : Destination is inside DAV collection but it doesn't exists. COPY /DAVtest/litmus/copysrc HTTP/1.1 Host: localhost:4004 User-Agent: litmus/0.11 neon/0.25.5 Connection: TE TE: trailers Depth: 0 Destination: http://localhost:4004/DAVtest/litmus/nonesuch/foo Overwrite: F X-Litmus: copymove: 5 (copy_nodestcoll) Date: Wed, 07 Mar 2007 00:33:02 GMT Server: Apache/2.2.5-dev (Unix) mod_ssl/2.2.5-dev OpenSSL/0.9.8a DAV/2 SVN/1.4.3 mod_perl/2.0.4-dev Perl/v5.8.8 Content-Length: 509 Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>409 Conflict</title> </head><body> <h1>Conflict</h1> <p>The server encountered an internal error or misconfiguration and was unable to complete your request.</p> <p>Please contact the server administrator, you@example.com and inform them of the time the error occurred, and anything you might have done that may have caused the error.</p> <p>More information about this error may be available in the server error log.</p> </body></html> --------------------------------------- Test 3 : Destination is in other DAV collection COPY /DAVtest/litmus/copysrc HTTP/1.1 Host: localhost:4004 User-Agent: litmus/0.11 neon/0.25.5 Connection: TE TE: trailers Depth: 0 Destination: http://localhost:4004/DAVOtherTest/foo Overwrite: F X-Litmus: copymove: 5 (copy_nodestcoll) Date: Wed, 07 Mar 2007 00:40:18 GMT Server: Apache/2.2.5-dev (Unix) mod_ssl/2.2.5-dev OpenSSL/0.9.8a DAV/2 SVN/1.4.3 mod_perl/2.0.4-dev Perl/v5.8.8 Location: http://localhost:4004/DAVOtherTest/foo Content-Length: 192 Content-Type: text/html <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>201 Created</title> </head><body> <h1>Created</h1> <p>Destination /DAVOtherTest/foo has been created.</p> </body></html> --------------------------------------- Comment on attachment 19673 [details] Revised patch. Index: modules/dav/fs/repos.c =================================================================== --- modules/dav/fs/repos.c (revision 500367) +++ modules/dav/fs/repos.c (working copy) @@ -348,8 +348,19 @@ status = apr_file_open(&outf, dst, APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BINARY, perms, p); if (status != APR_SUCCESS) { + char *dirpath = NULL; + apr_finfo_t dir_finfo; + apr_status_t rv; apr_file_close(inf); + /* check if destination directory exists if not then return + * HTTP_CONFLICT + */ + dirpath = ap_make_dirstr_parent(p, dst); + rv = apr_stat(&dir_finfo, dirpath, APR_FINFO_NORM, p); + if (rv != APR_SUCCESS) + return dav_new_error(p, HTTP_CONFLICT, 0, dirpath); + return dav_new_error(p, MAP_IO2HTTP(status), 0, "Could not open file for writing"); } Index: modules/dav/main/mod_dav.c =================================================================== --- modules/dav/main/mod_dav.c (revision 500367) +++ modules/dav/main/mod_dav.c (working copy) @@ -2637,6 +2637,10 @@ return dav_error_response(r, lookup.rnew->status, "Destination URI had an error."); } + if (!dav_get_provider(lookup.rnew)) { + return dav_error_response(r, HTTP_FORBIDDEN, + "Destination URI had an error."); + } /* Resolve destination resource */ err = dav_get_resource(lookup.rnew, 0 /* label_allowed */, Created attachment 19674 [details]
Revised Patch
By mistake I attached comments as patch previously. Sorry for that. (Is there a
way to delete it?).
For me the 500 on COPY occurs when source file is not readable (-w--w---- for example) and the destination is OK: [Thu Dec 13 19:20:50 2007] [error] [client 127.0.0.1] Could not MOVE/COPY /uploads/kermit-ui/dialog.diff. [500, #0] [Thu Dec 13 19:20:50 2007] [error] [client 127.0.0.1] (13)Permission denied: Could not open file for reading [500, #0] I think it should return 403 or something, but not 500. There is no need to perform the additional stat in the ENOENT case as the preceding apr_file_open has the APR_CREATE flag set. This means the ENOENT status will mean that an intermediate directory does not exist (man 2 open). Although it could also mean a dangling symlink in the intermediate path, this is for all intents and purposes equivalent - it should still be a 409. Attaching a simpler patch shortly. Although the patch does not fix a second (independent) problem (COPY/MOVE from a non readable source should not return 500) I don't see why this is a reason why not to fix one of these bugs. The original report for the litmus test is: (COPY/MOVE to a destination collection where an intermediate does not exist should return 403) which is what the patch fixes. Perhaps a new bug should be created (COPY/MOVE from a non readable source should not return 500) or this one left open and retitled - but can we possbily apply a fix for one of these bugs. Created attachment 21345 [details]
revised patch without additional apr_stat
reformulate previous patch removing redundant apr_stat call and providing a
more informative error message.
fixes the "COPY/MOVE to a destination collection where an intermediate
directory does not exist should return 409" case. verified with litmus that it
fixes the warning on the copy_nodestcoll test.
the mod_dav.c fragment fixes a related but distinct issue (COPY/MOVE to a
destination URI with no provider causes segfault) - not specifically tested but
limtus passes and so do general tests with OS X DAV client.
COPY/MOVE from a non readable source should not return 500 issue not addressed
in this patch although I believe this is a separate bug.
The segfault part is already fixed in trunk and 2.2.x as PR 44734. The 500 instead of 409 part is fixed in trunk as r834073 and r834107 Created attachment 26610 [details]
mobile device error report
error created by blackberry.com
(In reply to Stefan Fritsch from comment #11) > The segfault part is already fixed in trunk and 2.2.x as PR 44734. > > The 500 instead of 409 part is fixed in trunk as r834073 and r834107 This bug still exists in 2.4.25 (on MacOSX): % cadaver https://slenderpoke.local:8001/test2/ Authentication required for My Test Realm on server `slenderpoke.local': Username: test2 Password: dav:/test2/> mkcol foo Creating `foo': succeeded. dav:/test2/> mkcol foo/bar Creating `foo/bar': succeeded. dav:/test2/> put httpd-bug39299.pl foo/bar/somefile Uploading httpd-bug39299.pl to `/test2/foo/bar/somefile': Progress: [=============================>] 100.0% of 1158 bytes succeeded. dav:/test2/> mv foo/bar/somefile foo/baz/somefile Moving `/test2/foo/bar/somefile' to `/test2/foo/baz/somefile': failed: 500 Internal Server Error The 2.4.x branch was branched from r1200449, so it should include r834073 and r834107. The bug also still exists in httpd built from the trunk (r1795372): dav:/bugzilla39299/> mkcol fromcoll Creating `fromcoll': succeeded. dav:/bugzilla39299/> put testfile fromcoll/somefile Uploading testfile to `/bugzilla39299/fromcoll/somefile': Progress: [=============================>] 100.0% of 18 bytes succeeded. dav:/bugzilla39299/> mv fromcoll/somefile tocoll/somefile Moving `/bugzilla39299/fromcoll/somefile' to `/bugzilla39299/tocoll/somefile': failed: 500 Internal Server Error dav:/bugzilla39299/> mkcol tocoll Creating `tocoll': succeeded. dav:/bugzilla39299/> mv fromcoll/somefile tocoll/somefile Moving `/bugzilla39299/fromcoll/somefile' to `/bugzilla39299/tocoll/somefile': succeeded. [Tue May 16 23:15:33.225431 2017] [dav:error] [pid 69020:tid 123145307131904] [client 127.0.0.1:65432] Could not MOVE/COPY /bugzilla39299/fromcoll/somefile. [500, #0] [Tue May 16 23:15:33.225463 2017] [dav:error] [pid 69020:tid 123145307131904] (2)No such file or directory: [client 127.0.0.1:65432] Could not rename resource. [500, #0] Please help us to refine our list of open and current defects; this is a mass update of old and inactive Bugzilla reports which reflect user error, already resolved defects, and still-existing defects in httpd. As repeatedly announced, the Apache HTTP Server Project has discontinued all development and patch review of the 2.2.x series of releases. The final release 2.2.34 was published in July 2017, and no further evaluation of bug reports or security risks will be considered or published for 2.2.x releases. All reports older than 2.4.x have been updated to status RESOLVED/LATER; no further action is expected unless the report still applies to a current version of httpd. If your report represented a question or confusion about how to use an httpd feature, an unexpected server behavior, problems building or installing httpd, or working with an external component (a third party module, browser etc.) we ask you to start by bringing your question to the User Support and Discussion mailing list, see [https://httpd.apache.org/lists.html#http-users] for details. Include a link to this Bugzilla report for completeness with your question. If your report was clearly a defect in httpd or a feature request, we ask that you retest using a modern httpd release (2.4.33 or later) released in the past year. If it can be reproduced, please reopen this bug and change the Version field above to the httpd version you have reconfirmed with. Your help in identifying defects or enhancements still applicable to the current httpd server software release is greatly appreciated. |