Skip to content

Commit 9f298da

Browse files
committedFeb 19, 2013
[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
1 parent 3ece9be commit 9f298da

File tree

6 files changed

+41
-4
lines changed

6 files changed

+41
-4
lines changed
 

‎compiler-rt/lib/asan/asan_mac.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ void LeakyResetEnv(const char *name, const char *name_value) {
114114
char **del = environ;
115115
do {
116116
del[0] = del[1];
117-
} while(*del++);
117+
} while (*del++);
118118
}
119119
}
120120
}
@@ -193,7 +193,8 @@ void MaybeReexec() {
193193
if ((uptr)(piece_start - dyld_insert_libraries) > old_env_len) break;
194194
uptr piece_len = piece_end - piece_start;
195195

196-
// If the current piece isn't the runtime library name, append it to new_env.
196+
// If the current piece isn't the runtime library name,
197+
// append it to new_env.
197198
if ((piece_len != fname_len) ||
198199
(internal_strncmp(piece_start, info.dli_fname, fname_len) != 0)) {
199200
if (new_env_pos != new_env + env_name_len + 1) {
@@ -202,7 +203,7 @@ void MaybeReexec() {
202203
}
203204
internal_strncpy(new_env_pos, piece_start, piece_len);
204205
}
205-
// Move on to the next piece.
206+
// Move on to the next piece.
206207
new_env_pos += piece_len;
207208
piece_start = piece_end;
208209
} while (piece_start < old_env_end);

‎compiler-rt/lib/asan/asan_rtl.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,17 @@ ASAN_REPORT_ERROR(store, true, 4)
222222
ASAN_REPORT_ERROR(store, true, 8)
223223
ASAN_REPORT_ERROR(store, true, 16)
224224

225+
#define ASAN_REPORT_ERROR_N(type, is_write) \
226+
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
227+
void __asan_report_ ## type ## _n(uptr addr, uptr size); \
228+
void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
229+
GET_CALLER_PC_BP_SP; \
230+
__asan_report_error(pc, bp, sp, addr, is_write, size); \
231+
}
232+
233+
ASAN_REPORT_ERROR_N(load, false)
234+
ASAN_REPORT_ERROR_N(store, true)
235+
225236
// Force the linker to keep the symbols for various ASan interface functions.
226237
// We want to keep those in the executable in order to let the instrumented
227238
// dynamic libraries access the symbol even if it is not used by the executable

‎compiler-rt/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
// RUN: echo __asan_report_store4 >> %t.interface
3232
// RUN: echo __asan_report_store8 >> %t.interface
3333
// RUN: echo __asan_report_store16 >> %t.interface
34+
// RUN: echo __asan_report_load_n >> %t.interface
35+
// RUN: echo __asan_report_store_n >> %t.interface
3436

3537
// RUN: cat %t.interface | sort -u | diff %t.symbols -
3638

‎compiler-rt/lib/asan/lit_tests/Linux/interface_symbols_linux.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
// RUN: echo __asan_report_store4 >> %t.interface
2424
// RUN: echo __asan_report_store8 >> %t.interface
2525
// RUN: echo __asan_report_store16 >> %t.interface
26+
// RUN: echo __asan_report_load_n >> %t.interface
27+
// RUN: echo __asan_report_store_n >> %t.interface
2628
// RUN: cat %t.interface | sort -u | diff %t.symbols -
2729

2830
int main() { return 0; }

‎compiler-rt/lib/asan/tests/asan_test.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,26 @@ TEST(AddressSanitizer, UAF_char) {
170170
EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, kLargeMalloc / 2), uaf_string);
171171
}
172172

173+
TEST(AddressSanitizer, UAF_long_double) {
174+
long double *p = Ident(new long double[10]);
175+
EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 10");
176+
EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 10");
177+
delete [] Ident(p);
178+
}
179+
180+
struct Packed5 {
181+
int x;
182+
char c;
183+
} __attribute__((packed));
184+
185+
186+
TEST(AddressSanitizer, UAF_Packed5) {
187+
Packed5 *p = Ident(new Packed5[2]);
188+
EXPECT_DEATH(p[0] = p[3], "READ of size 5");
189+
EXPECT_DEATH(p[3] = p[0], "WRITE of size 5");
190+
delete [] Ident(p);
191+
}
192+
173193
#if ASAN_HAS_BLACKLIST
174194
TEST(AddressSanitizer, IgnoreTest) {
175195
int *x = Ident(new int);

‎compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ TEST(SanitizerCommon, FileOps) {
5757

5858
u32 uid = GetUid();
5959
char temp_filename[128];
60-
internal_snprintf(temp_filename, 128, "/tmp/sanitizer_common.tmp.%d", uid);
60+
internal_snprintf(temp_filename, sizeof(temp_filename),
61+
"/tmp/sanitizer_common.tmp.%d", uid);
6162
fd_t fd = OpenFile(temp_filename, true);
6263
EXPECT_NE(fd, kInvalidFd);
6364
EXPECT_EQ(len1, internal_write(fd, str1, len1));

0 commit comments

Comments
 (0)
Please sign in to comment.