Problem: possible use-after-free

Solution: check for failure and do not access any members afterwards
This commit is contained in:
Simon Giesecke 2019-03-22 07:19:06 -04:00
parent f083e60d8c
commit e17232f725
2 changed files with 20 additions and 7 deletions

View File

@ -297,13 +297,20 @@ void zmq::stream_engine_t::terminate ()
} }
void zmq::stream_engine_t::in_event () void zmq::stream_engine_t::in_event ()
{
// ignore errors
const bool res = in_event_internal ();
LIBZMQ_UNUSED (res);
}
bool zmq::stream_engine_t::in_event_internal ()
{ {
zmq_assert (!_io_error); zmq_assert (!_io_error);
// If still handshaking, receive and process the greeting message. // If still handshaking, receive and process the greeting message.
if (unlikely (_handshaking)) if (unlikely (_handshaking))
if (!handshake ()) if (!handshake ())
return; return false;
zmq_assert (_decoder); zmq_assert (_decoder);
@ -311,7 +318,7 @@ void zmq::stream_engine_t::in_event ()
if (_input_stopped) { if (_input_stopped) {
rm_fd (_handle); rm_fd (_handle);
_io_error = true; _io_error = true;
return; return true; // TODO or return false in this case too?
} }
// If there's no data to process in the buffer... // If there's no data to process in the buffer...
@ -329,12 +336,14 @@ void zmq::stream_engine_t::in_event ()
// connection closed by peer // connection closed by peer
errno = EPIPE; errno = EPIPE;
error (connection_error); error (connection_error);
return; return false;
} }
if (rc == -1) { if (rc == -1) {
if (errno != EAGAIN) if (errno != EAGAIN) {
error (connection_error); error (connection_error);
return; return false;
}
return true;
} }
// Adjust input size // Adjust input size
@ -363,13 +372,14 @@ void zmq::stream_engine_t::in_event ()
if (rc == -1) { if (rc == -1) {
if (errno != EAGAIN) { if (errno != EAGAIN) {
error (protocol_error); error (protocol_error);
return; return false;
} }
_input_stopped = true; _input_stopped = true;
reset_pollin (_handle); reset_pollin (_handle);
} }
_session->flush (); _session->flush ();
return true;
} }
void zmq::stream_engine_t::out_event () void zmq::stream_engine_t::out_event ()
@ -497,7 +507,8 @@ bool zmq::stream_engine_t::restart_input ()
_session->flush (); _session->flush ();
// Speculative read. // Speculative read.
in_event (); if (!in_event_internal ())
return false;
} }
return true; return true;

View File

@ -87,6 +87,8 @@ class stream_engine_t : public io_object_t, public i_engine
void timer_event (int id_); void timer_event (int id_);
private: private:
bool in_event_internal ();
// Unplug the engine from the session. // Unplug the engine from the session.
void unplug (); void unplug ();