You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by mt...@apache.org on 2006/11/10 15:26:12 UTC

svn commit: r473349 - in /tomcat/tc6.0.x/trunk/native/connector: include/tcn.h src/network.c src/sslnetwork.c

Author: mturk
Date: Fri Nov 10 06:26:11 2006
New Revision: 473349

URL: http://svn.apache.org/viewvc?view=rev&rev=473349
Log:
Backport from tomcat-connectors.
Fix coredump when the client socket is inside read/write
operation (not closed), and the Tomcat is shutdown.
The pool was destroyed twice in that case.

Modified:
    tomcat/tc6.0.x/trunk/native/connector/include/tcn.h
    tomcat/tc6.0.x/trunk/native/connector/src/network.c
    tomcat/tc6.0.x/trunk/native/connector/src/sslnetwork.c

Modified: tomcat/tc6.0.x/trunk/native/connector/include/tcn.h
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/native/connector/include/tcn.h?view=diff&rev=473349&r1=473348&r2=473349
==============================================================================
--- tomcat/tc6.0.x/trunk/native/connector/include/tcn.h (original)
+++ tomcat/tc6.0.x/trunk/native/connector/include/tcn.h Fri Nov 10 06:26:11 2006
@@ -145,6 +145,7 @@
 
 typedef struct {
     apr_pool_t   *pool;
+    apr_pool_t   *child;
     apr_socket_t *sock;
     void         *opaque;
     char         *jsbbuff;

Modified: tomcat/tc6.0.x/trunk/native/connector/src/network.c
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/native/connector/src/network.c?view=diff&rev=473349&r1=473348&r2=473349
==============================================================================
--- tomcat/tc6.0.x/trunk/native/connector/src/network.c (original)
+++ tomcat/tc6.0.x/trunk/native/connector/src/network.c Fri Nov 10 06:26:11 2006
@@ -83,8 +83,9 @@
     if (s->net && s->net->cleanup)
         (*s->net->cleanup)(s->opaque);
     if (s->sock) {
-        apr_socket_close(s->sock);
+        apr_socket_t *as = s->sock;
         s->sock = NULL;
+        apr_socket_close(as);
     }
 #ifdef TCN_DO_STATISTICS
     apr_atomic_inc32(&sp_cleared);
@@ -181,6 +182,15 @@
     GET_S_FAMILY(f, family);
     GET_S_TYPE(t, type);
 
+    a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
+    TCN_CHECK_ALLOCATED(a);
+    a->pool = p;
+    if (family >= 0)
+        a->net = &apr_socket_layer;
+    apr_pool_cleanup_register(p, (const void *)a,
+                              sp_socket_cleanup,
+                              apr_pool_cleanup_null);
+
     if (family >= 0) {
         TCN_THROW_IF_ERR(apr_socket_create(&s,
                          f, t, protocol, p), a);
@@ -188,19 +198,15 @@
 #ifdef TCN_DO_STATISTICS
     sp_created++;
 #endif
-    a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
-    TCN_CHECK_ALLOCATED(a);
     a->sock = s;
-    a->pool = p;
     if (family >= 0)
         a->net = &apr_socket_layer;
     a->opaque   = s;
-    apr_pool_cleanup_register(p, (const void *)a,
-                              sp_socket_cleanup,
-                              apr_pool_cleanup_null);
+    apr_pool_create(&a->child, a->pool);
 
-cleanup:
     return P2J(a);
+cleanup:
+    return 0;
 
 }
 
@@ -209,6 +215,18 @@
     tcn_socket_t *s = J2P(sock, tcn_socket_t *);
     UNREFERENCED_STDARGS;
     TCN_ASSERT(sock != 0);
+
+    apr_pool_cleanup_kill(s->pool, s, sp_socket_cleanup);
+    if (s->net && s->net->cleanup) {
+        (*s->net->cleanup)(s->opaque);
+        s->net = NULL;
+    }
+    if (s->sock) {
+        apr_socket_t *as = s->sock;
+        s->sock = NULL;
+        apr_socket_close(as);
+    }
+    
     apr_pool_destroy(s->pool);
 }
 
@@ -264,6 +282,10 @@
     UNREFERENCED_STDARGS;
     TCN_ASSERT(sock != 0);
 
+    apr_pool_cleanup_kill(s->pool, s, sp_socket_cleanup);
+    if (s->child) {
+        apr_pool_clear(s->child);
+    }
 #ifdef TCN_DO_STATISTICS
     apr_atomic_inc32(&sp_closed);
 #endif
@@ -272,8 +294,9 @@
         s->net = NULL;
     }
     if (s->sock) {
-        rv = (jint)apr_socket_close(s->sock);
+        apr_socket_t *as = s->sock;
         s->sock = NULL;
+        rv = (jint)apr_socket_close(as);
     }
     return rv;
 }
