Package: libapache2-mod-gnutls
Version: 0.5.6-1
Severity: important
Tags: squeeze sid patch

Hi,

After upgrading our subversion server from lenny to squeeze, our apache server
was segfaulting on almost all https connections. All apache2 children crashed,
see below:

[Sat Feb 26 11:06:20 2011] [notice] child pid 5439 exit signal Segmentation 
fault (11)
[Sat Feb 26 11:06:25 2011] [notice] child pid 5440 exit signal Segmentation 
fault (11)
[Sat Feb 26 11:06:26 2011] [notice] child pid 5500 exit signal Segmentation 
fault (11)
[Sat Feb 26 11:06:27 2011] [notice] child pid 5533 exit signal Segmentation 
fault (11)
[Sat Feb 26 11:06:27 2011] [notice] child pid 5534 exit signal Segmentation 
fault (11)
[Sat Feb 26 11:06:29 2011] [notice] child pid 5590 exit signal Segmentation 
fault (11)
[Sat Feb 26 11:06:30 2011] [notice] child pid 5618 exit signal Segmentation 
fault (11)
[Sat Feb 26 11:06:30 2011] [notice] child pid 5619 exit signal Segmentation 
fault (11)
[Sat Feb 26 11:06:32 2011] [notice] child pid 5676 exit signal Segmentation 
fault (11)
[Sat Feb 26 11:06:33 2011] [notice] child pid 5704 exit signal Segmentation 
fault (11)
[Sat Feb 26 11:06:33 2011] [notice] child pid 5705 exit signal Segmentation 
fault (11)

The following bug report describes this behaviour and contains a patch:
http://issues.outoforder.cc/view.php?id=106

I've applied the patch to the debian package and this seems to fix this bug.

Please consider applying this patch to the Debian package and a backport for a 
squeeze
point release.

According to the bug report, this bug is also fixed in the 0.5.8 upstream 
version.

Regards,

Rik


