mirror of
https://github.com/DynamoRIO/dynamorio.git
synced 2026-10-12 02:02:04 +00:00
i#8034: Make native_exec_is_back_from_native check more robust to avoid BOLT induced crashes (#8035)
native_exec_is_back_from_native() bounds its range check with the hard-coded MAX_NATIVE_RETSTACK * BACK_FROM_NATIVE_RETSTUB_SIZE (40 bytes) rather than the actual extent of the retstub region. Bound the check by back_from_native_retstubs_end - back_from_native_retstubs instead. On x86 this is equivalent, the asm emits MAX_NATIVE_RETSTACK stubs and native_exec_init() already asserts end == start + MAX_NATIVE_RETSTACK * BACK_FROM_NATIVE_RETSTUB_SIZE. Fixes #8034
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
/* **********************************************************
|
||||
* Copyright (c) 2012-2025 Google, Inc. All rights reserved.
|
||||
* Copyright (c) 2026 Meta Platforms, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
@@ -487,3 +488,27 @@ put_back_native_retaddrs(dcontext_t *dcontext)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef STANDALONE_UNIT_TEST
|
||||
|
||||
void
|
||||
unit_test_native_exec(void)
|
||||
{
|
||||
const ptr_uint_t retstubs_sym_start = (ptr_uint_t)back_from_native_retstubs;
|
||||
const ptr_uint_t retstubs_sym_end = (ptr_uint_t)back_from_native_retstubs_end;
|
||||
|
||||
EXPECT(retstubs_sym_end >= retstubs_sym_start, true);
|
||||
EXPECT(native_exec_is_back_from_native((app_pc)retstubs_sym_start),
|
||||
(retstubs_sym_end > retstubs_sym_start));
|
||||
|
||||
/* If non-zero size label. */
|
||||
if (retstubs_sym_end > retstubs_sym_start) {
|
||||
EXPECT(native_exec_is_back_from_native((app_pc)(retstubs_sym_end - 1)), true);
|
||||
}
|
||||
|
||||
/* Boundary conditions: strictly outside the stub. */
|
||||
EXPECT(native_exec_is_back_from_native((app_pc)(retstubs_sym_start - 1)), false);
|
||||
EXPECT(native_exec_is_back_from_native((app_pc)(retstubs_sym_end)), false);
|
||||
}
|
||||
|
||||
#endif /* STANDALONE_UNIT_TEST */
|
||||
|
||||
+8
-1
@@ -1,5 +1,6 @@
|
||||
/* **********************************************************
|
||||
* Copyright (c) 2012-2025 Google, Inc. All rights reserved.
|
||||
* Copyright (c) 2026 Meta Platforms, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
@@ -120,8 +121,14 @@ put_back_native_retaddrs(dcontext_t *dcontext);
|
||||
static inline bool
|
||||
native_exec_is_back_from_native(app_pc pc)
|
||||
{
|
||||
/* Non-x86 platforms can have zero-sized retstub if native_exec is not implemented.
|
||||
* retstub_region_size is a link-time constant on all platforms, making the check a
|
||||
* single compare.
|
||||
*/
|
||||
ptr_uint_t retstub_region_size =
|
||||
(ptr_uint_t)back_from_native_retstubs_end - (ptr_uint_t)back_from_native_retstubs;
|
||||
ptr_uint_t diff = (ptr_uint_t)pc - (ptr_uint_t)back_from_native_retstubs;
|
||||
return (diff < MAX_NATIVE_RETSTACK * BACK_FROM_NATIVE_RETSTUB_SIZE);
|
||||
return (diff < retstub_region_size);
|
||||
}
|
||||
|
||||
#ifdef UNIX
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* **********************************************************
|
||||
* Copyright (c) 2012-2013 Google, Inc. All rights reserved.
|
||||
* Copyright (c) 2026 Meta Platforms, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
@@ -38,6 +39,8 @@
|
||||
|
||||
void
|
||||
unit_test_io(void);
|
||||
void
|
||||
unit_test_native_exec(void);
|
||||
#ifdef UNIX
|
||||
void
|
||||
unit_test_string(void);
|
||||
@@ -75,6 +78,7 @@ main(int argc, char **argv, char **envp)
|
||||
* might be worth looking into gtest, which already does this.
|
||||
*/
|
||||
unit_test_io();
|
||||
unit_test_native_exec();
|
||||
#ifdef UNIX
|
||||
unit_test_string();
|
||||
unit_test_os();
|
||||
|
||||
Reference in New Issue
Block a user