From 69771b6784e7172f9f1ece47f55ef6dc90d3d2c5 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Tue, 17 Aug 2010 19:04:34 +0200 Subject: Safer usage of session variable to prevent segmentation faults on closure. Should solve issue #106. --- src/gnutls_hooks.c | 50 +++++++++++++++++++++++++++++++++++++++++++------- src/gnutls_io.c | 27 ++++++++++++++++++++------- 2 files changed, 63 insertions(+), 14 deletions(-) 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; } -- cgit