https://bz.apache.org/bugzilla/show_bug.cgi?id=70298
Bug ID: 70298
Summary: mod_dav_lock: dav_size_indirect() reserves sizeof(int)
for a field written as apr_size_t
Product: Apache httpd-2
Version: 2.4-HEAD
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P2
Component: mod_dav
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
modules/dav/lock/locks.c (2.4.x tip c904033f65) sizes each serialized
indirect lock record with:
#define dav_size_indirect(a) (1 + sizeof(apr_uuid_t) \
+ sizeof(time_t) \
+ sizeof(int) + (a)->key.dsize)
but dav_generic_save_lock_record() writes the key-length field as
sizeof(ip->key.dsize), and apr_datum_t.dsize is apr_size_t (8 bytes on
LP64):
memcpy(ptr, &ip->key.dsize, sizeof(ip->key.dsize)); /* locks.c:544 */
Each indirect record is therefore written 4 bytes past the end of its
apr_pcalloc() buffer (locks.c:505). The loader reads the field as
`*((int *) ...)` (locks.c:670) but advances by sizeof(ip->key.dsize).
The copy of the same macro in modules/dav/fs/lock.c:163 already uses
sizeof((a)->key.dsize), so the fix is to make locks.c match:
--- a/modules/dav/lock/locks.c
+++ b/modules/dav/lock/locks.c
@@ -155,5 +155,5 @@
#define dav_size_indirect(a) (1 + sizeof(apr_uuid_t) \
+ sizeof(time_t) \
- + sizeof(int) + (a)->key.dsize)
+ + sizeof((a)->key.dsize) + (a)->key.dsize)
This is NOT reproducible with the distributed modules alone. mod_dav_fs
uses its own lock code (modules/dav/fs/lock.c) and never calls
dav_hooks_locks_generic, so the generic provider is reached only through a
DAV repository provider that is wired to it, with DAVGenericLockDB set.
I reproduced it with a small test-only module that registers a clone of
the "filesystem" provider using the generic hooks; it is
test scaffolding, not evidence of an issue in a stock configuration.
With that module on a 64-bit build:
1. LOCK with "Depth: infinity" on a collection with one member.
2. LOCK on the member with an "If:" header naming the token from step 1.
Observed:
- Non-instrumented build (httpd 2.4.6 distro package): step 2 returns
HTTP 500 with "The lock database was found to be corrupt".
- AddressSanitizer build of 2.4.x: heap-buffer-overflow READ in
dav_generic_load_lock_record() (locks.c:672) via apr_pmemdup(). This
is visible only under ASAN. I have not shown impact beyond the 500
above in a non-instrumented build.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]