Skip to content

Commit eb69ccb

Browse files
Merge pull request #5856 from icing/errq-improvements
Improvements in OpenSSL Compat ERR Queue handling.
2 parents bdadbef + 02094eb commit eb69ccb

5 files changed

Lines changed: 876 additions & 391 deletions

File tree

configure.ac

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,12 +1629,23 @@ fi
16291629
AC_ARG_ENABLE([error-queue-per-thread],
16301630
[AS_HELP_STRING([--enable-error-queue-per-thread],[Enable one error queue per thread. Requires thread local storage. (default: disabled)])],
16311631
[ ENABLED_ERRORQUEUEPERTHREAD=$enableval ],
1632-
[ ENABLED_ERRORQUEUEPERTHREAD=no ]
1632+
[ ENABLED_ERRORQUEUEPERTHREAD=check ]
16331633
)
16341634

1635+
if test "$ENABLED_ERRORQUEUEPERTHREAD" = "check"
1636+
then
1637+
AS_IF([test "$thread_ls_on" = "no"],
1638+
[ENABLED_ERRORQUEUEPERTHREAD=no],
1639+
[ENABLED_ERRORQUEUEPERTHREAD=yes])
1640+
fi
1641+
16351642
if test "$ENABLED_ERRORQUEUEPERTHREAD" = "yes"
16361643
then
1637-
AM_CFLAGS="$AM_CFLAGS -DERROR_QUEUE_PER_THREAD"
1644+
if test "$thread_ls_on" != "yes"
1645+
then
1646+
AC_MSG_ERROR(error-queue-per-thread needs thread-local storage.)
1647+
fi
1648+
AM_CFLAGS="$AM_CFLAGS -DERROR_QUEUE_PER_THREAD"
16381649
fi
16391650

16401651
# High Strength Build
@@ -8831,6 +8842,7 @@ echo " * NXP SE050: $ENABLED_SE050"
88318842
echo " * Maxim Integrated MAXQ10XX: $ENABLED_MAXQ10XX"
88328843
echo " * PSA: $ENABLED_PSA"
88338844
echo " * System CA certs: $ENABLED_SYS_CA_CERTS"
8845+
echo " * ERR Queues per Thread: $ENABLED_ERRORQUEUEPERTHREAD"
88348846
echo ""
88358847
echo "---"
88368848

src/ssl.c

Lines changed: 32 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -17045,51 +17045,12 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
1704517045

1704617046
unsigned long wolfSSL_ERR_get_error(void)
1704717047
{
17048-
int ret;
17049-
1705017048
WOLFSSL_ENTER("wolfSSL_ERR_get_error");
17051-
1705217049
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
17053-
ret = wc_PullErrorNode(NULL, NULL, NULL);
17054-
if (ret < 0) {
17055-
if (ret == BAD_STATE_E) {
17056-
ret = 0; /* no errors in queue */
17057-
}
17058-
else {
17059-
WOLFSSL_MSG("Error with pulling error node!");
17060-
WOLFSSL_LEAVE("wolfSSL_ERR_get_error", ret);
17061-
ret = 0 - ret; /* return absolute value of error */
17062-
/* panic and try to clear out nodes */
17063-
wc_ClearErrorNodes();
17064-
}
17065-
}
17066-
else {
17067-
int idx = wc_GetCurrentIdx();
17068-
if (idx < 0) {
17069-
WOLFSSL_MSG("Error with getting current index!");
17070-
ret = BAD_STATE_E;
17071-
WOLFSSL_LEAVE("wolfSSL_ERR_get_error", ret);
17072-
17073-
/* panic and try to clear out nodes and reset queue state */
17074-
wc_ClearErrorNodes();
17075-
}
17076-
else if (idx > 0) {
17077-
idx -= 1;
17078-
wc_RemoveErrorNode(idx);
17079-
}
17080-
else {
17081-
/* if current idx is 0 then the queue only had one node */
17082-
wc_RemoveErrorNode(idx);
17083-
}
17084-
}
17085-
17086-
return ret;
17050+
return wc_GetErrorNodeErr();
1708717051
#else
17088-
17089-
(void)ret;
17090-
1709117052
return (unsigned long)(0 - NOT_COMPILED_IN);
17092-
#endif /* WOLFSSL_HAVE_ERROR_QUEUE */
17053+
#endif
1709317054
}
1709417055

