Skip to content

Commit 553aa95

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:3b3f8c50b646 into origin/amd-gfx:6124eec093c1
Local branch origin/amd-gfx 6124eec Reapply "DAG: Use phi to create vregs instead of the constant input" (llvm#1274) Remote branch main 3b3f8c5 [asan] Re-exec without ASLR if needed on 32-bit Linux (llvm#131975)
2 parents 6124eec + 3b3f8c5 commit 553aa95

File tree

32 files changed

+1478
-2343
lines changed

32 files changed

+1478
-2343
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2936,9 +2936,8 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
29362936
bool IsThunk) {
29372937

29382938
if (llvm::Intrinsic::ID IID = F->getIntrinsicID()) {
2939-
// If this is an intrinsic function, set the function's attributes
2940-
// to the intrinsic's attributes.
2941-
F->setAttributes(llvm::Intrinsic::getAttributes(getLLVMContext(), IID));
2939+
// If this is an intrinsic function, the attributes will have been set
2940+
// when the function was created.
29422941
return;
29432942
}
29442943

compiler-rt/lib/asan/asan_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ void ReplaceSystemMalloc();
8282
uptr FindDynamicShadowStart();
8383
void AsanCheckDynamicRTPrereqs();
8484
void AsanCheckIncompatibleRT();
85+
void TryReExecWithoutASLR();
8586

8687
// Unpoisons platform-specific stacks.
8788
// Returns true if all stacks have been unpoisoned.

compiler-rt/lib/asan/asan_linux.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
# include <pthread.h>
2222
# include <stdio.h>
2323
# include <sys/mman.h>
24+
# include <sys/personality.h>
2425
# include <sys/resource.h>
2526
# include <sys/syscall.h>
2627
# include <sys/time.h>
@@ -107,6 +108,37 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) {
107108
ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size));
108109
}
109110

111+
void ReExecWithoutASLR() {
112+
// ASLR personality check.
113+
// Caution: 'personality' is sometimes forbidden by sandboxes, so only call
114+
// this function as a last resort (when the memory mapping is incompatible
115+
// and ASan would fail anyway).
116+
int old_personality = personality(0xffffffff);
117+
if (old_personality == -1) {
118+
VReport(1, "WARNING: unable to run personality check.\n");
119+
return;
120+
}
121+
122+
bool aslr_on = (old_personality & ADDR_NO_RANDOMIZE) == 0;
123+
124+
if (aslr_on) {
125+
// Disable ASLR if the memory layout was incompatible.
126+
// Alternatively, we could just keep re-execing until we get lucky
127+
// with a compatible randomized layout, but the risk is that if it's
128+
// not an ASLR-related issue, we will be stuck in an infinite loop of
129+
// re-execing (unless we change ReExec to pass a parameter of the
130+
// number of retries allowed.)
131+
VReport(1,
132+
"WARNING: AddressSanitizer: memory layout is incompatible, "
133+
"possibly due to high-entropy ASLR.\n"
134+
"Re-execing with fixed virtual address space.\n"
135+
"N.B. reducing ASLR entropy is preferable.\n");
136+
CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1);
137+
138+
ReExec();
139+
}
140+
}
141+
110142
# if SANITIZER_ANDROID
111143
// FIXME: should we do anything for Android?
112144
void AsanCheckDynamicRTPrereqs() {}

compiler-rt/lib/asan/asan_mac.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ uptr FindDynamicShadowStart() {
5555
GetMmapGranularity());
5656
}
5757

58+
// Not used.
59+
void TryReExecWithoutASLR() {}
60+
5861
// No-op. Mac does not support static linkage anyway.
5962
void AsanCheckDynamicRTPrereqs() {}
6063

compiler-rt/lib/asan/asan_shadow_setup.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ void InitializeShadowMemory() {
109109
ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
110110
ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
111111
} else {
112+
// The shadow mappings can shadow the entire user address space. However,
113+
// on 32-bit systems, the maximum ASLR entropy (currently up to 16-bits
114+
// == 256MB) is a significant chunk of the address space; reclaiming it by
115+
// disabling ASLR might allow chonky binaries to run.
116+
if (sizeof(uptr) == 32)
117+
TryReExecWithoutASLR();
118+
112119
Report(
113120
"Shadow memory range interleaves with an existing memory mapping. "
114121
"ASan cannot proceed correctly. ABORTING.\n");

compiler-rt/lib/asan/asan_win.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ uptr FindDynamicShadowStart() {
279279
GetMmapGranularity());
280280
}
281281

282+
// Not used
283+
void TryReExecWithoutASLR() {}
284+
282285
void AsanCheckDynamicRTPrereqs() {}
283286

284287
void AsanCheckIncompatibleRT() {}

libclc/cmake/modules/AddLibclc.cmake

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,13 @@ function(link_bc)
107107
set( LINK_INPUT_ARG "@${RSP_FILE}" )
108108
endif()
109109

