Bug 16313 - Multiple MMapFile causes Segmentation fault
Summary: Multiple MMapFile causes Segmentation fault
Status: CLOSED FIXED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_file_cache (show other bugs)
Version: 2.0.44
Hardware: All Linux
: P3 major (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-01-22 03:13 UTC by John Kearns
Modified: 2004-11-16 19:05 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John Kearns 2003-01-22 03:13:45 UTC
Specifying more than one file with the MMapFile configuration command causes 
httpd to core dump with a Segmentation fault.  Problem did not happen in 2.0.43.

Some debug of the code with gdb shows that mmap_cleanup (mmap.c) is called with 
a *themap with it's next and prev pointers set to NULL, causing APR_RING_REMOVE 
to fail.

Tested with MMapFile commands:
MMapFile /usr/local/apache/htdocs/apache_pb2.gif
MMapFile /usr/local/apache/htdocs/apache_pb2.png
(also segfaults if both files specified with one MMapFile command)

Here is the gdb dump:

(gdb) r -DONE_PROCESS
Starting program: /usr/local/apache/bin/httpd -DONE_PROCESS
[New Thread 1024 (LWP 19351)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1024 (LWP 19351)]
0x400fca8d in mmap_cleanup (themmap=0x80e6340) at mmap.c:90
90          APR_RING_REMOVE(mm,link);
(gdb) where
#0  0x400fca8d in mmap_cleanup (themmap=0x80e6340) at mmap.c:90
#1  0x400fe986 in apr_pool_cleanup_run (p=0x80a8ef0, data=0x80e6340, 
cleanup_fn=0x400fca58 <mmap_cleanup>) at apr_pools.c:1967
#2  0x400fccee in apr_mmap_delete (mm=0x80e6340) at mmap.c:195
#3  0x402ce2a2 in cleanup_file_cache (sconfv=0x80d7870) at mod_file_cache.c:177
#4  0x400fe9c7 in run_cleanups (cref=0x80a8f00) at apr_pools.c:1976
#5  0x400fde3f in apr_pool_clear (pool=0x80a8ef0) at apr_pools.c:718
#6  0x08071d08 in main (argc=2, argv=0xbffffb04) at main.c:608
#7  0x401a0657 in __libc_start_main (main=0x80715fc <main>, argc=2, 
ubp_av=0xbffffb04, init=0x80609c4 <_init>, 
    fini=0x80917a0 <_fini>, rtld_fini=0x4000dcd4 <_dl_fini>, 
stack_end=0xbffffafc) at ../sysdeps/generic/libc-start.c:129
Comment 1 Cliff Woolley 2003-01-22 04:19:24 UTC
 aawwwww mannnnnnnnnn.  :(  That would be my fault.  Sheesh.  I'll look into  it.  Thanks for the report and the backtrace! 
Comment 2 Cliff Woolley 2003-01-22 05:50:23 UTC
Try the patch given in  
http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=104321419500550&w=2 and see 
if that fixes it for you.  Assuming it stops crashing, try some server restarts 
and make sure you don't get any memory or file descriptor leaks. 
 
Thanks, 
Cliff 
Comment 3 John Kearns 2003-01-22 23:23:09 UTC
Tried the patch...it works just fine.
Out of interest though, instead of (or also with) deleting the section of code 
that calls the APR_RING_REMOVE define, why not just add error-checking into the 
APR_RING_UNSPLICE define with a couple of 'if' statements in apr_ring.h?
Example:

#define APR_RING_UNSPLICE(ep1, epN, link) do {                          \
        if (APR_RING_PREV((ep1), link))                                 \
                APR_RING_NEXT(APR_RING_PREV((ep1), link), link) =       \
                        APR_RING_NEXT((epN), link);                     \
        if (APR_RING_NEXT((epN), link))                                 \
                APR_RING_PREV(APR_RING_NEXT((epN), link), link) =       \
                        APR_RING_PREV((ep1), link);                     \
   } while (0)

I tested this modification with the original mod_file_cache.c and it seems to 
work as well.  Although, truth be told, I'm not entirely sure how to find out 
if it has memory or fd leaks (I program mainly on win32...unix still mystifies 
me at times!)  The only reason I'd suggest this is to keep this same problem 
happening in potential future modules that register a cleanup call for a 
simular list.

Thanks-
Drew
Comment 4 Cliff Woolley 2003-01-22 23:51:51 UTC
It's a design decision we made through all of APR: we don't test for NULL.  If it's NULL, that's a bug, and it will cause a segfault.  If it segfaults, that's good, because it lets us find the bug very easily.  Another concern is that code with no bugs will never have those pointers be NULL, so non-buggy code would be paying a performance penalty just to accommodate buggy code.  Thanks for testing the patch.  I'll look for leaks myself.  --Cliff 
Comment 5 John Kearns 2003-01-23 00:40:10 UTC
Heh..makes sense!  Thanks for quick fix on this.
Looking forward to the next release!
-Drew