From 54587c904e33b9868b1aa64dfd2eff025c55b545 Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Mon, 5 Jan 2026 12:41:30 +0000 Subject: [PATCH] mod_dav: Fix security issue in unreleased MS-WDV support: * modules/dav/main/ms_wdv.c (mswdv_combined_proppatch): The MS-WDV combined PROPPATCH handler reads a 16-byte hex length prefix from the request body and uses it directly for memory allocation without bounds checking. An attacker can specify an extremely large value to trigger OOM and crash the worker process. This patch validates the parsed length against LimitXMLRequestBody and APR_SIZE_MAX before allocation. Reported by: Pavel Kohout, Aisle Research, www.aisle.com Submitted by: Pavel Kohout, jorton --- modules/dav/main/ms_wdv.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/dav/main/ms_wdv.c b/modules/dav/main/ms_wdv.c index ecb506d168e..bff0689922e 100644 --- a/modules/dav/main/ms_wdv.c +++ b/modules/dav/main/ms_wdv.c @@ -6,6 +6,7 @@ #include "http_protocol.h" #include "http_request.h" #include "http_log.h" +#include "http_core.h" #include "mod_dav.h" @@ -589,7 +590,7 @@ static dav_error *mswdv_combined_proppatch(request_rec *r) apr_bucket_brigade *bb; apr_status_t status; apr_size_t len = 16; - apr_off_t proppatch_len; + apr_off_t proppatch_len, limit; char proppatch_len_str[16 + 1]; char *proppatch_data; @@ -618,6 +619,17 @@ static dav_error *mswdv_combined_proppatch(request_rec *r) return dav_new_error(r->pool, HTTP_BAD_REQUEST, 0, status, "Bad PROPPATCH part length"); + /* Validate PROPPATCH length against configured limits */ + limit = ap_get_limit_xml_body(r); + if (limit > 0 && proppatch_len > limit) { + return dav_new_error(r->pool, HTTP_REQUEST_ENTITY_TOO_LARGE, 0, 0, + "PROPPATCH part length exceeds configured limit"); + } + if (proppatch_len <= 0 || proppatch_len > (apr_off_t)APR_SIZE_MAX) { + return dav_new_error(r->pool, HTTP_REQUEST_ENTITY_TOO_LARGE, 0, 0, + "PROPPATCH part length invalid or too large"); + } + apr_brigade_destroy(bb); bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);