@@ -316,6 +339,13 @@
 
     if (s->net->type == TCN_SOCKET_APR) {
         TCN_ASSERT(s->sock != NULL);
+        a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
+        TCN_CHECK_ALLOCATED(a);
+        a->pool   = p;
+        apr_pool_cleanup_register(p, (const void *)a,
+                                  sp_socket_cleanup,
+                                  apr_pool_cleanup_null);
+
         TCN_THROW_IF_ERR(apr_socket_accept(&n, s->sock, p), n);
     }
     else {
@@ -326,15 +356,9 @@
 #ifdef TCN_DO_STATISTICS
         apr_atomic_inc32(&sp_accepted);
 #endif
-        a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
-        TCN_CHECK_ALLOCATED(a);
-        a->sock   = n;
-        a->pool   = p;
         a->net    = &apr_socket_layer;
+        a->sock   = n;
         a->opaque = n;
-        apr_pool_cleanup_register(p, (const void *)a,
-                                  sp_socket_cleanup,
-                                  apr_pool_cleanup_null);
     }
 
 cleanup:
@@ -354,6 +378,13 @@
     TCN_THROW_IF_ERR(apr_pool_create(&p, s->pool), p);
     if (s->net->type == TCN_SOCKET_APR) {
         TCN_ASSERT(s->sock != NULL);
+        a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
+        TCN_CHECK_ALLOCATED(a);
+        a->pool   = p;
+        apr_pool_cleanup_register(s->child, (const void *)a,
+                                  sp_socket_cleanup,
+                                  apr_pool_cleanup_null);
+
         TCN_THROW_IF_ERR(apr_socket_accept(&n, s->sock, p), n);
     }
     else {
@@ -364,15 +395,9 @@
 #ifdef TCN_DO_STATISTICS
         apr_atomic_inc32(&sp_accepted);
 #endif
-        a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
-        TCN_CHECK_ALLOCATED(a);
-        a->sock   = n;
-        a->pool   = p;
         a->net    = &apr_socket_layer;
+        a->sock   = n;
         a->opaque = n;
-        apr_pool_cleanup_register(p, (const void *)a,
-                                  sp_socket_cleanup,
-                                  apr_pool_cleanup_null);
     }
     return P2J(a);
 cleanup:
@@ -1202,7 +1227,7 @@
     void *rv = NULL;
 
     UNREFERENCED(o);
