diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp index dd3a96e64..4ebc796d2 100644 --- a/libc/bionic/fdsan.cpp +++ b/libc/bionic/fdsan.cpp @@ -106,30 +106,8 @@ FdEntry* FdTableImpl::at(size_t idx) { } void __libc_init_fdsan() { - constexpr auto default_level = ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE; - const prop_info* pi = __system_property_find(kFdsanPropertyName); - if (!pi) { - android_fdsan_set_error_level(default_level); - return; - } - __system_property_read_callback( - pi, - [](void*, const char*, const char* value, uint32_t) { - if (strcasecmp(value, "1") == 0 || strcasecmp(value, "fatal") == 0) { - android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL); - } else if (strcasecmp(value, "warn") == 0) { - android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS); - } else if (strcasecmp(value, "warn_once") == 0) { - android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE); - } else { - if (strlen(value) != 0 && strcasecmp(value, "0") != 0) { - async_safe_format_log(ANDROID_LOG_ERROR, "libc", - "debug.fdsan set to unknown value '%s', disabling", value); - } - android_fdsan_set_error_level(default_level); - } - }, - nullptr); + constexpr auto default_level = ANDROID_FDSAN_ERROR_LEVEL_FATAL; + android_fdsan_set_error_level_from_property(default_level); } static FdTable& GetFdTable() { @@ -355,6 +333,45 @@ android_fdsan_error_level android_fdsan_set_error_level(android_fdsan_error_leve return atomic_exchange(&GetFdTable().error_level, new_level); } +android_fdsan_error_level android_fdsan_set_error_level_from_property( + android_fdsan_error_level default_level) { + const prop_info* pi = __system_property_find(kFdsanPropertyName); + if (!pi) { + return android_fdsan_set_error_level(default_level); + } + + struct callback_data { + android_fdsan_error_level default_value; + android_fdsan_error_level result; + }; + + callback_data data; + data.default_value = default_level; + + __system_property_read_callback( + pi, + [](void* arg, const char*, const char* value, uint32_t) { + callback_data* data = static_cast(arg); + + if (strcasecmp(value, "1") == 0 || strcasecmp(value, "fatal") == 0) { + data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL); + } else if (strcasecmp(value, "warn") == 0) { + data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS); + } else if (strcasecmp(value, "warn_once") == 0) { + data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE); + } else { + if (strlen(value) != 0 && strcasecmp(value, "0") != 0) { + async_safe_format_log(ANDROID_LOG_ERROR, "libc", + "debug.fdsan set to unknown value '%s', disabling", value); + } + data->result = android_fdsan_set_error_level(data->default_value); + } + }, + &data); + + return data.result; +} + int close(int fd) { int rc = android_fdsan_close_with_tag(fd, 0); if (rc == -1 && errno == EINTR) { diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h index 1169ed046..83b9318ba 100644 --- a/libc/include/android/fdsan.h +++ b/libc/include/android/fdsan.h @@ -197,4 +197,8 @@ enum android_fdsan_error_level android_fdsan_get_error_level() __INTRODUCED_IN(2 */ enum android_fdsan_error_level android_fdsan_set_error_level(enum android_fdsan_error_level new_level) __INTRODUCED_IN(29) __attribute__((__weak__)); +/* + * Set the error level to the global setting if available, or a default value. + */ +enum android_fdsan_error_level android_fdsan_set_error_level_from_property(enum android_fdsan_error_level default_level) __INTRODUCED_IN(30) __attribute__((__weak__)); __END_DECLS diff --git a/linker/linker_sdk_versions.cpp b/linker/linker_sdk_versions.cpp index b06f3e63f..29c0f4af2 100644 --- a/linker/linker_sdk_versions.cpp +++ b/linker/linker_sdk_versions.cpp @@ -26,10 +26,13 @@ * SUCH DAMAGE. */ -#include "linker.h" -#include #include +#include +#include + +#include "linker.h" + static std::atomic g_target_sdk_version(__ANDROID_API__); void set_application_target_sdk_version(int target) { @@ -38,6 +41,10 @@ void set_application_target_sdk_version(int target) { target = __ANDROID_API__; } g_target_sdk_version = target; + + if (target < 30) { + android_fdsan_set_error_level_from_property(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE); + } } int get_application_target_sdk_version() {