mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 05:32:28 +08:00
[libc++][hardening] Introduce a dylib function to log hardening errors. (#148266)
Unlike `verbose_abort`, this function merely logs the error but does not terminate execution. It is intended to make it possible to implement the `observe` semantic for Hardening.
This commit is contained in:
committed by
GitHub
parent
ee5b9369cd
commit
49d2b5f1cd
@@ -535,6 +535,7 @@ set(files
|
||||
__locale_dir/time.h
|
||||
__locale_dir/wbuffer_convert.h
|
||||
__locale_dir/wstring_convert.h
|
||||
__log_hardening_failure
|
||||
__math/abs.h
|
||||
__math/copysign.h
|
||||
__math/error_functions.h
|
||||
|
||||
@@ -304,6 +304,11 @@
|
||||
#define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT _LIBCPP_INTRODUCED_IN_LLVM_15
|
||||
#define _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_INTRODUCED_IN_LLVM_15_ATTRIBUTE
|
||||
|
||||
// This controls whether the library provides a function to log errors without terminating the program (used in
|
||||
// particular by the `observe` assertion semantic).
|
||||
#define _LIBCPP_AVAILABILITY_HAS_LOG_HARDENING_FAILURE _LIBCPP_INTRODUCED_IN_LLVM_21
|
||||
#define _LIBCPP_AVAILABILITY_LOG_HARDENING_FAILURE _LIBCPP_INTRODUCED_IN_LLVM_21_ATTRIBUTE
|
||||
|
||||
// This controls the availability of the C++17 std::pmr library,
|
||||
// which is implemented in large part in the built library.
|
||||
//
|
||||
|
||||
45
libcxx/include/__log_hardening_failure
Normal file
45
libcxx/include/__log_hardening_failure
Normal file
@@ -0,0 +1,45 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _LIBCPP___LOG_HARDENING_FAILURE
|
||||
#define _LIBCPP___LOG_HARDENING_FAILURE
|
||||
|
||||
#include <__config>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// This function should never be called directly from the code -- it should only be called through the
|
||||
// `_LIBCPP_LOG_HARDENING_FAILURE` macro.
|
||||
_LIBCPP_AVAILABILITY_LOG_HARDENING_FAILURE _LIBCPP_EXPORTED_FROM_ABI void
|
||||
__log_hardening_failure(const char* __message) _NOEXCEPT;
|
||||
|
||||
// _LIBCPP_LOG_HARDENING_FAILURE(message)
|
||||
//
|
||||
// This macro is used to log an error without terminating the program (as is the case for hardening failures if the
|
||||
// `observe` assertion semantic is used, for example).
|
||||
|
||||
#if !defined(_LIBCPP_LOG_HARDENING_FAILURE)
|
||||
|
||||
# if !_LIBCPP_AVAILABILITY_HAS_LOG_HARDENING_FAILURE
|
||||
// The decltype is there to suppress -Wunused warnings in this configuration.
|
||||
void __use(const char*);
|
||||
# define _LIBCPP_LOG_HARDENING_FAILURE(__message) (decltype(::std::__use(__message))())
|
||||
# else
|
||||
# define _LIBCPP_LOG_HARDENING_FAILURE(__message) ::std::__log_hardening_failure(__message)
|
||||
# endif
|
||||
|
||||
#endif // !defined(_LIBCPP_LOG_HARDENING_FAILURE)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___LOG_HARDENING_FAILURE
|
||||
@@ -2353,6 +2353,9 @@ module std [system] {
|
||||
header "__std_mbstate_t.h"
|
||||
export *
|
||||
}
|
||||
module log_hardening_failure {
|
||||
header "__log_hardening_failure"
|
||||
}
|
||||
module verbose_abort {
|
||||
header "__verbose_abort"
|
||||
}
|
||||
|
||||
@@ -36,6 +36,14 @@ Version 21.0
|
||||
-------------
|
||||
Symbol added: _ZNSt3__113__hash_memoryEPKvm
|
||||
|
||||
* [libc++][hardening] Introduce a dylib function to log hardening errors.
|
||||
|
||||
This patch added a function to log hardening failures to the dylib.
|
||||
|
||||
All platforms
|
||||
-------------
|
||||
Symbol added: _ZNSt3__123__log_hardening_failureEPKc
|
||||
|
||||
------------
|
||||
Version 20.0
|
||||
------------
|
||||
|
||||
@@ -1581,6 +1581,7 @@
|
||||
{'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__123__log_hardening_failureEPKc', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
|
||||
@@ -1217,6 +1217,7 @@
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk123__log_hardening_failureEPKc', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
|
||||
@@ -569,6 +569,7 @@
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__log_hardening_failureEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
|
||||
@@ -569,6 +569,7 @@
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__123__log_hardening_failureEPKc', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
{'import_export': 'EXP', 'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'storage_mapping_class': 'DS', 'type': 'FUNC'}
|
||||
|
||||
@@ -1580,6 +1580,7 @@
|
||||
{'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__123__log_hardening_failureEPKc', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointEPKcS1_RdNS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__127__from_chars_floating_pointEPKcS1_RfNS_12chars_formatE', 'type': 'FUNC'}
|
||||
|
||||
@@ -1217,6 +1217,7 @@
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk123__log_hardening_failureEPKc', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt6__ndk127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
|
||||
@@ -1231,6 +1231,7 @@
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__log_hardening_failureEPKc', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
|
||||
@@ -1229,6 +1229,7 @@
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__log_hardening_failureEPKc', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
|
||||
@@ -1200,6 +1200,7 @@
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__123__log_hardening_failureEPKc', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIdEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__127__from_chars_floating_pointIfEENS_19__from_chars_resultIT_EEPKcS5_NS_12chars_formatE', 'type': 'FUNC'}
|
||||
|
||||
@@ -31,6 +31,7 @@ set(LIBCXX_SOURCES
|
||||
include/to_chars_floating_point.h
|
||||
include/from_chars_floating_point.h
|
||||
memory.cpp
|
||||
log_hardening_failure.cpp
|
||||
memory_resource.cpp
|
||||
new_handler.cpp
|
||||
new_helpers.cpp
|
||||
|
||||
50
libcxx/src/log_hardening_failure.cpp
Normal file
50
libcxx/src/log_hardening_failure.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <__config>
|
||||
#include <__log_hardening_failure>
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef __BIONIC__
|
||||
# include <syslog.h>
|
||||
extern "C" void android_set_abort_message(const char* msg);
|
||||
#endif // __BIONIC__
|
||||
|
||||
#if defined(__APPLE__) && __has_include(<os/reason_private.h>)
|
||||
# include <TargetConditionals.h>
|
||||
# include <os/reason_private.h>
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
void __log_hardening_failure(const char* message) noexcept {
|
||||
// Always log the message to `stderr` in case the platform-specific system calls fail.
|
||||
fputs(message, stderr);
|
||||
|
||||
// On Apple platforms, use the `os_fault_with_payload` OS function that simulates a crash.
|
||||
#if defined(__APPLE__) && __has_include(<os/reason_private.h>) && !TARGET_OS_SIMULATOR
|
||||
os_fault_with_payload(
|
||||
/*reason_namespace=*/OS_REASON_SECURITY,
|
||||
/*reason_code=*/0,
|
||||
/*payload=*/nullptr,
|
||||
/*payload_size=*/0,
|
||||
/*reason_string=*/message,
|
||||
/*reason_flags=*/0);
|
||||
|
||||
#elif defined(__BIONIC__)
|
||||
// Show error in tombstone.
|
||||
android_set_abort_message(message);
|
||||
|
||||
// Show error in logcat.
|
||||
openlog("libc++", 0, 0);
|
||||
syslog(LOG_CRIT, "%s", message);
|
||||
closelog();
|
||||
#endif
|
||||
}
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
26
libcxx/test/libcxx/assertions/log_hardening_failure.pass.cpp
Normal file
26
libcxx/test/libcxx/assertions/log_hardening_failure.pass.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Basic smoke test for `__log_hardening_failure`.
|
||||
// XFAIL: availability-log_hardening_failure-missing
|
||||
|
||||
// UNSUPPORTED: FROZEN-CXX03-HEADERS-FIXME
|
||||
|
||||
#include <__log_hardening_failure>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
ASSERT_NOEXCEPT(std::__log_hardening_failure(""));
|
||||
|
||||
int main(int, char**) {
|
||||
std::__log_hardening_failure("Some message");
|
||||
// It's difficult to properly test platform-specific logging behavior of the function; just make sure it exists and
|
||||
// can be called at runtime.
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -926,4 +926,12 @@ DEFAULT_FEATURES += [
|
||||
cfg.available_features,
|
||||
),
|
||||
),
|
||||
# Tests that require __log_hardening_failure support in the built library
|
||||
Feature(
|
||||
name="availability-log_hardening_failure-missing",
|
||||
when=lambda cfg: BooleanExpression.evaluate(
|
||||
"!libcpp-has-no-availability-markup && (stdlib=apple-libc++ && !_target-has-llvm-21)",
|
||||
cfg.available_features,
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user