-    TCN_ASSERT(sock != 0);
+    TCN_ASSERT(socket != 0);
 
     if (apr_socket_data_get(&rv, J2S(key), s->sock) != APR_SUCCESS) {
         rv = NULL;

Modified: tomcat/tc6.0.x/trunk/native/connector/src/sslnetwork.c
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/native/connector/src/sslnetwork.c?view=diff&rev=473349&r1=473348&r2=473349
==============================================================================
--- tomcat/tc6.0.x/trunk/native/connector/src/sslnetwork.c (original)
+++ tomcat/tc6.0.x/trunk/native/connector/src/sslnetwork.c Fri Nov 10 06:26:11 2006
@@ -97,10 +97,15 @@
     tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)data;
 
     if (con) {
+        /* Pollset was already destroyed by
+         * the pool cleanup/destroy.
+         */
+        con->pollset = NULL;
         if (con->ssl) {
-            ssl_smart_shutdown(con->ssl, con->shutdown_type);
-            SSL_free(con->ssl);
-            con->ssl = NULL;
+            SSL *ssl = con->ssl;
+            con->ssl = NULL;            
+            ssl_smart_shutdown(ssl, con->shutdown_type);
+            SSL_free(ssl);
         }
         if (con->peer) {
             X509_free(con->peer);
@@ -157,6 +162,12 @@
     return con;
 }
 
+#ifdef WIN32
+#define APR_INVALID_SOCKET  INVALID_SOCKET
+#else
+#define APR_INVALID_SOCKET  -1
+#endif
+
 static apr_status_t wait_for_io_or_timeout(tcn_ssl_conn_t *con,
                                            int for_what)
 {
@@ -164,6 +175,18 @@
     apr_pollfd_t pfd;
     int type;
     apr_status_t status;
+    apr_os_sock_t sock;
+
+    if (!con->pollset)
+        return APR_ENOPOLL;    
+    if (!con->sock)
+        return APR_ENOTSOCK;        
+    
+    /* Check if the socket was already closed
+     */    
+    apr_os_sock_get(&sock, con->sock);    
+    if (sock == APR_INVALID_SOCKET)
+        return APR_ENOTSOCK;        
 
     /* Figure out the the poll direction */
     switch (for_what) {
@@ -241,12 +264,13 @@
     tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
 
     if (con->ssl) {
+        SSL *ssl = con->ssl;
+        con->ssl = NULL;
         if (how < 1)
             how = con->shutdown_type;
-        rv = ssl_smart_shutdown(con->ssl, how);
+        rv = ssl_smart_shutdown(ssl, how);
         /* TODO: Translate OpenSSL Error codes */
-        SSL_free(con->ssl);
-        con->ssl = NULL;
+        SSL_free(ssl);
     }
     return rv;
 }
@@ -261,9 +285,10 @@
     apr_atomic_inc32(&ssl_closed);
 #endif
     if (con->ssl) {
-        rv = ssl_smart_shutdown(con->ssl, con->shutdown_type);
-        SSL_free(con->ssl);
+        SSL *ssl = con->ssl;
         con->ssl = NULL;
+        rv = ssl_smart_shutdown(ssl, con->shutdown_type);
+        SSL_free(ssl);
     }
     if (con->peer) {
         X509_free(con->peer);
@@ -276,7 +301,7 @@
 {
     tcn_socket_t *ss = J2P(sock, tcn_socket_t *);
     tcn_ssl_conn_t *con;
-    int s;
+    int s, i;
     apr_status_t rv;
     X509 *peer;
 
@@ -287,7 +312,10 @@
     con = (tcn_ssl_conn_t *)ss->opaque;
     while (!SSL_is_init_finished(con->ssl)) {
         if ((s = SSL_do_handshake(con->ssl)) <= 0) {
-            int i = SSL_get_error(con->ssl, s);
+            apr_status_t os = apr_get_netos_error();
+            if (!con->ssl)
+                return os == APR_SUCCESS ? APR_ENOTSOCK : os;
+            i = SSL_get_error(con->ssl, s);
             switch (i) {
                 case SSL_ERROR_NONE:
                     con->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD;
@@ -302,11 +330,10 @@
                 break;
                 case SSL_ERROR_SYSCALL:
                 case SSL_ERROR_SSL:
-                    s = apr_get_netos_error();
-                    if (!APR_STATUS_IS_EAGAIN(s) &&
-                        !APR_STATUS_IS_EINTR(s)) {
+                    if (!APR_STATUS_IS_EAGAIN(os) &&
+                        !APR_STATUS_IS_EINTR(os)) {
                         con->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
-                        return s;
+                        return os;
                     }
                 break;
                 default:
@@ -318,6 +345,9 @@
                 break;
             }
         }
+        if (!con->ssl)
+            return APR_ENOTSOCK;
+        
         /*
         * Check for failed client authentication
         */
@@ -344,13 +374,16 @@
 ssl_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
 {
     tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
-    int s, wr = (int)(*len);
+    int s, i, wr = (int)(*len);
     apr_status_t rv = APR_SUCCESS;
 
     for (;;) {
         if ((s = SSL_read(con->ssl, buf, wr)) <= 0) {
             apr_status_t os = apr_get_netos_error();
-            int i = SSL_get_error(con->ssl, s);
+            if (!con->ssl)
+                return os == APR_SUCCESS ? APR_ENOTSOCK : os;
+            
+            i = SSL_get_error(con->ssl, s);
             /* Special case if the "close notify" alert send by peer */
             if (s == 0 && (con->ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
                 *len = 0;
@@ -397,13 +430,16 @@
                 apr_size_t *len)
 {
     tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)sock;
-    int s, wr = (int)(*len);
+    int s, i, wr = (int)(*len);
     apr_status_t rv = APR_SUCCESS;
 
     for (;;) {
         if ((s = SSL_write(con->ssl, buf, wr)) <= 0) {
             apr_status_t os = apr_get_netos_error();
-            int i = SSL_get_error(con->ssl, s);
+            if (!con->ssl)
+                return os == APR_SUCCESS ? APR_ENOTSOCK : os;
+            
+            i = SSL_get_error(con->ssl, s);
             switch (i) {
                 case SSL_ERROR_ZERO_RETURN:
                     *len = 0;
@@ -490,8 +526,14 @@
     TCN_ASSERT(ctx != 0);
     TCN_ASSERT(sock != 0);
 
+    if (!s->sock)
+        return APR_ENOTSOCK;
+
     if ((rv = apr_os_sock_get(&oss, s->sock)) != APR_SUCCESS)
         return rv;
+    if (oss == APR_INVALID_SOCKET)
+        return APR_ENOTSOCK;        
+        
     if ((con = ssl_create(e, c, s->pool)) == NULL)
         return APR_EGENERAL;
     con->sock = s->sock;



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org