forked from OSchip/llvm-project
[asan] instrument memory accesses with unusual sizes
This patch makes asan instrument memory accesses with unusual sizes (e.g. 5 bytes or 10 bytes), e.g. long double or packed structures. Instrumentation is done with two 1-byte checks (first and last bytes) and if the error is found __asan_report_load_n(addr, real_size) or __asan_report_store_n(addr, real_size) is called. asan-rt part Also fix lint. llvm-svn: 175508
This commit is contained in:
parent
3ece9beaf1
commit
9f298da9bd
|
@ -114,7 +114,7 @@ void LeakyResetEnv(const char *name, const char *name_value) {
|
|||
char **del = environ;
|
||||
do {
|
||||
del[0] = del[1];
|
||||
} while(*del++);
|
||||
} while (*del++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +193,8 @@ void MaybeReexec() {
|
|||
if ((uptr)(piece_start - dyld_insert_libraries) > old_env_len) break;
|
||||
uptr piece_len = piece_end - piece_start;
|
||||
|
||||
// If the current piece isn't the runtime library name, append it to new_env.
|
||||
// If the current piece isn't the runtime library name,
|
||||
// append it to new_env.
|
||||
if ((piece_len != fname_len) ||
|
||||
(internal_strncmp(piece_start, info.dli_fname, fname_len) != 0)) {
|
||||
if (new_env_pos != new_env + env_name_len + 1) {
|
||||
|
|
|
@ -222,6 +222,17 @@ ASAN_REPORT_ERROR(store, true, 4)
|
|||
ASAN_REPORT_ERROR(store, true, 8)
|
||||
ASAN_REPORT_ERROR(store, true, 16)
|
||||
|
||||
#define ASAN_REPORT_ERROR_N(type, is_write) \
|
||||
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
||||
void __asan_report_ ## type ## _n(uptr addr, uptr size); \
|
||||
void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
|
||||
GET_CALLER_PC_BP_SP; \
|
||||
__asan_report_error(pc, bp, sp, addr, is_write, size); \
|
||||
}
|
||||
|
||||
ASAN_REPORT_ERROR_N(load, false)
|
||||
ASAN_REPORT_ERROR_N(store, true)
|
||||
|
||||
// Force the linker to keep the symbols for various ASan interface functions.
|
||||
// We want to keep those in the executable in order to let the instrumented
|
||||
// dynamic libraries access the symbol even if it is not used by the executable
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
// RUN: echo __asan_report_store4 >> %t.interface
|
||||
// RUN: echo __asan_report_store8 >> %t.interface
|
||||
// RUN: echo __asan_report_store16 >> %t.interface
|
||||
// RUN: echo __asan_report_load_n >> %t.interface
|
||||
// RUN: echo __asan_report_store_n >> %t.interface
|
||||
|
||||
// RUN: cat %t.interface | sort -u | diff %t.symbols -
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
// RUN: echo __asan_report_store4 >> %t.interface
|
||||
// RUN: echo __asan_report_store8 >> %t.interface
|
||||
// RUN: echo __asan_report_store16 >> %t.interface
|
||||
// RUN: echo __asan_report_load_n >> %t.interface
|
||||
// RUN: echo __asan_report_store_n >> %t.interface
|
||||
// RUN: cat %t.interface | sort -u | diff %t.symbols -
|
||||
|
||||
int main() { return 0; }
|
||||
|
|
|
@ -170,6 +170,26 @@ TEST(AddressSanitizer, UAF_char) {
|
|||
EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, kLargeMalloc / 2), uaf_string);
|
||||
}
|
||||
|
||||
TEST(AddressSanitizer, UAF_long_double) {
|
||||
long double *p = Ident(new long double[10]);
|
||||
EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 10");
|
||||
EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 10");
|
||||
delete [] Ident(p);
|
||||
}
|
||||
|
||||
struct Packed5 {
|
||||
int x;
|
||||
char c;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
TEST(AddressSanitizer, UAF_Packed5) {
|
||||
Packed5 *p = Ident(new Packed5[2]);
|
||||
EXPECT_DEATH(p[0] = p[3], "READ of size 5");
|
||||
EXPECT_DEATH(p[3] = p[0], "WRITE of size 5");
|
||||
delete [] Ident(p);
|
||||
}
|
||||
|
||||
#if ASAN_HAS_BLACKLIST
|
||||
TEST(AddressSanitizer, IgnoreTest) {
|
||||
int *x = Ident(new int);
|
||||
|
|
|
@ -57,7 +57,8 @@ TEST(SanitizerCommon, FileOps) {
|
|||
|
||||
u32 uid = GetUid();
|
||||
char temp_filename[128];
|
||||
internal_snprintf(temp_filename, 128, "/tmp/sanitizer_common.tmp.%d", uid);
|
||||
internal_snprintf(temp_filename, sizeof(temp_filename),
|
||||
"/tmp/sanitizer_common.tmp.%d", uid);
|
||||
fd_t fd = OpenFile(temp_filename, true);
|
||||
EXPECT_NE(fd, kInvalidFd);
|
||||
EXPECT_EQ(len1, internal_write(fd, str1, len1));
|
||||
|
|
Loading…
Reference in New Issue