diff options
author | Gustavo Sverzut Barbieri <barbieri@profusion.mobi> | 2016-12-09 10:01:57 -0200 |
---|---|---|
committer | Gustavo Sverzut Barbieri <barbieri@profusion.mobi> | 2016-12-09 13:47:03 -0200 |
commit | cfc21c16fb0151bafea41f68a9f4a95248018408 (patch) | |
tree | 3cf383c5e4a727daeb2c169c4a564da8de435b7d | |
parent | c97111bf3cfee74449b5789f47c878d484eea226 (diff) | |
download | efl-cfc21c16fb0151bafea41f68a9f4a95248018408.tar.gz |
efl_net_ssl: do not access torn down sockets.
OpenSSL crashes if given a NULL pointer, then be safe and remember if
we did the tear down -- print error so bugs can be identified more
easily.
-rw-r--r-- | src/lib/ecore_con/efl_net_socket_ssl.c | 15 | ||||
-rw-r--r-- | src/lib/ecore_con/efl_net_ssl_conn-openssl.c | 22 |
2 files changed, 33 insertions, 4 deletions
diff --git a/src/lib/ecore_con/efl_net_socket_ssl.c b/src/lib/ecore_con/efl_net_socket_ssl.c index eb27888496..492fe7b335 100644 --- a/src/lib/ecore_con/efl_net_socket_ssl.c +++ b/src/lib/ecore_con/efl_net_socket_ssl.c @@ -114,6 +114,7 @@ typedef struct _Efl_Net_Socket_Ssl_Data Efl_Net_Ssl_Verify_Mode verify_mode; Eina_Bool hostname_verify; Eina_Bool did_handshake; + Eina_Bool torndown; Eina_Bool can_read; Eina_Bool eos; Eina_Bool can_write; @@ -131,6 +132,8 @@ efl_net_socket_ssl_handshake_try(Eo *o, Efl_Net_Socket_Ssl_Data *pd) { Eina_Error err; + if (pd->torndown) return; + DBG("SSL=%p handshake...", o); err = efl_net_ssl_conn_handshake(&pd->ssl_conn, &pd->did_handshake); @@ -209,6 +212,7 @@ efl_net_socket_ssl_sock_del(void *data, const Efl_Event *event EINA_UNUSED) Eo *o = data; Efl_Net_Socket_Ssl_Data *pd = efl_data_scope_get(o, MY_CLASS); pd->sock = NULL; + pd->torndown = EINA_TRUE; efl_net_ssl_conn_teardown(&pd->ssl_conn); } @@ -226,6 +230,7 @@ efl_net_socket_ssl_sock_connected(void *data, const Efl_Event *event EINA_UNUSED Efl_Net_Socket_Ssl_Data *pd = efl_data_scope_get(o, MY_CLASS); Eina_Error err; + if (pd->torndown) return; efl_ref(o); /* we're emitting callbacks then continuing the workflow */ @@ -325,6 +330,7 @@ _efl_net_socket_ssl_verify_mode_set(Eo *o EINA_UNUSED, Efl_Net_Socket_Ssl_Data * { pd->verify_mode = verify_mode; if (!efl_finalized_get(o)) return; + EINA_SAFETY_ON_TRUE_RETURN(pd->torndown); efl_net_ssl_conn_verify_mode_set(&pd->ssl_conn, pd->verify_mode); } @@ -340,6 +346,7 @@ _efl_net_socket_ssl_hostname_verify_set(Eo *o EINA_UNUSED, Efl_Net_Socket_Ssl_Da { pd->hostname_verify = hostname_verify; if (!efl_finalized_get(o)) return; + EINA_SAFETY_ON_TRUE_RETURN(pd->torndown); efl_net_ssl_conn_hostname_verify_set(&pd->ssl_conn, pd->hostname_verify); } @@ -357,6 +364,10 @@ _efl_net_socket_ssl_hostname_override_set(Eo *o EINA_UNUSED, Efl_Net_Socket_Ssl_ const char *hostname; eina_stringshare_replace(&pd->hostname_override, hostname_override); + + if (!efl_finalized_get(o)) return; + EINA_SAFETY_ON_TRUE_RETURN(pd->torndown); + hostname = pd->hostname_override; if (!hostname) { @@ -425,6 +436,7 @@ _efl_net_socket_ssl_efl_object_destructor(Eo *o, Efl_Net_Socket_Ssl_Data *pd) efl_destructor(efl_super(o, MY_CLASS)); + pd->torndown = EINA_TRUE; efl_net_ssl_conn_teardown(&pd->ssl_conn); if (pd->sock) { @@ -454,6 +466,7 @@ _efl_net_socket_ssl_efl_io_closer_close(Eo *o, Efl_Net_Socket_Ssl_Data *pd) efl_io_reader_can_read_set(o, EINA_FALSE); efl_io_reader_eos_set(o, EINA_TRUE); + pd->torndown = EINA_TRUE; efl_net_ssl_conn_teardown(&pd->ssl_conn); if (efl_io_closer_closed_get(pd->sock)) return 0; @@ -472,6 +485,7 @@ _efl_net_socket_ssl_efl_io_reader_read(Eo *o, Efl_Net_Socket_Ssl_Data *pd, Eina_ Eina_Error err; EINA_SAFETY_ON_NULL_RETURN_VAL(rw_slice, EINVAL); + EINA_SAFETY_ON_TRUE_RETURN_VAL(pd->torndown, EBADF); if (!pd->did_handshake) { @@ -529,6 +543,7 @@ _efl_net_socket_ssl_efl_io_writer_write(Eo *o, Efl_Net_Socket_Ssl_Data *pd, Eina Eina_Error err; EINA_SAFETY_ON_NULL_RETURN_VAL(ro_slice, EINVAL); + EINA_SAFETY_ON_TRUE_RETURN_VAL(pd->torndown, EBADF); if (!pd->did_handshake) { diff --git a/src/lib/ecore_con/efl_net_ssl_conn-openssl.c b/src/lib/ecore_con/efl_net_ssl_conn-openssl.c index 050664d729..3ecabea3e7 100644 --- a/src/lib/ecore_con/efl_net_ssl_conn-openssl.c +++ b/src/lib/ecore_con/efl_net_ssl_conn-openssl.c @@ -373,7 +373,11 @@ efl_net_ssl_conn_teardown(Efl_Net_Ssl_Conn *conn) static Eina_Error efl_net_ssl_conn_write(Efl_Net_Ssl_Conn *conn, Eina_Slice *slice) { - int r = SSL_write(conn->ssl, slice->mem, slice->len); + int r; + + EINA_SAFETY_ON_NULL_RETURN_VAL(conn->ssl, EINVAL); + + r = SSL_write(conn->ssl, slice->mem, slice->len); if (r < 0) { int ssl_err = SSL_get_error(conn->ssl, r); @@ -391,7 +395,11 @@ efl_net_ssl_conn_write(Efl_Net_Ssl_Conn *conn, Eina_Slice *slice) static Eina_Error efl_net_ssl_conn_read(Efl_Net_Ssl_Conn *conn, Eina_Rw_Slice *slice) { - int r = SSL_read(conn->ssl, slice->mem, slice->len); + int r; + + EINA_SAFETY_ON_NULL_RETURN_VAL(conn->ssl, EINVAL); + + r = SSL_read(conn->ssl, slice->mem, slice->len); if (r < 0) { int ssl_err = SSL_get_error(conn->ssl, r); @@ -454,6 +462,8 @@ _efl_net_ssl_conn_hostname_verify(Efl_Net_Ssl_Conn *conn) int family = AF_INET; int r; + EINA_SAFETY_ON_NULL_RETURN_VAL(conn->ssl, EINVAL); + if ((!conn->hostname) || (conn->hostname[0] == '\0')) { ERR("ssl_conn=%p no hostname, cannot verify", conn); @@ -496,14 +506,16 @@ _efl_net_ssl_conn_hostname_verify(Efl_Net_Ssl_Conn *conn) static Eina_Error efl_net_ssl_conn_handshake(Efl_Net_Ssl_Conn *conn, Eina_Bool *done) { - int r = SSL_do_handshake(conn->ssl); long err_ssl; const char *err_file; const char *err_data; - int err_line, err_flags; + int r, err_line, err_flags; *done = EINA_FALSE; + EINA_SAFETY_ON_NULL_RETURN_VAL(conn->ssl, EINVAL); + + r = SSL_do_handshake(conn->ssl); if (r == 1) { _efl_net_ssl_conn_session_debug(conn); @@ -561,6 +573,8 @@ efl_net_ssl_conn_verify_mode_set(Efl_Net_Ssl_Conn *conn, Efl_Net_Ssl_Verify_Mode { int ssl_mode; + EINA_SAFETY_ON_NULL_RETURN_VAL(conn->ssl, EINVAL); + switch (verify_mode) { case EFL_NET_SSL_VERIFY_MODE_NONE: |