From db27496d28e9ea14a92df5969da8d39771e674e9 Mon Sep 17 00:00:00 2001 From: Graham Leggett Date: Mon, 20 Nov 2023 13:16:10 +0000 Subject: [PATCH] Backport to 2.4: *) Allow mod_dav_fs to tolerate race conditions between PROPFIND and an operation which removes a directory/file between apr_dir_read() and apr_stat(). Current behaviour is to abort the connection which seems inferior to tolerating (and logging) the error. trunk patch: http://svn.apache.org/r1910811 2.4.x patch: https://svn.apache.org/repos/asf/httpd/httpd/patches/2.4.x/httpd-2.4-dav-tolerant.patch +1: minfrin, ylavic, jorton git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1913982 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 5 +++++ STATUS | 8 -------- include/ap_mmn.h | 3 ++- modules/dav/fs/repos.c | 14 ++++++++++++++ modules/dav/main/mod_dav.c | 2 +- modules/dav/main/mod_dav.h | 1 + 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 34aeaac6f3a..2c29c9c8fe7 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,11 @@ -*- coding: utf-8 -*- Changes with Apache 2.4.59 + *) Allow mod_dav_fs to tolerate race conditions between PROPFIND and an + operation which removes a directory/file between apr_dir_read() and + apr_stat(). Current behaviour is to abort the connection which seems + inferior to tolerating (and logging) the error. [Joe Orton] + *) mod_ldap: HTML-escape data in the ldap-status handler. [Eric Covener, Chamal De Silva] diff --git a/STATUS b/STATUS index b872224c608..adfe8452106 100644 --- a/STATUS +++ b/STATUS @@ -153,14 +153,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - *) Allow mod_dav_fs to tolerate race conditions between PROPFIND and an - operation which removes a directory/file between apr_dir_read() and - apr_stat(). Current behaviour is to abort the connection which seems - inferior to tolerating (and logging) the error. - trunk patch: http://svn.apache.org/r1910811 - 2.4.x patch: https://svn.apache.org/repos/asf/httpd/httpd/patches/2.4.x/httpd-2.4-dav-tolerant.patch - +1: minfrin, ylavic, jorton - *) core: Fix use after free warning with gcc -fanalyzer. trunk patch: http://svn.apache.org/r1892413 2.4.x patch: https://svn.apache.org/repos/asf/httpd/httpd/patches/2.4.x/httpd-2.4-use-after-free.patch diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 2e4b65ca836..6f80ab35f74 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -598,6 +598,7 @@ * 20120211.128 (2.4.55-dev) Add AP_CTIME_OPTION_GMTOFF to util_time.h * 20120211.129 (2.4.58-dev) Add ap_get_pollfd_from_conn() * 20120211.130 (2.4.59-dev) Add ap_proxy_determine_address() + * 20120211.131 (2.4.59-dev) Add DAV_WALKTYPE_TOLERANT */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -605,7 +606,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20120211 #endif -#define MODULE_MAGIC_NUMBER_MINOR 130 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 131 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/modules/dav/fs/repos.c b/modules/dav/fs/repos.c index d38868c70a1..64bc894cf66 100644 --- a/modules/dav/fs/repos.c +++ b/modules/dav/fs/repos.c @@ -35,6 +35,7 @@ #include "mod_dav.h" #include "repos.h" +APLOG_USE_MODULE(dav_fs); /* to assist in debugging mod_dav's GET handling */ #define DEBUG_GET_HANDLER 0 @@ -1586,6 +1587,19 @@ static dav_error * dav_fs_walker(dav_fs_walker_context *fsctx, int depth) status = apr_stat(&fsctx->info1.finfo, fsctx->path1.buf, DAV_FINFO_MASK, pool); if (status != APR_SUCCESS && status != APR_INCOMPLETE) { + dav_resource_private *ctx = params->root->info; + + ap_log_rerror(APLOG_MARK, APLOG_ERR, status, ctx->r, + APLOGNO(10472) "could not access file (%s) during directory walk", + fsctx->path1.buf); + + /* If being tolerant, ignore failure due to losing a race + * with some other process deleting files out from under + * the directory walk. */ + if ((params->walk_type & DAV_WALKTYPE_TOLERANT) + && APR_STATUS_IS_ENOENT(status)) { + continue; + } /* woah! where'd it go? */ /* ### should have a better error here */ err = dav_new_error(pool, HTTP_NOT_FOUND, 0, status, NULL); diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index a035f254f4d..dea3f18b118 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -2217,7 +2217,7 @@ static int dav_method_propfind(request_rec *r) return HTTP_BAD_REQUEST; } - ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH; + ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH | DAV_WALKTYPE_TOLERANT; ctx.w.func = dav_propfind_walker; ctx.w.walk_ctx = &ctx; ctx.w.pool = r->pool; diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index eca34a26dbe..c8c54f38776 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -1823,6 +1823,7 @@ typedef struct #define DAV_WALKTYPE_AUTH 0x0001 /* limit to authorized files */ #define DAV_WALKTYPE_NORMAL 0x0002 /* walk normal files */ #define DAV_WALKTYPE_LOCKNULL 0x0004 /* walk locknull resources */ +#define DAV_WALKTYPE_TOLERANT 0x0008 /* tolerate non-fatal errors */ /* callback function and a client context for the walk */ dav_error * (*func)(dav_walk_resource *wres, int calltype);