summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-12-09 10:01:57 -0200
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-12-09 13:47:03 -0200
commitcfc21c16fb0151bafea41f68a9f4a95248018408 (patch)
tree3cf383c5e4a727daeb2c169c4a564da8de435b7d
parentc97111bf3cfee74449b5789f47c878d484eea226 (diff)
downloadefl-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.c15
-rw-r--r--src/lib/ecore_con/efl_net_ssl_conn-openssl.c22
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: