[openssl-commits] [openssl] master update
davidben at google.com
davidben at google.com
Wed May 23 21:35:31 UTC 2018
The branch master has been updated
via 2de108dfa343c3e06eb98beb122cd06306bb12fd (commit)
from e363534cfe0ae01503dde6963e0631ec5f7fef3f (commit)
- Log -----------------------------------------------------------------
commit 2de108dfa343c3e06eb98beb122cd06306bb12fd
Author: David Benjamin <davidben at google.com>
Date: Sun May 20 17:24:30 2018 -0400
Save and restore the Windows error around TlsGetValue.
TlsGetValue clears the last error even on success, so that callers may
distinguish it successfully returning NULL or failing. This error-mangling
behavior interferes with the caller's use of GetLastError. In particular
SSL_get_error queries the error queue to determine whether the caller should
look at the OS's errors. To avoid destroying state, save and restore the
Windows error.
Fixes #6299.
Reviewed-by: Rich Salz <rsalz at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6316)
-----------------------------------------------------------------------
Summary of changes:
crypto/threads_win.c | 21 +++++++++++-
test/build.info | 6 +++-
test/errtest.c | 39 ++++++++++++++++++++++
.../{04-test_bio_callback.t => 04-test_err.t} | 2 +-
4 files changed, 65 insertions(+), 3 deletions(-)
create mode 100644 test/errtest.c
copy test/recipes/{04-test_bio_callback.t => 04-test_err.t} (86%)
diff --git a/crypto/threads_win.c b/crypto/threads_win.c
index 1e5cf82..7fdbc1f 100644
--- a/crypto/threads_win.c
+++ b/crypto/threads_win.c
@@ -101,7 +101,26 @@ int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
{
- return TlsGetValue(*key);
+ DWORD last_error;
+ void *ret;
+
+ /*
+ * TlsGetValue clears the last error even on success, so that callers may
+ * distinguish it successfully returning NULL or failing. It is documented
+ * to never fail if the argument is a valid index from TlsAlloc, so we do
+ * not need to handle this.
+ *
+ * However, this error-mangling behavior interferes with the caller's use of
+ * GetLastError. In particular SSL_get_error queries the error queue to
+ * determine whether the caller should look at the OS's errors. To avoid
+ * destroying state, save and restore the Windows error.
+ *
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ms686812(v=vs.85).aspx
+ */
+ last_error = GetLastError();
+ ret = TlsGetValue(*key);
+ SetLastError(last_error);
+ return ret;
}
int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
diff --git a/test/build.info b/test/build.info
index c3a0904..000153d 100644
--- a/test/build.info
+++ b/test/build.info
@@ -51,7 +51,7 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
recordlentest drbgtest drbg_cavs_test sslbuffertest \
time_offset_test pemtest ssl_cert_table_internal_test ciphername_test \
servername_test ocspapitest rsa_mp_test fatalerrtest tls13ccstest \
- sysdefaulttest
+ sysdefaulttest errtest
SOURCE[versions]=versions.c
INCLUDE[versions]=../include
@@ -535,6 +535,10 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
SOURCE[sysdefaulttest]=sysdefaulttest.c
INCLUDE[sysdefaulttest]=../include
DEPEND[sysdefaulttest]=../libcrypto ../libssl libtestutil.a
+
+ SOURCE[errtest]=errtest.c
+ INCLUDE[errtest]=../include
+ DEPEND[errtest]=../libcrypto libtestutil.a
ENDIF
{-
diff --git a/test/errtest.c b/test/errtest.c
new file mode 100644
index 0000000..e464d08
--- /dev/null
+++ b/test/errtest.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/opensslconf.h>
+#include <openssl/err.h>
+
+#include "testutil.h"
+
+#if defined(OPENSSL_SYS_WINDOWS)
+# include <windows.h>
+#else
+# include <errno.h>
+#endif
+
+/* Test that querying the error queue preserves the OS error. */
+static int preserves_system_error(void)
+{
+#if defined(OPENSSL_SYS_WINDOWS)
+ SetLastError(ERROR_INVALID_FUNCTION);
+ ERR_get_error();
+ return TEST_int_eq(GetLastError(), ERROR_INVALID_FUNCTION);
+#else
+ errno = EINVAL;
+ ERR_get_error();
+ return TEST_int_eq(errno, EINVAL);
+#endif
+}
+
+int setup_tests(void)
+{
+ ADD_TEST(preserves_system_error);
+ return 1;
+}
diff --git a/test/recipes/04-test_bio_callback.t b/test/recipes/04-test_err.t
similarity index 86%
copy from test/recipes/04-test_bio_callback.t
copy to test/recipes/04-test_err.t
index 1422cb6..dd7681a 100644
--- a/test/recipes/04-test_bio_callback.t
+++ b/test/recipes/04-test_err.t
@@ -9,4 +9,4 @@
use OpenSSL::Test::Simple;
-simple_test("test_bio_callback", "bio_callback_test");
+simple_test("test_err", "errtest");
More information about the openssl-commits
mailing list