Skip to content

Commit 8e2fb68

Browse files
committed
[msan] Fix open_memstream handling.
For open_memstream() files, buffer pointer is only valid immediately after fflush() or fclose(). Fix the fclose() interceptor to unpoison after the REAL(fclose) call, not before it. llvm-svn: 242535
1 parent b063f5c commit 8e2fb68

File tree

2 files changed

+28
-17
lines changed

2 files changed

+28
-17
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4831,15 +4831,14 @@ INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
48314831
INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
48324832
void *ctx;
48334833
COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
4834-
if (fp) {
4835-
COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
4836-
const FileMetadata *m = GetInterceptorMetadata(fp);
4837-
if (m) {
4838-
COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
4839-
DeleteInterceptorMetadata(fp);
4840-
}
4834+
COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
4835+
const FileMetadata *m = GetInterceptorMetadata(fp);
4836+
int res = REAL(fclose)(fp);
4837+
if (m) {
4838+
COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
4839+
DeleteInterceptorMetadata(fp);
48414840
}
4842-
return REAL(fclose)(fp);
4841+
return res;
48434842
}
48444843
#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
48454844
#else

compiler-rt/test/sanitizer_common/TestCases/Linux/open_memstream.cc

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,34 +25,46 @@ static void check_mem_is_good(void *p, size_t s) {
2525
static void check_mem_is_good(void *p, size_t s) {}
2626
#endif
2727

28-
static void run(void) {
28+
static void run(bool flush) {
2929
char *buf;
3030
size_t buf_len;
3131
fprintf(stderr, " &buf %p, &buf_len %p\n", &buf, &buf_len);
3232
FILE *fp = open_memstream(&buf, &buf_len);
3333
fprintf(fp, "hello");
34-
fflush(fp);
35-
check_mem_is_good(&buf, sizeof(buf));
36-
check_mem_is_good(&buf_len, sizeof(buf_len));
37-
check_mem_is_good(buf, buf_len);
34+
if (flush) {
35+
fflush(fp);
36+
check_mem_is_good(&buf, sizeof(buf));
37+
check_mem_is_good(&buf_len, sizeof(buf_len));
38+
check_mem_is_good(buf, buf_len);
39+
}
3840

3941
char *p = new char[1024];
4042
memset(p, 'a', 1023);
4143
p[1023] = 0;
4244
for (int i = 0; i < 100; ++i)
4345
fprintf(fp, "%s", p);
4446
delete[] p;
45-
fflush(fp);
46-
fprintf(stderr, " %p addr %p, len %zu\n", &buf, buf, buf_len);
47+
48+
if (flush) {
49+
fflush(fp);
50+
fprintf(stderr, " %p addr %p, len %zu\n", &buf, buf, buf_len);
51+
check_mem_is_good(&buf, sizeof(buf));
52+
check_mem_is_good(&buf_len, sizeof(buf_len));
53+
check_mem_is_good(buf, buf_len);\
54+
}
55+
56+
fclose(fp);
4757
check_mem_is_good(&buf, sizeof(buf));
4858
check_mem_is_good(&buf_len, sizeof(buf_len));
4959
check_mem_is_good(buf, buf_len);
50-
fclose(fp);
60+
5161
free(buf);
5262
}
5363

5464
int main(void) {
5565
for (int i = 0; i < 100; ++i)
56-
run();
66+
run(false);
67+
for (int i = 0; i < 100; ++i)
68+
run(true);
5769
return 0;
5870
}

0 commit comments

Comments
 (0)