Skip to content

Commit

Permalink
Fix spurious "success" on SSL system errors:
Browse files Browse the repository at this point in the history
Fix boostorg/beast#807
Fix boostorg/beast#1373

This resolves an issue where an ssl::stream read operation
returns a successful error code but zero bytes transferred,
violating its contract.

* Treat SSL_ERROR_ZERO_RETURN as EOF

* Use the ssl category for sys_error

* On error, if sys_error is 0 (success),
  return ssl::errors::read_sys_error instead.
  • Loading branch information
vinniefalco committed Dec 25, 2018
1 parent a6008b6 commit 6bdd2a2
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 9 deletions.
26 changes: 17 additions & 9 deletions include/boost/asio/ssl/detail/impl/engine.ipp
Expand Up @@ -237,17 +237,18 @@ engine::want engine::perform(int (engine::* op)(void*, std::size_t),
int sys_error = static_cast<int>(::ERR_get_error());
std::size_t pending_output_after = ::BIO_ctrl_pending(ext_bio_);

if (ssl_error == SSL_ERROR_SSL)
if (ssl_error == SSL_ERROR_SSL || ssl_error == SSL_ERROR_SYSCALL)
{
ec = boost::system::error_code(sys_error,
if(sys_error == 0)
{
// remap success to a code that indicates failure
ec = boost::asio::ssl::error::read_sys_error;
}
else
{
ec = boost::system::error_code(sys_error,
boost::asio::error::get_ssl_category());
return want_nothing;
}

if (ssl_error == SSL_ERROR_SYSCALL)
{
ec = boost::system::error_code(sys_error,
boost::asio::error::get_system_category());
}
return want_nothing;
}

Expand All @@ -274,8 +275,15 @@ engine::want engine::perform(int (engine::* op)(void*, std::size_t),
ec = boost::asio::error::eof;
return want_nothing;
}
else if (ssl_error == SSL_ERROR_ZERO_RETURN)
{
ec = boost::asio::error::eof;
return want_nothing;
}
else
{
BOOST_ASIO_ASSERT(result > 0);
//if(result <= 0) std::cerr << "result <= 0, ssl_error = " << ssl_error << std::endl;
ec = boost::system::error_code();
return want_nothing;
}
Expand Down
4 changes: 4 additions & 0 deletions include/boost/asio/ssl/error.hpp
Expand Up @@ -46,11 +46,15 @@ enum stream_errors
#if defined(GENERATING_DOCUMENTATION)
/// The underlying stream closed before the ssl stream gracefully shut down.
stream_truncated

#elif (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_IS_BORINGSSL)
stream_truncated = ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ)
#else
stream_truncated = 1
#endif

/// An unspecified system error occurred during an ssl read operation.
,read_sys_error = stream_truncated + 1
};

extern BOOST_ASIO_DECL
Expand Down
1 change: 1 addition & 0 deletions include/boost/asio/ssl/impl/error.ipp
Expand Up @@ -77,6 +77,7 @@ public:
switch (value)
{
case stream_truncated: return "stream truncated";
case read_sys_error: return "sys_error=0 on read";
default: return "asio.ssl.stream error";
}
}
Expand Down

0 comments on commit 6bdd2a2

Please sign in to comment.