"Clean room" test for a "copy on write" problem leading to bugs #113

and #928. Under certain conditions a fork()ed child process can
write to the parent process' memory.
A fix follows...


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20401 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-03-21 19:36:34 +00:00
parent 6f93ad781b
commit 34ce586692
2 changed files with 73 additions and 7 deletions

View File

@ -3,10 +3,17 @@ SubDir HAIKU_TOP src tests system kernel ;
UsePrivateHeaders kernel ; UsePrivateHeaders kernel ;
UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ;
SimpleTest cow_bug113_test : cow_bug113_test.cpp ;
SimpleTest fibo_load_image : fibo_load_image.cpp ; SimpleTest fibo_load_image : fibo_load_image.cpp ;
SimpleTest fibo_fork : fibo_fork.cpp ; SimpleTest fibo_fork : fibo_fork.cpp ;
SimpleTest fibo_exec : fibo_exec.cpp ; SimpleTest fibo_exec : fibo_exec.cpp ;
SimpleTest lock_node_test :
lock_node_test.cpp
: be
;
SimpleTest port_close_test_1 : port_close_test_1.cpp ; SimpleTest port_close_test_1 : port_close_test_1.cpp ;
SimpleTest port_close_test_2 : port_close_test_2.cpp ; SimpleTest port_close_test_2 : port_close_test_2.cpp ;
@ -22,16 +29,11 @@ SimpleTest port_wakeup_test_7 : port_wakeup_test_7.cpp ;
SimpleTest port_wakeup_test_8 : port_wakeup_test_8.cpp ; SimpleTest port_wakeup_test_8 : port_wakeup_test_8.cpp ;
SimpleTest port_wakeup_test_9 : port_wakeup_test_9.cpp ; SimpleTest port_wakeup_test_9 : port_wakeup_test_9.cpp ;
SimpleTest transfer_area_test : transfer_area_test.cpp ;
SimpleTest syscall_time : syscall_time.cpp ; SimpleTest syscall_time : syscall_time.cpp ;
SimpleTest yield_test : yield_test.cpp ; SimpleTest transfer_area_test : transfer_area_test.cpp ;
SimpleTest lock_node_test : SimpleTest yield_test : yield_test.cpp ;
lock_node_test.cpp
: be
;
SimpleTest wait_test_1 : wait_test_1.c ; SimpleTest wait_test_1 : wait_test_1.c ;
SimpleTest wait_test_2 : wait_test_2.cpp ; SimpleTest wait_test_2 : wait_test_2.cpp ;

View File

@ -0,0 +1,64 @@
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <OS.h>
const char* kInitialValue = "/dev/null";
const char* kChangedValue = "Argh!";
int
main(int argc, const char* const* argv)
{
thread_id parent = find_thread(NULL);
char* globalVar = NULL;
area_id area = create_area("cow test", (void**)&globalVar,
B_ANY_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
if (area < 0) {
printf("failed to create area\n");
return 1;
}
strcpy(globalVar, kInitialValue);
printf("[%ld] parent: before fork(): globalVar(%p): \"%s\"\n", parent,
globalVar, globalVar);
pid_t child = fork();
if (child == 0) {
// child
child = find_thread(NULL);
// let the kernel read access the page
struct stat st;
stat(globalVar, &st);
printf("[%ld] child: after kernel read: globalVar: \"%s\"\n",
child, globalVar);
// write access the page from userland
strcpy(globalVar, kChangedValue);
printf("[%ld] child: after change: globalVar: \"%s\"\n", child,
globalVar);
} else {
// parent
// wait for the child
status_t exitVal;
while (wait_for_thread(child, &exitVal) == B_INTERRUPTED);
// check the value
printf("[%ld] parent: after exit child: globalVar: \"%s\"\n",
parent, globalVar);
if (strcmp(globalVar, kInitialValue) == 0)
printf("test OK\n");
else
printf("test FAILED: child process changed parent's memory!\n");
}
return 0;
}