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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]