-- System Information:
Debian Release: 6.0
  APT prefers squeeze-updates
  APT policy: (500, 'squeeze-updates'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.32-5-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages libapache2-mod-gnutls depends on:
ii  libc6                         2.11.2-10  Embedded GNU C Library: Shared lib
ii  libgnutls26                   2.8.6-1    the GNU TLS library - runtime libr

libapache2-mod-gnutls recommends no packages.

libapache2-mod-gnutls suggests no packages.

-- no debconf information
diff --git a/src/gnutls_hooks.c b/src/gnutls_hooks.c
index 3ce8188..7c638fb 100644
--- a/src/gnutls_hooks.c
+++ b/src/gnutls_hooks.c
@@ -486,7 +486,12 @@ void mgs_hook_child_init(apr_pool_t * p, server_rec * s)
 
 const char *mgs_hook_http_scheme(const request_rec * r)
 {
-    mgs_srvconf_rec *sc =
+    mgs_srvconf_rec *sc;
+    
+    if (r == NULL)
+        return NULL;
+    
+    sc =
 	(mgs_srvconf_rec *) ap_get_module_config(r->server->module_config,
 						 &gnutls_module);
 
@@ -500,7 +505,12 @@ const char *mgs_hook_http_scheme(const request_rec * r)
 
 apr_port_t mgs_hook_default_port(const request_rec * r)
 {
-    mgs_srvconf_rec *sc =
+    mgs_srvconf_rec *sc;
+    
+    if (r == NULL)
+        return 0;
+    
+    sc =
 	(mgs_srvconf_rec *) ap_get_module_config(r->server->module_config,
 						 &gnutls_module);
 
@@ -579,6 +589,9 @@ mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session)
     mgs_srvconf_rec *tsc;
 #endif
 
+    if (session == NULL)
+        return NULL;
+
     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
     ctxt = gnutls_transport_get_ptr(session);
 
@@ -693,12 +706,18 @@ static mgs_handle_t *create_gnutls_handle(apr_pool_t * pool, conn_rec * c)
 int mgs_hook_pre_connection(conn_rec * c, void *csd)
 {
     mgs_handle_t *ctxt;
-    mgs_srvconf_rec *sc =
+    mgs_srvconf_rec *sc;
+
+    _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
+    
+    if (c == NULL)
+        return DECLINED;
+    
+    sc =
 	(mgs_srvconf_rec *) ap_get_module_config(c->base_server->
 						 module_config,
 						 &gnutls_module);
 
-    _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
     if (!(sc && (sc->enabled == GNUTLS_ENABLED_TRUE))) {
 	return DECLINED;
     }
@@ -732,13 +751,16 @@ int mgs_hook_fixups(request_rec * r)
     mgs_handle_t *ctxt;
     int rv = OK;
 
+    if (r == NULL)
+        return DECLINED;
+
     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
     apr_table_t *env = r->subprocess_env;
 
     ctxt =
 	ap_get_module_config(r->connection->conn_config, &gnutls_module);
 
-    if (!ctxt) {
+    if (!ctxt || ctxt->session == NULL) {
 	return DECLINED;
     }
 
@@ -804,14 +826,19 @@ int mgs_hook_authz(request_rec * r)
 {
     int rv;
     mgs_handle_t *ctxt;
-    mgs_dirconf_rec *dc = ap_get_module_config(r->per_dir_config,
+    mgs_dirconf_rec *dc;
+    
+    if (r == NULL)
+        return DECLINED;
+    
+    dc = ap_get_module_config(r->per_dir_config,
 					       &gnutls_module);
 
     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
     ctxt =
 	ap_get_module_config(r->connection->conn_config, &gnutls_module);
 
-    if (!ctxt) {
+    if (!ctxt || ctxt->session == NULL) {
 	return DECLINED;
     }
 
@@ -875,6 +902,9 @@ mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side,
     size_t len;
     int ret, i;
 
+    if (r == NULL)
+        return;
+
     apr_table_t *env = r->subprocess_env;
 
     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
@@ -983,6 +1013,9 @@ mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side
     const char *tmp;
     size_t len;
     int ret;
+    
+    if (r == NULL)
+        return;
 
     _gnutls_log(debug_log_fp,   "%s: %d\n", __func__, __LINE__);
     apr_table_t *env = r->subprocess_env;
@@ -1052,6 +1085,9 @@ static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt)
     } cert;
     apr_time_t expiration_time, cur_time;
 
+    if (r == NULL || ctxt == NULL || ctxt->session == NULL)
+        return HTTP_FORBIDDEN;
+
     _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__);
     cert_list =
 	gnutls_certificate_get_peers(ctxt->session, &cert_list_size);
diff --git a/src/gnutls_io.c b/src/gnutls_io.c
index 8187da6..ba03fce 100644
--- a/src/gnutls_io.c
+++ b/src/gnutls_io.c
@@ -221,6 +221,10 @@ static apr_status_t gnutls_io_input_read(mgs_handle_t * ctxt,
             ctxt->input_block = APR_NONBLOCK_READ;
         }
     }
+    
+    if (ctxt->session == NULL) {
+        return APR_EGENERAL;
+    }
 
     while (1) {
 
@@ -360,7 +364,7 @@ static int gnutls_do_handshake(mgs_handle_t * ctxt)
     int errcode;
     int maxtries = HANDSHAKE_MAX_TRIES;
 
-    if (ctxt->status != 0) {
+    if (ctxt->status != 0 || ctxt->session == NULL) {
         return -1;
     }
 
@@ -441,6 +445,9 @@ tryagain:
 int mgs_rehandshake(mgs_handle_t * ctxt)
 {
     int rv;
+    
+    if (ctxt->session == NULL)
+        return -1;
 
     rv = gnutls_rehandshake(ctxt->session);
     
@@ -565,7 +572,7 @@ apr_status_t mgs_filter_output(ap_filter_t * f,
 
             apr_bucket_copy(bucket, &e);
             APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, e);
-            
+ 
             if ((status = ap_pass_brigade(f->next, tmpb)) != APR_SUCCESS) {
                 apr_brigade_cleanup(ctxt->output_bb);
                 return status;
@@ -609,10 +616,14 @@ apr_status_t mgs_filter_output(ap_filter_t * f,
             
             if (len > 0) {
 
-                do {
-                    ret = gnutls_record_send(ctxt->session, data, len);
+                if (ctxt->session == NULL) {
+                    ret = GNUTLS_E_INVALID_REQUEST;
+                } else {
+                    do {
+                        ret = gnutls_record_send(ctxt->session, data, len);
+                    }
+                    while(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
                 }
-                while(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
 
                 if (ret < 0) {
                     /* error sending output */
@@ -674,7 +685,8 @@ ssize_t mgs_transport_read(gnutls_transport_ptr_t ptr,
             if (APR_STATUS_IS_EOF(ctxt->input_rc)) {
                 return 0;
             } else {
-                gnutls_transport_set_errno(ctxt->session, EINTR);
+                if (ctxt->session)
+                    gnutls_transport_set_errno(ctxt->session, EINTR);
                 return -1;
             }
         }
@@ -697,7 +709,8 @@ ssize_t mgs_transport_read(gnutls_transport_ptr_t ptr,
     if (APR_STATUS_IS_EAGAIN(ctxt->input_rc)
         || APR_STATUS_IS_EINTR(ctxt->input_rc)) {
         if (len == 0) {
-            gnutls_transport_set_errno(ctxt->session, EINTR);
+            if (ctxt->session)
+                gnutls_transport_set_errno(ctxt->session, EINTR);
             return -1;
         }
 

Reply via email to