From 34ce58669229176770ea902db64ca025026fcd67 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 21 Mar 2007 19:36:34 +0000 Subject: [PATCH] "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 --- src/tests/system/kernel/Jamfile | 16 +++--- src/tests/system/kernel/cow_bug113_test.cpp | 64 +++++++++++++++++++++ 2 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 src/tests/system/kernel/cow_bug113_test.cpp diff --git a/src/tests/system/kernel/Jamfile b/src/tests/system/kernel/Jamfile index a8016225c7..74e897e26f 100644 --- a/src/tests/system/kernel/Jamfile +++ b/src/tests/system/kernel/Jamfile @@ -3,10 +3,17 @@ SubDir HAIKU_TOP src tests system kernel ; UsePrivateHeaders kernel ; UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; +SimpleTest cow_bug113_test : cow_bug113_test.cpp ; + SimpleTest fibo_load_image : fibo_load_image.cpp ; SimpleTest fibo_fork : fibo_fork.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_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_9 : port_wakeup_test_9.cpp ; -SimpleTest transfer_area_test : transfer_area_test.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 : - lock_node_test.cpp - : be - ; +SimpleTest yield_test : yield_test.cpp ; SimpleTest wait_test_1 : wait_test_1.c ; SimpleTest wait_test_2 : wait_test_2.cpp ; diff --git a/src/tests/system/kernel/cow_bug113_test.cpp b/src/tests/system/kernel/cow_bug113_test.cpp new file mode 100644 index 0000000000..4bdd0e3538 --- /dev/null +++ b/src/tests/system/kernel/cow_bug113_test.cpp @@ -0,0 +1,64 @@ +#include +#include +#include + +#include + +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; +}