Update allocator alignment tests.

clang was configured to force 16 byte alignments on allocations > 8
for 64 bit. Unfortunately, we never updated our alignment test to
verify this behavior. So this finally adds these new restrictions.

In addition, when GWP-ASan is enabled, it will take over allocations
from the native allocator. In order to make sure that GWP-ASan also
obeys these alignment checks, add a test that forces GWP-ASan on and
runs the alignment check test.

Test: Ran unit tests on a flame using scudo (both 32 bit and 64 bit).
Test: Ran unit tests on a flame using jemalloc (both 32 bit and 64 bit).
Change-Id: I87a20b9c2f32b9d207f36437d291ed44247dcbd1
This commit is contained in:
Christopher Ferris 2021-09-21 10:32:40 -07:00
parent b47aa42a11
commit b3cac0fab4

View file

@ -872,7 +872,7 @@ static void __attribute__((optnone)) AndroidVerifyAlignment(size_t alloc_size, s
}
#endif
TEST(malloc, align_check) {
void AlignCheck() {
// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_445
// for a discussion of type alignment.
ASSERT_NO_FATAL_FAILURE(TestAllocateType<float>());
@ -896,22 +896,35 @@ TEST(malloc, align_check) {
#if defined(__ANDROID__)
// On Android, there is a lot of code that expects certain alignments:
// - Allocations of a size that rounds up to a multiple of 16 bytes
// must have at least 16 byte alignment.
// - Allocations of a size that rounds up to a multiple of 8 bytes and
// not 16 bytes, are only required to have at least 8 byte alignment.
// This is regardless of whether it is in a 32 bit or 64 bit environment.
// 1. Allocations of a size that rounds up to a multiple of 16 bytes
// must have at least 16 byte alignment.
// 2. Allocations of a size that rounds up to a multiple of 8 bytes and
// not 16 bytes, are only required to have at least 8 byte alignment.
// In addition, on Android clang has been configured for 64 bit such that:
// 3. Allocations <= 8 bytes must be aligned to at least 8 bytes.
// 4. Allocations > 8 bytes must be aligned to at least 16 bytes.
// For 32 bit environments, only the first two requirements must be met.
// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2293.htm for
// a discussion of this alignment mess. The code below is enforcing
// strong-alignment, since who knows what code depends on this behavior now.
// As mentioned before, for 64 bit this will enforce the higher
// requirement since clang expects this behavior on Android now.
for (size_t i = 1; i <= 128; i++) {
#if defined(__LP64__)
if (i <= 8) {
AndroidVerifyAlignment(i, 8);
} else {
AndroidVerifyAlignment(i, 16);
}
#else
size_t rounded = (i + 7) & ~7;
if ((rounded % 16) == 0) {
AndroidVerifyAlignment(i, 16);
} else {
AndroidVerifyAlignment(i, 8);
}
#endif
if (::testing::Test::HasFatalFailure()) {
return;
}
@ -919,6 +932,22 @@ TEST(malloc, align_check) {
#endif
}
TEST(malloc, align_check) {
AlignCheck();
}
// Force GWP-ASan on and verify all alignment checks still pass.
TEST(malloc, align_check_gwp_asan) {
#if defined(__BIONIC__)
bool force_init = true;
ASSERT_TRUE(android_mallopt(M_INITIALIZE_GWP_ASAN, &force_init, sizeof(force_init)));
AlignCheck();
#else
GTEST_SKIP() << "bionic-only test";
#endif
}
// Jemalloc doesn't pass this test right now, so leave it as disabled.
TEST(malloc, DISABLED_alloc_after_fork) {
// Both of these need to be a power of 2.