[openssl-commits] [openssl] OpenSSL_1_1_0-stable update

davidben at google.com davidben at google.com
Thu May 24 19:50:07 UTC 2018


The branch OpenSSL_1_1_0-stable has been updated
       via  1ae891c6b15e28b280845858326fb50ea5b61ac7 (commit)
      from  926b21117df939241f1cd63f2f9e3ab87819f0ed (commit)


- Log -----------------------------------------------------------------
commit 1ae891c6b15e28b280845858326fb50ea5b61ac7
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>
    
    (cherry picked from commit 2de108dfa343c3e06eb98beb122cd06306bb12fd)
    
    (Merged from https://github.com/openssl/openssl/pull/6349)

-----------------------------------------------------------------------

Summary of changes:
 crypto/threads_win.c                             | 21 ++++++++++++-
 test/build.info                                  |  6 +++-
 test/errtest.c                                   | 40 ++++++++++++++++++++++++
 test/recipes/{03-test_exdata.t => 04-test_err.t} |  4 +--
 4 files changed, 67 insertions(+), 4 deletions(-)
 create mode 100644 test/errtest.c
 copy test/recipes/{03-test_exdata.t => 04-test_err.t} (74%)

diff --git a/crypto/threads_win.c b/crypto/threads_win.c
index 4e0de90..c9da56b 100644
--- a/crypto/threads_win.c
+++ b/crypto/threads_win.c
@@ -98,7 +98,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 dcb3985..87961bc 100644
--- a/test/build.info
+++ b/test/build.info
@@ -18,7 +18,7 @@ IF[{- !$disabled{tests} -}]
           dtlsv1listentest ct_test threadstest afalgtest d2i_test \
           ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \
           bioprinttest sslapitest dtlstest sslcorrupttest bio_enc_test \
-          ocspapitest fatalerrtest x509_time_test
+          ocspapitest fatalerrtest x509_time_test errtest
 
   SOURCE[versions]=versions.c
   INCLUDE[versions]=../include
@@ -306,6 +306,10 @@ IF[{- !$disabled{tests} -}]
     SOURCE[shlibloadtest]=shlibloadtest.c
     INCLUDE[shlibloadtest]=../include
   ENDIF
+
+  SOURCE[errtest]=errtest.c testutil.c
+  INCLUDE[errtest]=../include
+  DEPEND[errtest]=../libcrypto
 ENDIF
 
 {-
diff --git a/test/errtest.c b/test/errtest.c
new file mode 100644
index 0000000..df4cddb
--- /dev/null
+++ b/test/errtest.c
@@ -0,0 +1,40 @@
+/*
+ * 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 GetLastError() == ERROR_INVALID_FUNCTION;
+#else
+    errno = EINVAL;
+    ERR_get_error();
+    return errno == EINVAL;
+#endif
+}
+
+int main(int argc, char **argv)
+{
+    ADD_TEST(preserves_system_error);
+
+    return run_tests(argv[0]);
+}
diff --git a/test/recipes/03-test_exdata.t b/test/recipes/04-test_err.t
similarity index 74%
copy from test/recipes/03-test_exdata.t
copy to test/recipes/04-test_err.t
index da66f95..dd7681a 100644
--- a/test/recipes/03-test_exdata.t
+++ b/test/recipes/04-test_err.t
@@ -1,5 +1,5 @@
 #! /usr/bin/env perl
-# Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+# 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
@@ -9,4 +9,4 @@
 
 use OpenSSL::Test::Simple;
 
-simple_test("test_exdata", "exdatatest");
+simple_test("test_err", "errtest");


More information about the openssl-commits mailing list