1709517056
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
@@ -33220,63 +33181,42 @@ int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags)
3322033181
#endif /* WOLFSSL_ASYNC_CRYPT */
3322133182

3322233183
#ifdef OPENSSL_EXTRA
33184+
33185+
static int peek_ignore_err(int err)
33186+
{
33187+
switch(err) {
33188+
case -WANT_READ:
33189+
case -WANT_WRITE:
33190+
case -ZERO_RETURN:
33191+
case -WOLFSSL_ERROR_ZERO_RETURN:
33192+
case -SOCKET_PEER_CLOSED_E:
33193+
case -SOCKET_ERROR_E:
33194+
return 1;
33195+
default:
33196+
return 0;
33197+
}
33198+
}
33199+
3322333200
unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
3322433201
const char **data, int *flags)
3322533202
{
33226-
WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
33227-
33228-
(void)line;
33229-
(void)file;
33230-
33231-
/* No data or flags stored - error display only in Nginx. */
33232-
if (data != NULL) {
33233-
*data = "";
33234-
}
33235-
if (flags != NULL) {
33236-
*flags = 0;
33237-
}
33238-
33239-
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
33240-
{
33241-
int ret = 0;
33242-
int idx = wc_GetCurrentIdx();
33243-
33244-
while (1) {
33245-
ret = wc_PeekErrorNode(idx, file, NULL, line);
33246-
if (ret == BAD_MUTEX_E || ret == BAD_FUNC_ARG || ret == BAD_STATE_E) {
33247-
WOLFSSL_MSG("Issue peeking at error node in queue");
33248-
return 0;
33249-
}
33250-
/* OpenSSL uses positive error codes */
33251-
if (ret < 0) {
33252-
ret = -ret;
33253-
}
33203+
unsigned long err;
3325433204

33255-
if (ret == -ASN_NO_PEM_HEADER)
33256-
return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
33257-
#ifdef OPENSSL_ALL
33258-
/* PARSE_ERROR is returned if an HTTP request is detected. */
33259-
if (ret == -SSL_R_HTTP_REQUEST)
33260-
return (ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST;
33261-
#endif
33262-
#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
33263-
if (ret == ASN1_R_HEADER_TOO_LONG) {
33264-
return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
33265-
}
33266-
#endif
33267-
if (ret != -WANT_READ && ret != -WANT_WRITE &&
33268-
ret != -ZERO_RETURN && ret != -WOLFSSL_ERROR_ZERO_RETURN &&
33269-
ret != -SOCKET_PEER_CLOSED_E && ret != -SOCKET_ERROR_E)
33270-
break;
33271-
33272-
wc_RemoveErrorNode(idx);
33273-
}
33205+
WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
33206+
err = wc_PeekErrorNodeLineData(file, line, data, flags, peek_ignore_err);
3327433207

33275-
return (unsigned long)ret;
33276-
}
33277-
#else
33278-
return (unsigned long)(0 - NOT_COMPILED_IN);
33208+
if (err == -ASN_NO_PEM_HEADER)
33209+
return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
33210+
#ifdef OPENSSL_ALL
33211+
/* PARSE_ERROR is returned if an HTTP request is detected. */
33212+
else if (err == -SSL_R_HTTP_REQUEST)
33213+
return (ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST;
33214+
#endif
33215+
#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
33216+
else if (err == ASN1_R_HEADER_TOO_LONG)
33217+
return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
3327933218
#endif
33219+
return err;
3328033220
}
3328133221
#endif
3328233222

tests/api.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35237,6 +35237,13 @@ static void post_auth_version_cb(WOLFSSL* ssl)
3523735237
/* do handshake and then test version error */
3523835238
AssertIntEQ(wolfSSL_accept(ssl), WOLFSSL_SUCCESS);
3523935239
AssertStrEQ("TLSv1.2", wolfSSL_get_version(ssl));
35240+
}
35241+
35242+
static void post_auth_version_client_cb(WOLFSSL* ssl)
35243+
{
35244+
/* do handshake and then test version error */
35245+
AssertIntEQ(wolfSSL_connect(ssl), WOLFSSL_SUCCESS);
35246+
AssertStrEQ("TLSv1.2", wolfSSL_get_version(ssl));
3524035247
AssertIntEQ(wolfSSL_verify_client_post_handshake(ssl), WOLFSSL_FAILURE);
3524135248
#if defined(OPENSSL_ALL) && !defined(NO_ERROR_QUEUE)
3524235249
/* check was added to error queue */
@@ -35302,8 +35309,9 @@ static int test_wolfSSL_Tls13_postauth(void)
3530235309
XMEMSET(&client_cbf, 0, sizeof(callback_functions));
3530335310
server_cbf.method = wolfTLSv1_2_server_method;
3530435311
server_cbf.ssl_ready = set_post_auth_cb;
35305-
client_cbf.ssl_ready = set_post_auth_cb;
3530635312
server_cbf.on_result = post_auth_version_cb;
35313+
client_cbf.ssl_ready = set_post_auth_cb;
35314+
client_cbf.on_result = post_auth_version_client_cb;
3530735315
server_args.callbacks = &server_cbf;
3530835316
client_args.callbacks = &client_cbf;
3530935317

@@ -35319,6 +35327,7 @@ static int test_wolfSSL_Tls13_postauth(void)
3531935327
server_cbf.ssl_ready = set_post_auth_cb;
3532035328
client_cbf.ssl_ready = set_post_auth_cb;
3532135329
server_cbf.on_result = post_auth_cb;
35330+
client_cbf.on_result = NULL;
3532235331
server_args.callbacks = &server_cbf;
3532335332
client_args.callbacks = &client_cbf;
3532435333

@@ -38734,12 +38743,22 @@ static int test_wolfSSL_PKCS8_d2i(void)
3873438743
defined(OPENSSL_EXTRA) && defined(DEBUG_WOLFSSL)
3873538744
#define LOGGING_THREADS 5
3873638745
#define ERROR_COUNT 10
38746+
/* copied from logging.c since this is not exposed otherwise */
38747+
#ifndef ERROR_QUEUE_MAX
38748+
#ifdef ERROR_QUEUE_PER_THREAD
38749+
#define ERROR_QUEUE_MAX 16
38750+
#else
38751+
/* this breaks from compat of unlimited error queue size */
38752+
#define ERROR_QUEUE_MAX 100
38753+
#endif
38754+
#endif
38755+
3873738756
static volatile int loggingThreadsReady;
3873838757
static THREAD_RETURN WOLFSSL_THREAD test_logging(void* args)
3873938758
{
3874038759
const char* file;
3874138760
int line;
38742-
int err;
38761+
unsigned long err;
3874338762
int errorCount = 0;
3874438763
int i;
3874538764

@@ -38756,6 +38775,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_logging(void* args)
3875638775
AssertIntEQ(errorCount, ERROR_COUNT);
3875738776

3875838777
/* test max queue behavior, trying to add an arbitrary 3 errors over */
38778+
ERR_clear_error(); /* ERR_get_error_line() does not remove */
3875938779
errorCount = 0;
3876038780
for (i = 0; i < ERROR_QUEUE_MAX + 3; i++)
3876138781
ERR_put_error(ERR_LIB_PEM, SYS_F_ACCEPT, -990 - i, __FILE__, __LINE__);

0 commit comments

Comments
 (0)