Fix for segfault in RubyChildInitHandler

Michael Granger <[email protected]> Fri, 26 May 2006 18:00:36 -0700
Newsgroups gmane.comp.apache.mod-ruby
Message-ID <[email protected]>
--Apple-Mail-4-733228603
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	delsp=yes;
	format=flowed

The most recent mod_ruby (rev 125) segfaults when a  
RubyChildInitHandler is configured. Here is a minimal httpd.conf  
testcase that can be run from the working directory:

   #
   # Minimal RubyChildInitHandler testcase
   #

   ServerRoot "."

   LoadModule ruby_module ./mod_ruby.so

   PidFile testserver.pid
   ErrorLog test.error_log
   LogLevel debug

   DocumentRoot "doc"
   Listen 8888
   RubyChildInitHandler "class CIHandler; def child_init(r); return  
Apache::OK; end; end; CIHandler.new"


Starting the server on MacOS/X with Apache 2.2.x (prefork mpm) does  
this:

   $ httpd -d . -f minimal.conf -e debug -X
   [Fri May 26 17:26:27 2006] [debug] mod_so.c(246): loaded module  
ruby_module
   Abort trap

With the following stacktrace:

   Exception:  EXC_BAD_ACCESS (0x0001)
   Codes:      KERN_PROTECTION_FAILURE (0x0002) at 0x00000014

   Thread 0 Crashed:
   0   mod_ruby.so 	0x0111e1d8 apache_request_new + 248 (request.c:195)
   1   mod_ruby.so 	0x01118948 ruby_handler_internal + 440  
(mod_ruby.c:1130)
   2   mod_ruby.so 	0x01118d48 ruby_handler + 212 (mod_ruby.c:1329)
   3   httpd       	0x0000a8fc ap_run_child_init + 112 (config.c:153)
   4   httpd       	0x00029424 child_main + 324 (prefork.c:515)
   5   httpd       	0x00029890 make_child + 136 (prefork.c:680)
   6   httpd       	0x00029ebc ap_mpm_run + 1172 (prefork.c:956)
   7   httpd       	0x00003e00 main + 3228 (main.c:712)
   8   httpd       	0x00002630 _start + 344 (crt.c:272)
   9   httpd       	0x000024d4 start + 60

This is caused by apache_request_new() trying to build the per- 
directory options array:

   if (dconf->gc_per_request)

Because the request is a fake one from fake_request_rec() in  
mod_ruby.c:842, r->dconf is 0x00, and so segfaults when accessed.

I discovered a similar situation in mod_ruby.c:1180 at the very end  
of per_request_cleanup():

   if (dconf->gc_per_request)

The attached patch works around these two situations by adding guard  
conditionals around code that uses dconf, but I'm not sure if it's  
the best way to do this.

I hereby transfer the rights to any and all code in this email to  
Shugo-san.


--Apple-Mail-4-733228603
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="child_init_handler_fix.patch"
Content-Disposition: attachment;
	filename=child_init_handler_fix.patch

Index: mod_ruby.c
===================================================================
--- mod_ruby.c	(revision 125)
+++ mod_ruby.c	(working copy)
@@ -1177,7 +1177,7 @@
 	    restore_env(r->pool, rconf->saved_env);
     }
     rb_progname = Qnil;
-    if (dconf->gc_per_request)
+    if (dconf && dconf->gc_per_request)
 	rb_gc();
 }
 
Index: request.c
===================================================================
--- request.c	(revision 125)
+++ request.c	(working copy)
@@ -192,14 +192,16 @@
     data->cookies = rb_hash_new();
     data->param_table = Qnil;
     data->options = rb_hash_new();
-    opts_arr = apr_table_elts(dconf->options);
-    opts = (table_entry *) opts_arr->elts;
-    for (i = 0; i < opts_arr->nelts; i++) {
-        if (opts[i].key == NULL)
-	    continue;
-	rb_hash_aset(data->options,
-		     rb_tainted_str_new2(opts[i].key),
-		     rb_tainted_str_new2(opts[i].val));
+    if (dconf) {
+        opts_arr = apr_table_elts(dconf->options);
+        opts = (table_entry *) opts_arr->elts;
+        for (i = 0; i < opts_arr->nelts; i++) {
+            if (opts[i].key == NULL)
+                continue;
+            rb_hash_aset(data->options,
+                         rb_tainted_str_new2(opts[i].key),
+                         rb_tainted_str_new2(opts[i].val));
+        }
     }
     
     rb_apache_register_object(obj);

--Apple-Mail-4-733228603
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
	charset=US-ASCII;
	format=flowed


--
Michael Granger <[email protected]>
Rubymage, Architect, Believer
The FaerieMUD Consortium <http://www.faeriemud.org/>





--Apple-Mail-4-733228603--