Merge "Fix setfsgid()/setfsuid() for LP32."
diff --git a/libc/Android.bp b/libc/Android.bp
index fb4825d..67da126 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1444,6 +1444,7 @@
whole_static_libs: [
"gwp_asan",
+ "gwp_asan_crash_handler",
"libarm-optimized-routines-string",
"libasync_safe",
"libc_bionic_ndk",
@@ -1686,6 +1687,7 @@
cflags: ["-DLIBC_STATIC"],
whole_static_libs: [
"gwp_asan",
+ "gwp_asan_crash_handler",
"libc_init_static",
"libc_common_static",
"libc_unwind_static",
@@ -1695,6 +1697,7 @@
srcs: [ ":libc_sources_shared" ],
whole_static_libs: [
"gwp_asan",
+ "gwp_asan_crash_handler",
"libc_init_dynamic",
"libc_common_shared",
"libunwind-exported",
diff --git a/libc/bionic/gwp_asan_wrappers.cpp b/libc/bionic/gwp_asan_wrappers.cpp
index fc59c88..251633d 100644
--- a/libc/bionic/gwp_asan_wrappers.cpp
+++ b/libc/bionic/gwp_asan_wrappers.cpp
@@ -36,6 +36,7 @@
#include <string.h>
#include <sys/types.h>
+#include "gwp_asan/crash_handler.h"
#include "gwp_asan/guarded_pool_allocator.h"
#include "gwp_asan/options.h"
#include "gwp_asan_wrappers.h"
@@ -189,6 +190,7 @@
}
bool GwpAsanInitialized = false;
+bool GwpAsanRecoverable = false;
// The probability (1 / SampleRate) that an allocation gets chosen to be put
// into the special GWP-ASan pool.
@@ -222,8 +224,32 @@
static const char* kMaxAllocsTargetedSyspropPrefix = "libc.debug.gwp_asan.max_allocs.";
static const char* kMaxAllocsEnvVar = "GWP_ASAN_MAX_ALLOCS";
+static const char* kRecoverableSystemSysprop = "libc.debug.gwp_asan.recoverable.system_default";
+static const char* kRecoverableAppSysprop = "libc.debug.gwp_asan.recoverable.app_default";
+static const char* kRecoverableTargetedSyspropPrefix = "libc.debug.gwp_asan.recoverable.";
+static const char* kRecoverableEnvVar = "GWP_ASAN_RECOVERABLE";
+
static const char kPersistPrefix[] = "persist.";
+bool NeedsGwpAsanRecovery(void* fault_ptr) {
+ fault_ptr = untag_address(fault_ptr);
+ return GwpAsanInitialized && GwpAsanRecoverable &&
+ __gwp_asan_error_is_mine(GuardedAlloc.getAllocatorState(),
+ reinterpret_cast<uintptr_t>(fault_ptr));
+}
+
+void GwpAsanPreCrashHandler(void* fault_ptr) {
+ fault_ptr = untag_address(fault_ptr);
+ if (!NeedsGwpAsanRecovery(fault_ptr)) return;
+ GuardedAlloc.preCrashReport(fault_ptr);
+}
+
+void GwpAsanPostCrashHandler(void* fault_ptr) {
+ fault_ptr = untag_address(fault_ptr);
+ if (!NeedsGwpAsanRecovery(fault_ptr)) return;
+ GuardedAlloc.postCrashReportRecoverableOnly(fault_ptr);
+}
+
void SetDefaultGwpAsanOptions(Options* options, unsigned* process_sample_rate,
const android_mallopt_gwp_asan_options_t& mallopt_options) {
options->Enabled = true;
@@ -236,14 +262,17 @@
*process_sample_rate = 1;
if (mallopt_options.desire == Action::TURN_ON_WITH_SAMPLING) {
*process_sample_rate = kDefaultProcessSampling;
+ } else if (mallopt_options.desire == Action::TURN_ON_FOR_APP_SAMPLED_NON_CRASHING) {
+ *process_sample_rate = kDefaultProcessSampling;
+ options->Recoverable = true;
+ GwpAsanRecoverable = true;
}
}
-bool GetGwpAsanOption(unsigned long long* result,
- const android_mallopt_gwp_asan_options_t& mallopt_options,
- const char* system_sysprop, const char* app_sysprop,
- const char* targeted_sysprop_prefix, const char* env_var,
- const char* descriptive_name) {
+bool GetGwpAsanOptionImpl(char* value_out,
+ const android_mallopt_gwp_asan_options_t& mallopt_options,
+ const char* system_sysprop, const char* app_sysprop,
+ const char* targeted_sysprop_prefix, const char* env_var) {
const char* basename = "";
if (mallopt_options.program_name) basename = __gnu_basename(mallopt_options.program_name);
@@ -278,17 +307,25 @@
sysprop_names[3] = persist_default_sysprop;
}
- char settings_buf[PROP_VALUE_MAX];
- if (!get_config_from_env_or_sysprops(env_var, sysprop_names, arraysize(sysprop_names),
- settings_buf, PROP_VALUE_MAX)) {
+ return get_config_from_env_or_sysprops(env_var, sysprop_names, arraysize(sysprop_names),
+ value_out, PROP_VALUE_MAX);
+}
+
+bool GetGwpAsanIntegerOption(unsigned long long* result,
+ const android_mallopt_gwp_asan_options_t& mallopt_options,
+ const char* system_sysprop, const char* app_sysprop,
+ const char* targeted_sysprop_prefix, const char* env_var,
+ const char* descriptive_name) {
+ char buffer[PROP_VALUE_MAX];
+ if (!GetGwpAsanOptionImpl(buffer, mallopt_options, system_sysprop, app_sysprop,
+ targeted_sysprop_prefix, env_var)) {
return false;
}
-
char* end;
- unsigned long long value = strtoull(settings_buf, &end, 10);
+ unsigned long long value = strtoull(buffer, &end, 10);
if (value == ULLONG_MAX || *end != '\0') {
warning_log("Invalid GWP-ASan %s: \"%s\". Using default value instead.", descriptive_name,
- settings_buf);
+ buffer);
return false;
}
@@ -296,6 +333,33 @@
return true;
}
+bool GetGwpAsanBoolOption(bool* result, const android_mallopt_gwp_asan_options_t& mallopt_options,
+ const char* system_sysprop, const char* app_sysprop,
+ const char* targeted_sysprop_prefix, const char* env_var,
+ const char* descriptive_name) {
+ char buffer[PROP_VALUE_MAX] = {};
+ if (!GetGwpAsanOptionImpl(buffer, mallopt_options, system_sysprop, app_sysprop,
+ targeted_sysprop_prefix, env_var)) {
+ return false;
+ }
+
+ if (strncasecmp(buffer, "1", PROP_VALUE_MAX) == 0 ||
+ strncasecmp(buffer, "true", PROP_VALUE_MAX) == 0) {
+ *result = true;
+ return true;
+ } else if (strncasecmp(buffer, "0", PROP_VALUE_MAX) == 0 ||
+ strncasecmp(buffer, "false", PROP_VALUE_MAX) == 0) {
+ *result = false;
+ return true;
+ }
+
+ warning_log(
+ "Invalid GWP-ASan %s: \"%s\". Using default value \"%s\" instead. Valid values are \"true\", "
+ "\"1\", \"false\", or \"0\".",
+ descriptive_name, buffer, *result ? "true" : "false");
+ return false;
+}
+
// Initialize the GWP-ASan options structure in *options, taking into account whether someone has
// asked for specific GWP-ASan settings. The order of priority is:
// 1. Environment variables.
@@ -310,22 +374,23 @@
bool had_overrides = false;
unsigned long long buf;
- if (GetGwpAsanOption(&buf, mallopt_options, kSampleRateSystemSysprop, kSampleRateAppSysprop,
- kSampleRateTargetedSyspropPrefix, kSampleRateEnvVar, "sample rate")) {
+ if (GetGwpAsanIntegerOption(&buf, mallopt_options, kSampleRateSystemSysprop,
+ kSampleRateAppSysprop, kSampleRateTargetedSyspropPrefix,
+ kSampleRateEnvVar, "sample rate")) {
options->SampleRate = buf;
had_overrides = true;
}
- if (GetGwpAsanOption(&buf, mallopt_options, kProcessSamplingSystemSysprop,
- kProcessSamplingAppSysprop, kProcessSamplingTargetedSyspropPrefix,
- kProcessSamplingEnvVar, "process sampling rate")) {
+ if (GetGwpAsanIntegerOption(&buf, mallopt_options, kProcessSamplingSystemSysprop,
+ kProcessSamplingAppSysprop, kProcessSamplingTargetedSyspropPrefix,
+ kProcessSamplingEnvVar, "process sampling rate")) {
*process_sample_rate = buf;
had_overrides = true;
}
- if (GetGwpAsanOption(&buf, mallopt_options, kMaxAllocsSystemSysprop, kMaxAllocsAppSysprop,
- kMaxAllocsTargetedSyspropPrefix, kMaxAllocsEnvVar,
- "maximum simultaneous allocations")) {
+ if (GetGwpAsanIntegerOption(&buf, mallopt_options, kMaxAllocsSystemSysprop, kMaxAllocsAppSysprop,
+ kMaxAllocsTargetedSyspropPrefix, kMaxAllocsEnvVar,
+ "maximum simultaneous allocations")) {
options->MaxSimultaneousAllocations = buf;
had_overrides = true;
} else if (had_overrides) {
@@ -337,6 +402,16 @@
options->MaxSimultaneousAllocations =
/* default */ kDefaultMaxAllocs / frequency_multiplier;
}
+
+ bool recoverable = false;
+ if (GetGwpAsanBoolOption(&recoverable, mallopt_options, kRecoverableSystemSysprop,
+ kRecoverableAppSysprop, kRecoverableTargetedSyspropPrefix,
+ kRecoverableEnvVar, "recoverable")) {
+ options->Recoverable = recoverable;
+ GwpAsanRecoverable = recoverable;
+ had_overrides = true;
+ }
+
return had_overrides;
}
@@ -396,6 +471,9 @@
__libc_shared_globals()->gwp_asan_state = GuardedAlloc.getAllocatorState();
__libc_shared_globals()->gwp_asan_metadata = GuardedAlloc.getMetadataRegion();
+ __libc_shared_globals()->debuggerd_needs_gwp_asan_recovery = NeedsGwpAsanRecovery;
+ __libc_shared_globals()->debuggerd_gwp_asan_pre_crash_report = GwpAsanPreCrashHandler;
+ __libc_shared_globals()->debuggerd_gwp_asan_post_crash_report = GwpAsanPostCrashHandler;
return true;
}
diff --git a/libc/include/sys/quota.h b/libc/include/sys/quota.h
index f8faee7..79c653d 100644
--- a/libc/include/sys/quota.h
+++ b/libc/include/sys/quota.h
@@ -51,6 +51,6 @@
*
* Available since API level 26.
*/
-int quotactl(int __cmd, const char* __special, int __id, char* __addr) __INTRODUCED_IN(26);
+int quotactl(int __cmd, const char* _Nullable __special, int __id, char* __BIONIC_COMPLICATED_NULLNESS __addr) __INTRODUCED_IN(26);
__END_DECLS
diff --git a/libc/include/sys/sysinfo.h b/libc/include/sys/sysinfo.h
index 4ecf986..cae5c49 100644
--- a/libc/include/sys/sysinfo.h
+++ b/libc/include/sys/sysinfo.h
@@ -43,7 +43,7 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int sysinfo(struct sysinfo* __info);
+int sysinfo(struct sysinfo* _Nonnull __info);
/**
* [get_nprocs_conf(3)](http://man7.org/linux/man-pages/man3/get_nprocs_conf.3.html) returns
diff --git a/libc/platform/bionic/malloc.h b/libc/platform/bionic/malloc.h
index ecc8743..3c290fc 100644
--- a/libc/platform/bionic/malloc.h
+++ b/libc/platform/bionic/malloc.h
@@ -121,15 +121,28 @@
// apply to system apps. They use the "libc.debug.gwp_asan.*.system_default"
// sysprops.
enum Action {
- // The app has opted-in to GWP-ASan, and should always have it enabled. This
- // should only be used by apps.
+ // Enable GWP-ASan. This is used by apps that have `gwpAsanMode=always` in
+ // the manifest.
TURN_ON_FOR_APP,
- // System processes apps have GWP-ASan enabled by default, but use the
- // process sampling method.
+ // Enable GWP-ASan, but only a small percentage of the time. This is used by
+ // system processes and system apps, and we use a lottery to determine which
+ // processes have GWP-ASan enabled. This allows us to mitigate system-wide
+ // memory overhead concerns, as each GWP-ASan enabled process uses ~70KiB of
+ // extra memory.
TURN_ON_WITH_SAMPLING,
- // Non-system apps don't have GWP-ASan by default.
+ // Don't enable GWP-ASan, unless overwritten by a system property or
+ // environment variable. This is used by apps that have `gwpAsanMode=never`
+ // in the manifest. Prior to Android 14, this also was used by non-system
+ // apps that didn't specify a `gwpAsanMode` in their manifest.
DONT_TURN_ON_UNLESS_OVERRIDDEN,
- // Note: GWP-ASan cannot be disabled once it's been enabled.
+ // Enable GWP-ASan, but only a small percentage of the time, and enable it
+ // in the non-crashing ("recoverable") mode. In Android 14, this is used by
+ // apps that don't specify `gwpAsanMode` (or use `gwpAsanMode=default`) in
+ // their manifest. GWP-ASan will detect heap memory safety bugs in this
+ // mode, and bug reports will be created by debuggerd, however the process
+ // will recover and continue to function as if the memory safety bug wasn't
+ // detected.
+ TURN_ON_FOR_APP_SAMPLED_NON_CRASHING,
};
Action desire = DONT_TURN_ON_UNLESS_OVERRIDDEN;
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index 520e50f..c375cc4 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -107,6 +107,9 @@
const gwp_asan::AllocatorState* gwp_asan_state = nullptr;
const gwp_asan::AllocationMetadata* gwp_asan_metadata = nullptr;
+ bool (*debuggerd_needs_gwp_asan_recovery)(void* fault_addr) = nullptr;
+ void (*debuggerd_gwp_asan_pre_crash_report)(void* fault_addr) = nullptr;
+ void (*debuggerd_gwp_asan_post_crash_report)(void* fault_addr) = nullptr;
const char* scudo_stack_depot = nullptr;
const char* scudo_region_info = nullptr;
diff --git a/libdl/libdl.cpp b/libdl/libdl.cpp
index a56a5ab..20f08d9 100644
--- a/libdl/libdl.cpp
+++ b/libdl/libdl.cpp
@@ -14,10 +14,11 @@
* limitations under the License.
*/
+#include <android/dlext.h>
#include <dlfcn.h>
#include <link.h>
+#include <signal.h>
#include <stdlib.h>
-#include <android/dlext.h>
// These functions are exported by the loader
// TODO(dimitry): replace these with reference to libc.so
@@ -72,6 +73,9 @@
__attribute__((__weak__, visibility("default")))
int __loader_android_get_application_target_sdk_version();
+__attribute__((__weak__, visibility("default"))) bool __loader_android_handle_signal(
+ int signal_number, siginfo_t* info, void* context);
+
// Proxy calls to bionic loader
__attribute__((__weak__))
void android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) {
@@ -138,4 +142,14 @@
return __loader_android_get_application_target_sdk_version();
}
+// Returns true if this function handled the signal, false if the caller should handle the signal
+// itself. This function returns true if the sigchain handler should immediately return, which
+// happens when the signal came from GWP-ASan, and we've dumped a debuggerd report and patched up
+// the GWP-ASan allocator to recover from the fault, and regular execution of the program can
+// continue.
+__attribute__((__weak__)) bool android_handle_signal(int signal_number, siginfo_t* info,
+ void* context) {
+ return __loader_android_handle_signal(signal_number, info, context);
+}
+
} // extern "C"
diff --git a/libdl/libdl.map.txt b/libdl/libdl.map.txt
index 473bdf2..043ec53 100644
--- a/libdl/libdl.map.txt
+++ b/libdl/libdl.map.txt
@@ -45,4 +45,5 @@
global:
android_get_LD_LIBRARY_PATH;
__cfi_init;
+ android_handle_signal;
} LIBC_OMR1;
diff --git a/libm/Android.bp b/libm/Android.bp
index b6c7b6a..f06bd4f 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -285,11 +285,10 @@
arm: {
srcs: [
"arm/fenv.c",
- "arm/floor.S",
- "arm/sqrt.S",
],
exclude_srcs: [
"upstream-freebsd/lib/msun/src/s_floor.c",
+ "upstream-freebsd/lib/msun/src/s_floorf.c",
],
instruction_set: "arm",
pack_relocations: false,
diff --git a/libm/NOTICE b/libm/NOTICE
index bce49ad..61dd125 100644
--- a/libm/NOTICE
+++ b/libm/NOTICE
@@ -1148,37 +1148,6 @@
-------------------------------------------------------------------
-Copyright (c) 2013-2014, NVIDIA Corporation. All rights reserved.
-Johnny Qiu <joqiu@nvidia.com>
-Shu Zhang <chazhang@nvidia.com>
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
- * Neither the name of The Linux Foundation nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--------------------------------------------------------------------
-
Copyright (c) 2014, Intel Corporation
All rights reserved.
diff --git a/libm/arm/floor.S b/libm/arm/floor.S
deleted file mode 100644
index 3af8f76..0000000
--- a/libm/arm/floor.S
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2013-2014, NVIDIA Corporation. All rights reserved.
- * Johnny Qiu <joqiu@nvidia.com>
- * Shu Zhang <chazhang@nvidia.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <float.h>
-#include <private/bionic_asm.h>
-
-ENTRY(floor) /* x in r0, r1 */
-
- and r3, r1, #0x80000000 /* sign(x) */
- bic r1, r1, #0x80000000 /* x = abs(x) */
-
- /* extract exp of x */
- lsr r2, r1, #20
- sub r2, r2, #0x3fc
- subs r2, r2, #0x3 /* r2 <- exp */
-
- /* |x| < 1.0? */
- blt .Lx_lt_one
-
- /* x < 0? */
- cmp r3, #0
- bne .Lclr_frac_neg
-
- /* |x| <= 2^20? */
- cmp r2, #20
- ble .Lclr_frac_r1
-
- /* |x| < 2^52? */
- cmp r2, #52
- blt .Lclr_frac_r0
-
- /* return x */
- bx lr
-
-.Lclr_frac_r1:
- rsb r2, r2, #20
- lsr r1, r1, r2
- lsl r1, r1, r2
- mov r0, #0
- bx lr
-
-.Lclr_frac_r0:
- rsb r2, r2, #52
- lsr r0, r0, r2
- lsl r0, r0, r2
- bx lr
-
-.Lclr_frac_neg:
- /* |x| <= 2^20? */
- cmp r2, #20
- ble .Lclr_frac_r1_neg
-
- /* |x| < 2^52? */
- cmp r2, #52
- blt .Lclr_frac_r0_neg
-
- /* return x */
- orr r1, r1, #0x80000000
- bx lr
-
-.Lclr_frac_r1_neg:
- rsb r2, r2, #20
- mov r3, #1
- lsl r3, r3, r2
- sub r3, r3, #1
- and r3, r1, r3
- orr r3, r3, r0
- lsr r1, r1, r2
- lsl r1, r1, r2
- mov r0, #0
- b .Lreturn_x_neg
-
-.Lclr_frac_r0_neg:
- rsb r2, r2, #52
- mov r3, #1
- lsl r3, r3, r2
- sub r3, r3, #1
- and r3, r0, r3
- lsr r0, r0, r2
- lsl r0, r0, r2
- b .Lreturn_x_neg
-
-.Lx_lt_one:
- /* x == +-0? */
- cmp r0, #0
- cmpeq r1, #0
- orreq r1, r1, r3
- bxeq lr
-
- /* (x > 0) ? 0 : -1 */
- mov r1, #0x00100000
- mov r0, #0
- cmp r3, #0
- movne r1, #0xc0000000
- sub r1, r1, #0x00100000
- bx lr
-
-.Lreturn_x_neg:
- cmp r3, #0
- orr r1, r1, #0x80000000
- bxeq lr
-
- vmov d16, r0, r1
- vmov.f64 d18, #1.0
- vsub.f64 d16, d16, d18
- vmov r0, r1, d16
- bx lr
-
-END(floor)
-
-ALIAS_SYMBOL(floorl, floor);
diff --git a/libm/arm/sqrt.S b/libm/arm/sqrt.S
deleted file mode 100644
index f2981f4..0000000
--- a/libm/arm/sqrt.S
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2013-2014, NVIDIA Corporation. All rights reserved.
- * Johnny Qiu <joqiu@nvidia.com>
- * Shu Zhang <chazhang@nvidia.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <float.h>
-#include <private/bionic_asm.h>
-
-ENTRY(sqrt)
- vmov.f64 d0, r0, r1
- vsqrt.f64 d0, d0
- vmov.f64 r0, r1, d0
- bx lr
-END(sqrt)
-
-ENTRY(sqrtf)
- vmov.f32 s0, r0
- vsqrt.f32 s0, s0
- vmov.f32 r0, s0
- bx lr
-END(sqrtf)
-
-ALIAS_SYMBOL(sqrtl, sqrt);
diff --git a/libm/builtins.cpp b/libm/builtins.cpp
index 256436e..99758ff 100644
--- a/libm/builtins.cpp
+++ b/libm/builtins.cpp
@@ -32,9 +32,12 @@
float copysignf(float x, float y) { return __builtin_copysignf(x, y); }
#endif
-#if defined(__aarch64__)
+#if defined(__arm__) || defined(__aarch64__)
float floorf(float x) { return __builtin_floorf(x); }
double floor(double x) { return __builtin_floor(x); }
+#if defined(__ILP32__)
+__weak_reference(floor, floorl);
+#endif
#endif
#if defined(__aarch64__) || defined(__riscv)
@@ -66,9 +69,12 @@
double round(double x) { return __builtin_round(x); }
#endif
-#if defined(__aarch64__) || defined(__riscv)
+#if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
float sqrtf(float x) { return __builtin_sqrtf(x); }
double sqrt(double x) { return __builtin_sqrt(x); }
+#if defined(__ILP32__)
+__weak_reference(sqrt, sqrtl);
+#endif
#endif
#if defined(__aarch64__)
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index af05027..a3f5246 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -28,8 +28,9 @@
#include "linker.h"
#include "linker_cfi.h"
-#include "linker_globals.h"
+#include "linker_debuggerd.h"
#include "linker_dlwarning.h"
+#include "linker_globals.h"
#include <link.h>
#include <pthread.h>
@@ -92,6 +93,8 @@
#if defined(__arm__)
_Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) __LINKER_PUBLIC__;
#endif
+bool __loader_android_handle_signal(int signal_number, siginfo_t* info,
+ void* context) __LINKER_PUBLIC__;
}
static pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
@@ -302,6 +305,10 @@
return __libc_shared_globals();
}
+bool __loader_android_handle_signal(int signal_number, siginfo_t* info, void* context) {
+ return debuggerd_handle_signal(signal_number, info, context);
+}
+
static uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8)));
static soinfo* __libdl_info = nullptr;
diff --git a/linker/ld_android.cpp b/linker/ld_android.cpp
index 0239c30..1c03106 100644
--- a/linker/ld_android.cpp
+++ b/linker/ld_android.cpp
@@ -44,6 +44,7 @@
__strong_alias(__loader_android_set_application_target_sdk_version, __internal_linker_error);
__strong_alias(__loader_android_update_LD_LIBRARY_PATH, __internal_linker_error);
__strong_alias(__loader_cfi_fail, __internal_linker_error);
+__strong_alias(__loader_android_handle_signal, __internal_linker_error);
__strong_alias(__loader_dl_iterate_phdr, __internal_linker_error);
__strong_alias(__loader_dladdr, __internal_linker_error);
__strong_alias(__loader_dlclose, __internal_linker_error);
diff --git a/linker/linker.arm.map b/linker/linker.arm.map
index be438ca..b805cd6 100644
--- a/linker/linker.arm.map
+++ b/linker/linker.arm.map
@@ -24,6 +24,7 @@
__loader_remove_thread_local_dtor;
__loader_shared_globals;
rtld_db_dlactivity;
+ __loader_android_handle_signal;
local:
*;
};
diff --git a/linker/linker.generic.map b/linker/linker.generic.map
index f3c01c0..4d7f236 100644
--- a/linker/linker.generic.map
+++ b/linker/linker.generic.map
@@ -23,6 +23,7 @@
__loader_remove_thread_local_dtor;
__loader_shared_globals;
rtld_db_dlactivity;
+ __loader_android_handle_signal;
local:
*;
};
diff --git a/linker/linker_debuggerd.h b/linker/linker_debuggerd.h
index d701879..95f99e7 100644
--- a/linker/linker_debuggerd.h
+++ b/linker/linker_debuggerd.h
@@ -28,4 +28,7 @@
#pragma once
+#include <signal.h>
+
void linker_debuggerd_init();
+extern "C" bool debuggerd_handle_signal(int signal_number, siginfo_t* info, void* context);
diff --git a/linker/linker_debuggerd_android.cpp b/linker/linker_debuggerd_android.cpp
index 3d64628..ab6fc30 100644
--- a/linker/linker_debuggerd_android.cpp
+++ b/linker/linker_debuggerd_android.cpp
@@ -46,6 +46,17 @@
.scudo_ring_buffer_size = __libc_shared_globals()->scudo_ring_buffer_size,
};
}
+
+static gwp_asan_callbacks_t get_gwp_asan_callbacks() {
+ return {
+ .debuggerd_needs_gwp_asan_recovery =
+ __libc_shared_globals()->debuggerd_needs_gwp_asan_recovery,
+ .debuggerd_gwp_asan_pre_crash_report =
+ __libc_shared_globals()->debuggerd_gwp_asan_pre_crash_report,
+ .debuggerd_gwp_asan_post_crash_report =
+ __libc_shared_globals()->debuggerd_gwp_asan_post_crash_report,
+ };
+}
#endif
void linker_debuggerd_init() {
@@ -53,9 +64,10 @@
// so don't pass in any process info from the bootstrap linker.
debuggerd_callbacks_t callbacks = {
#if defined(__ANDROID_APEX__)
- .get_process_info = get_process_info,
+ .get_process_info = get_process_info,
+ .get_gwp_asan_callbacks = get_gwp_asan_callbacks,
#endif
- .post_dump = notify_gdb_of_libraries,
+ .post_dump = notify_gdb_of_libraries,
};
debuggerd_init(&callbacks);
}
diff --git a/linker/linker_debuggerd_stub.cpp b/linker/linker_debuggerd_stub.cpp
index 631e6e4..c671dd9 100644
--- a/linker/linker_debuggerd_stub.cpp
+++ b/linker/linker_debuggerd_stub.cpp
@@ -28,5 +28,11 @@
#include "linker_debuggerd.h"
+#include <signal.h>
+
void linker_debuggerd_init() {
}
+extern "C" bool debuggerd_handle_signal(int /* signal_number */, siginfo_t* /* info */,
+ void* /* context */) {
+ return false;
+}