diff --git a/bssl-compat/source/err.cc b/bssl-compat/source/err.cc index ef9eac063d4..03cead339c7 100644 --- a/bssl-compat/source/err.cc +++ b/bssl-compat/source/err.cc @@ -2,6 +2,7 @@ #include #include #include +#include uint64_t o2b(uint64_t e) { @@ -71,6 +72,12 @@ extern "C" uint32_t ERR_get_error(void) { extern "C" const char *ERR_lib_error_string(uint32_t packed_error) { + // Handle system library errors like BoringSSL does + // OpenSSL 3.x returns NULL for system errors, but BoringSSL returns "system library" + if (ossl_ERR_SYSTEM_ERROR(packed_error)) { + return "system library"; + } + const char *ret = ossl.ossl_ERR_lib_error_string(b2o(packed_error)); return (ret ? ret : "unknown library"); } @@ -92,6 +99,18 @@ extern "C" uint32_t ERR_peek_last_error(void) { extern "C" const char *ERR_reason_error_string(uint32_t packed_error) { + // Handle system library errors like BoringSSL does + // For system errors, return strerror(errno) like BoringSSL does + if (ossl_ERR_SYSTEM_ERROR(packed_error)) { + uint32_t reason = ossl_ERR_GET_REASON(packed_error); + // Only use strerror for reasonable errno values (< 134) + // BoringSSL checks < 127, but Linux has valid errno values up to 133 + if (reason > 0 && reason < 134) { + return strerror(reason); + } + return "unknown error"; + } + /** * This is not an exhaustive list of errors; rather it is just the ones that * need to be translated for the Envoy tests to pass (yes some of the tests do diff --git a/bssl-compat/source/test/test_err.cc b/bssl-compat/source/test/test_err.cc index db19b257d29..39502bb71ef 100644 --- a/bssl-compat/source/test/test_err.cc +++ b/bssl-compat/source/test/test_err.cc @@ -2,6 +2,8 @@ #include #include #include +#include +#include TEST(ErrTest, test_ERR_func_error_string) { @@ -50,3 +52,65 @@ TEST(ErrTest, test_SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM) { EXPECT_STREQ("NO_COMMON_SIGNATURE_ALGORITHMS", ERR_reason_error_string(e)); EXPECT_STREQ("error:100000fd:SSL routines:OPENSSL_internal:NO_COMMON_SIGNATURE_ALGORITHMS", ERR_error_string_n(e, buf, sizeof(buf))); } + + +TEST(ErrTest, test_system_error_ECONNRESET) { + uint32_t err = 0x80000068; + + EXPECT_EQ(ERR_LIB_SYS, ERR_GET_LIB(err)); + EXPECT_EQ(104, ERR_GET_REASON(err)); + + const char *lib = ERR_lib_error_string(err); + ASSERT_NE(nullptr, lib); + EXPECT_STREQ("system library", lib); + + const char *reason = ERR_reason_error_string(err); + ASSERT_NE(nullptr, reason); + EXPECT_STREQ(strerror(104), reason); +} + + +TEST(ErrTest, test_system_error_EPIPE) { + uint32_t err = 0x80000020; + + EXPECT_EQ(ERR_LIB_SYS, ERR_GET_LIB(err)); + EXPECT_EQ(32, ERR_GET_REASON(err)); + + const char *lib = ERR_lib_error_string(err); + ASSERT_NE(nullptr, lib); + EXPECT_STREQ("system library", lib); + + const char *reason = ERR_reason_error_string(err); + ASSERT_NE(nullptr, reason); + EXPECT_STREQ(strerror(32), reason); +} + + +TEST(ErrTest, test_system_error_ETIMEDOUT) { + uint32_t err = 0x8000006E; + + EXPECT_EQ(ERR_LIB_SYS, ERR_GET_LIB(err)); + EXPECT_EQ(110, ERR_GET_REASON(err)); + + const char *lib = ERR_lib_error_string(err); + ASSERT_NE(nullptr, lib); + EXPECT_STREQ("system library", lib); + + const char *reason = ERR_reason_error_string(err); + ASSERT_NE(nullptr, reason); + EXPECT_STREQ(strerror(110), reason); +} + + +TEST(ErrTest, test_system_error_invalid_errno) { + uint32_t err = 0x80000FFF; + + EXPECT_EQ(ERR_LIB_SYS, ERR_GET_LIB(err)); + + const char *lib = ERR_lib_error_string(err); + ASSERT_NE(nullptr, lib); + EXPECT_STREQ("system library", lib); + + const char *reason = ERR_reason_error_string(err); + EXPECT_EQ(nullptr, reason); +}