|
From: Julian S. <js...@ac...> - 2011-03-05 00:55:19
|
Hi Bart,
I was looking at the free-is-write test (read_after_free.c) that
you removed in r11522. I think that program does not test exactly
the correct thing. It does (iiuc)
T1 T2
... free malloc'd area
access malloc'd area ...
so even Memcheck will detect this (I tried it). The dangerous case
is this
T1 T2
access malloc'd area ...
... free malloc'd area
Here, Memcheck does not complain, because the free happens
"wallclock-after" the access, but it does not "happen-after"
the access (if you see what I mean).
Below is a test which does, I think, the required check.
(Also, doesn't require atomics.)
J
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
static char* s_mem;
/* wait a second, so as to guarantee that the parent accesses
the malloc'd area, then free it. */
static void* thread_func(void* arg)
{
sleep(1);
free(s_mem);
return NULL;
}
int main(int argc, char** argv)
{
pthread_t tid;
int quiet;
fprintf(stderr, "Start.\n");
quiet = argc > 1;
s_mem = malloc(10);
if (0 && !quiet)
fprintf(stderr, "Pointer to allocated memory: %p\n", s_mem);
assert(s_mem);
pthread_create(&tid, NULL, thread_func, NULL);
/* Write, which isn't coordinated with the free ==> a race
should be reported. */
char c = s_mem[5];
__asm__ __volatile__("" : : "r"((long)c) );
pthread_join(tid, NULL);
fprintf(stderr, "Done.\n");
return 0;
}
|
|
From: Bart V. A. <bva...@ac...> - 2011-03-05 08:57:10
|
(see inline comments)
On Sat, Mar 5, 2011 at 1:52 AM, Julian Seward <js...@ac...> wrote:
> I was looking at the free-is-write test (read_after_free.c) that
> you removed in r11522. I think that program does not test exactly
> the correct thing. It does (iiuc)
>
> T1 T2
> ... free malloc'd area
> access malloc'd area ...
>
> so even Memcheck will detect this (I tried it). The dangerous case
> is this
>
> T1 T2
> access malloc'd area ...
> ... free malloc'd area
>
> Here, Memcheck does not complain, because the free happens
> "wallclock-after" the access, but it does not "happen-after"
> the access (if you see what I mean).
The purpose of the read_after_free test program was exactly what its
name suggests: trigger a read of memory after it has been freed
(wallclock-after), so that test program is correct. I am aware that
the problem triggered by that test is also detected by Memcheck. The
test program below is a different test program but a test program that
seems even more interesting to me than the original read_after_free
test program.
> #include <assert.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <pthread.h>
> #include <unistd.h>
>
> static char* s_mem;
>
> /* wait a second, so as to guarantee that the parent accesses
> the malloc'd area, then free it. */
> static void* thread_func(void* arg)
> {
> sleep(1);
> free(s_mem);
> return NULL;
> }
>
> int main(int argc, char** argv)
> {
> pthread_t tid;
> int quiet;
>
> fprintf(stderr, "Start.\n");
>
> quiet = argc > 1;
>
> s_mem = malloc(10);
> if (0 && !quiet)
> fprintf(stderr, "Pointer to allocated memory: %p\n", s_mem);
> assert(s_mem);
> pthread_create(&tid, NULL, thread_func, NULL);
>
> /* Write, which isn't coordinated with the free ==> a race
> should be reported. */
The above comment looks incorrect to me - the statement below triggers
a read of s_mem[5], not a write.
> char c = s_mem[5];
> __asm__ __volatile__("" : : "r"((long)c) );
>
> pthread_join(tid, NULL);
> fprintf(stderr, "Done.\n");
> return 0;
> }
Bart.
|