From aec8d9056db3e340009d1f19fd070d161f6f080c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 28 Jan 2018 17:29:13 +0200 Subject: [PATCH 1/3] Test that assigning to boost::throws() crashes --- test/Jamfile.v2 | 1 + test/throws_assign_fail.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 test/throws_assign_fail.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index bf90d08..55183b8 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -125,6 +125,7 @@ else [ run single_instance_test.cpp single_instance_lib1 single_instance_lib2 : : : static : single_instance_lib_static ] [ run single_instance_test.cpp single_instance_lib1 single_instance_lib2 : : : shared : single_instance_lib_shared ] [ system-run before_main_test.cpp ] + [ run-fail throws_assign_fail.cpp ] ; # Quick (CI) test diff --git a/test/throws_assign_fail.cpp b/test/throws_assign_fail.cpp new file mode 100644 index 0000000..8453577 --- /dev/null +++ b/test/throws_assign_fail.cpp @@ -0,0 +1,28 @@ + +// Copyright 2018 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. + +#include + +using namespace boost::system; + +static void f( error_code & ec ) +{ + ec = error_code(); +} + +#if defined(_WIN32) +# include // SetErrorMode +#endif + +int main() +{ +#if defined(_WIN32) + + SetErrorMode( SetErrorMode( 0 ) | SEM_NOGPFAULTERRORBOX ); + +#endif + + // this should crash + f( boost::throws() ); +} From 0433e561b5e2802979348cc8ce18c41f07ca0470 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 29 Jan 2018 02:29:14 +0200 Subject: [PATCH 2/3] Change the invalid address of boost::throws() to 8 from 1, so that it's properly aligned --- include/boost/system/error_code.hpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index 712d73e..f31155d 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -578,10 +578,14 @@ namespace boost inline system::error_code* throws() { // See github.com/boostorg/system/pull/12 by visigoth for why the return - // is poisoned with (1) rather than (0). A test, test_throws_usage(), has - // been added to error_code_test.cpp, and as visigoth mentioned it fails - // on clang for release builds with a return of 0 but works fine with (1). - return reinterpret_cast(1); + // is poisoned with nonzero rather than (0). A test, test_throws_usage(), + // has been added to error_code_test.cpp, and as visigoth mentioned it + // fails on clang for release builds with a return of 0 but works fine + // with (1). + // Since the undefined behavior sanitizer (-fsanitize=undefined) does not + // allow a reference to be formed to the unaligned address of (1), we use + // (8) instead. + return reinterpret_cast(8); } } From 6ea02e2668c16218c7881f36908dafdbabd3c8a7 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 29 Jan 2018 02:36:50 +0200 Subject: [PATCH 3/3] Reenable test_throws_usage() under UBSAN --- test/error_code_test.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/test/error_code_test.cpp b/test/error_code_test.cpp index 1f96c59..7965541 100644 --- a/test/error_code_test.cpp +++ b/test/error_code_test.cpp @@ -22,7 +22,6 @@ #include #include #include -#include // Although using directives are not the best programming practice, testing // with a boost::system using directive increases use scenario coverage. @@ -247,17 +246,8 @@ int main( int, char ** ) BOOST_TEST( econd.message() != "" ); BOOST_TEST( econd.message().substr( 0, 13) != "Unknown error" ); -#if !defined(UBSAN) - - // the current implementation of boost::throws() relies on undefined behavior test_throws_usage(); -#else - - BOOST_PRAGMA_MESSAGE("Skipping test_throws_usage() due to UBSAN"); - -#endif - #ifdef BOOST_WINDOWS_API std::cout << "Windows tests...\n"; // these tests probe the Windows errc decoder