110+
if( ARG_INTERNALIZE )
111+
set( link_flags --internalize --only-needed )
112+
endif()
113+
110114
add_custom_command(
111115
OUTPUT ${ARG_TARGET}.bc
112-
COMMAND ${llvm-link_exe} $<$<BOOL:${ARG_INTERNALIZE}>:--internalize> -o ${ARG_TARGET}.bc ${LINK_INPUT_ARG}
116+
COMMAND ${llvm-link_exe} ${link_flags} -o ${ARG_TARGET}.bc ${LINK_INPUT_ARG}
113117
DEPENDS ${llvm-link_target} ${ARG_DEPENDENCIES} ${ARG_INPUTS} ${RSP_FILE}
114118
)
115119

libcxx/test/std/containers/sequences/vector.bool/copy.pass.cpp

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111

1212
// vector(const vector& v);
1313

14-
#include <vector>
14+
#include <array>
1515
#include <cassert>
16+
#include <vector>
1617

17-
#include "test_macros.h"
18-
#include "test_allocator.h"
1918
#include "min_allocator.h"
19+
#include "test_allocator.h"
20+
#include "test_macros.h"
2021

2122
template <class C>
2223
TEST_CONSTEXPR_CXX20 void test(const C& x) {
@@ -25,39 +26,56 @@ TEST_CONSTEXPR_CXX20 void test(const C& x) {
2526
LIBCPP_ASSERT(c.__invariants());
2627
assert(c.size() == s);
2728
assert(c == x);
29+
#if TEST_STD_VER >= 11
30+
assert(c.get_allocator() ==
31+
std::allocator_traits<typename C::allocator_type>::select_on_container_copy_construction(x.get_allocator()));
32+
#endif
2833
}
2934

3035
TEST_CONSTEXPR_CXX20 bool tests() {
31-
{
32-
bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
33-
bool* an = a + sizeof(a) / sizeof(a[0]);
34-
test(std::vector<bool>(a, an));
35-
}
36-
{
37-
std::vector<bool, test_allocator<bool> > v(3, true, test_allocator<bool>(5));
38-
std::vector<bool, test_allocator<bool> > v2 = v;
39-
assert(v2 == v);
40-
assert(v2.get_allocator() == v.get_allocator());
36+
std::array<int, 5> a1 = {1, 0, 1, 0, 1};
37+
std::array<int, 18> a2 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
38+
std::array<int, 33> a3 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
39+
std::array<int, 65> a4 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
40+
std::array<int, 299> a5 = {};
41+
for (unsigned i = 0; i < a5.size(); i += 2)
42+
a5[i] = 1;
43+
44+
// Tests for vector<bool> copy constructor with word size up to 5 (i.e., bit size > 256 on a 64-bit system)
45+
{ // Test with default std::allocator
46+
test(std::vector<bool>(a1.begin(), a1.end()));
47+
test(std::vector<bool>(a2.begin(), a2.end()));
48+
test(std::vector<bool>(a3.begin(), a3.end()));
49+
test(std::vector<bool>(a4.begin(), a4.end()));
50+
test(std::vector<bool>(a5.begin(), a5.end()));
4151
}
42-
#if TEST_STD_VER >= 11
43-
{
44-
std::vector<bool, other_allocator<bool> > v(3, true, other_allocator<bool>(5));
45-
std::vector<bool, other_allocator<bool> > v2 = v;
46-
assert(v2 == v);
47-
assert(v2.get_allocator() == other_allocator<bool>(-2));
52+
{ // Test with test_allocator
53+
using A = test_allocator<bool>;
54+
using C = std::vector<bool, A>;
55+
test(C(a1.begin(), a1.end()));
56+
test(C(a2.begin(), a2.end()));
57+
test(C(a3.begin(), a3.end()));
58+
test(C(a4.begin(), a4.end()));
59+
test(C(a5.begin(), a5.end()));
4860
}
49-
{
50-
bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
51-
bool* an = a + sizeof(a) / sizeof(a[0]);
52-
test(std::vector<bool, min_allocator<bool>>(a, an));
61+
{ // Test with other_allocator
62+
using A = other_allocator<bool>;
63+
using C = std::vector<bool, A>;
64+
test(C(a1.begin(), a1.end()));
65+
test(C(a2.begin(), a2.end()));
66+
test(C(a3.begin(), a3.end()));
67+
test(C(a4.begin(), a4.end()));
68+
test(C(a5.begin(), a5.end()));
5369
}
54-
{
55-
std::vector<bool, min_allocator<bool> > v(3, true, min_allocator<bool>());
56-
std::vector<bool, min_allocator<bool> > v2 = v;
57-
assert(v2 == v);
58-
assert(v2.get_allocator() == v.get_allocator());
70+
{ // Test with min_allocator
71+
using A = min_allocator<bool>;
72+
using C = std::vector<bool, A>;
73+
test(C(a1.begin(), a1.end()));
74+
test(C(a2.begin(), a2.end()));
75+
test(C(a3.begin(), a3.end()));
76+
test(C(a4.begin(), a4.end()));
77+
test(C(a5.begin(), a5.end()));
5978
}
60-
#endif
6179

6280
return true;
6381
}

libcxx/test/std/containers/sequences/vector.bool/copy_alloc.pass.cpp

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@
77
//===----------------------------------------------------------------------===//
88

99
// <vector>
10+
// vector<bool>
1011

1112
// vector(const vector& v, const allocator_type& a);
1213

13-
#include <vector>
14+
#include <array>
1415
#include <cassert>
16+
#include <vector>
1517

16-
#include "test_macros.h"
17-
#include "test_allocator.h"
1818
#include "min_allocator.h"
19+
#include "test_allocator.h"
20+
#include "test_macros.h"
1921

2022
template <class C>
2123
TEST_CONSTEXPR_CXX20 void test(const C& x, const typename C::allocator_type& a) {
@@ -24,39 +26,53 @@ TEST_CONSTEXPR_CXX20 void test(const C& x, const typename C::allocator_type& a)
2426
LIBCPP_ASSERT(c.__invariants());
2527
assert(c.size() == s);
2628
assert(c == x);
29+
assert(c.get_allocator() == a);
2730
}
2831

2932
TEST_CONSTEXPR_CXX20 bool tests() {
30-
{
31-
bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
32-
bool* an = a + sizeof(a) / sizeof(a[0]);
33-
test(std::vector<bool>(a, an), std::allocator<bool>());
34-
}
35-
{
36-
std::vector<bool, test_allocator<bool> > l(3, true, test_allocator<bool>(5));
37-
std::vector<bool, test_allocator<bool> > l2(l, test_allocator<bool>(3));
38-
assert(l2 == l);
39-
assert(l2.get_allocator() == test_allocator<bool>(3));
33+
std::array<int, 5> a1 = {1, 0, 1, 0, 1};
34+
std::array<int, 18> a2 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
35+
std::array<int, 33> a3 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
36+
std::array<int, 65> a4 = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
37+
std::array<int, 299> a5 = {};
38+
for (unsigned i = 0; i < a5.size(); i += 2)
39+
a5[i] = 1;
40+
41+
// Tests for allocator-extended copy constructor with word size up to 5 (i.e., bit size > 256 on a 64-bit system)
42+
{ // Test with the default std::allocator
43+
test(std::vector<bool>(a1.begin(), a1.end()), std::allocator<bool>());
44+
test(std::vector<bool>(a2.begin(), a2.end()), std::allocator<bool>());
45+
test(std::vector<bool>(a3.begin(), a3.end()), std::allocator<bool>());
46+
test(std::vector<bool>(a4.begin(), a4.end()), std::allocator<bool>());
47+
test(std::vector<bool>(a5.begin(), a5.end()), std::allocator<bool>());
4048
}
41-
{
42-
std::vector<bool, other_allocator<bool> > l(3, true, other_allocator<bool>(5));
43-
std::vector<bool, other_allocator<bool> > l2(l, other_allocator<bool>(3));
44-
assert(l2 == l);
45-
assert(l2.get_allocator() == other_allocator<bool>(3));
49+
{ // Test with test_allocator
50+
using A = test_allocator<bool>;
51+
using C = std::vector<bool, A>;
52+
test(C(a1.begin(), a1.end(), A(5)), A(3));
53+
test(C(a2.begin(), a2.end(), A(5)), A(3));
54+
test(C(a3.begin(), a3.end(), A(5)), A(3));
55+
test(C(a4.begin(), a4.end(), A(5)), A(3));
56+
test(C(a5.begin(), a5.end(), A(5)), A(3));
4657
}
47-
#if TEST_STD_VER >= 11
48-
{
49-
bool a[] = {0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0};
50-
bool* an = a + sizeof(a) / sizeof(a[0]);
51-
test(std::vector<bool, min_allocator<bool>>(a, an), min_allocator<bool>());
58+
{ // Test with other_allocator
59+
using A = other_allocator<bool>;
60+
using C = std::vector<bool, A>;
61+
test(C(a1.begin(), a1.end(), A(5)), A(3));
62+
test(C(a2.begin(), a2.end(), A(5)), A(3));
63+
test(C(a3.begin(), a3.end(), A(5)), A(3));
64+
test(C(a4.begin(), a4.end(), A(5)), A(3));
65+
test(C(a5.begin(), a5.end(), A(5)), A(3));
5266
}
53-
{
54-
std::vector<bool, min_allocator<bool> > l(3, true, min_allocator<bool>());
55-
std::vector<bool, min_allocator<bool> > l2(l, min_allocator<bool>());
56-
assert(l2 == l);
57-
assert(l2.get_allocator() == min_allocator<bool>());
67+
{ // Test with min_allocator
68+
using A = min_allocator<bool>;
69+
using C = std::vector<bool, A>;
70+
test(C(a1.begin(), a1.end(), A()), A());
71+
test(C(a2.begin(), a2.end(), A()), A());
72+
test(C(a3.begin(), a3.end(), A()), A());
73+
test(C(a4.begin(), a4.end(), A()), A());
74+
test(C(a5.begin(), a5.end(), A()), A());
5875
}
59-
#endif
6076

6177
return true;
6278
}

0 commit comments

Comments
 (0)