|
21 | 21 | # include <pthread.h> |
22 | 22 | # include <stdio.h> |
23 | 23 | # include <sys/mman.h> |
| 24 | +# include <sys/personality.h> |
24 | 25 | # include <sys/resource.h> |
25 | 26 | # include <sys/syscall.h> |
26 | 27 | # include <sys/time.h> |
@@ -107,6 +108,37 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) { |
107 | 108 | ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size)); |
108 | 109 | } |
109 | 110 |
|
| 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 | + |
110 | 142 | # if SANITIZER_ANDROID |
111 | 143 | // FIXME: should we do anything for Android? |
112 | 144 | void AsanCheckDynamicRTPrereqs() {} |
|
0 commit comments