diff --git a/CMakeLists.txt b/CMakeLists.txt index cc699abf..259afa48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -328,6 +328,16 @@ foreach(filename ${ae_overflow_files}) ) endforeach() +# loops over ae_nullptr_files and run "ae $bc_file" +file(GLOB ae_nullptr_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/test_cases_bc/ae_nullptr_deref_tests/*.bc") + +foreach(filename ${ae_nullptr_files}) + add_test( + NAME ae_nullptr/${filename} + COMMAND ae -nullptr ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) +endforeach() ## symbolic abstraction tests (ctest -R symabs -VV) set(cmd "ae -symabs") diff --git a/generate_bc.sh b/generate_bc.sh index 179bc83e..4de04f2c 100755 --- a/generate_bc.sh +++ b/generate_bc.sh @@ -18,6 +18,7 @@ test_dirs=" objtype_tests ae_overflow_tests ae_assert_tests + ae_nullptr_deref_tests " diff --git a/src/ae_assert_tests/LOOP_while01-1.c b/src/ae_assert_tests/LOOP_while01-1.c new file mode 100644 index 00000000..f1a17641 --- /dev/null +++ b/src/ae_assert_tests/LOOP_while01-1.c @@ -0,0 +1,12 @@ +#include "stdbool.h" +extern void svf_assert(bool); + +int main(){ + int x; + x=10; + while(x>0) { + x--; + } + svf_assert(x == 0); + return 0; +} \ No newline at end of file diff --git a/src/ae_assert_tests/LOOP_while02-0.c b/src/ae_assert_tests/LOOP_while02-0.c new file mode 100644 index 00000000..b26f9e0b --- /dev/null +++ b/src/ae_assert_tests/LOOP_while02-0.c @@ -0,0 +1,12 @@ +#include "stdbool.h" +extern void svf_assert(bool); + +int main(){ + int x; + x=1; + while(x<128) { + x*=2; + } + svf_assert(x == 128); + return 0; +} \ No newline at end of file diff --git a/src/ae_assert_tests/LOOP_while02-1.c b/src/ae_assert_tests/LOOP_while02-1.c new file mode 100644 index 00000000..f3d86ddf --- /dev/null +++ b/src/ae_assert_tests/LOOP_while02-1.c @@ -0,0 +1,12 @@ +#include "stdbool.h" +extern void svf_assert(bool); + +int main(){ + int x; + x=128; + while(x>4) { + x/=2; + } + svf_assert(x == 4); + return 0; +} \ No newline at end of file diff --git a/src/ae_assert_tests/CVE-2022-27239-0.c b/src/ae_assert_tests_fail/CVE-2022-27239-0.c similarity index 100% rename from src/ae_assert_tests/CVE-2022-27239-0.c rename to src/ae_assert_tests_fail/CVE-2022-27239-0.c diff --git a/src/ae_nullptr_deref_tests/array_2d_big.c b/src/ae_nullptr_deref_tests/array_2d_big.c new file mode 100644 index 00000000..8bacb520 --- /dev/null +++ b/src/ae_nullptr_deref_tests/array_2d_big.c @@ -0,0 +1,23 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +#define SIZE 100 + +int main() { + int *arr[SIZE][SIZE]; + + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + arr[i][j] = NULL; + } + } + + for (int m = 0; m < SIZE; m++) { + for (int n = 0; n < SIZE; n++) { + UNSAFE_LOAD(arr[m][n]); + } + } + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/array_2d_small.c b/src/ae_nullptr_deref_tests/array_2d_small.c new file mode 100644 index 00000000..f7ac26df --- /dev/null +++ b/src/ae_nullptr_deref_tests/array_2d_small.c @@ -0,0 +1,16 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + int *arr[2][2]; + arr[0][0] = NULL; + arr[0][1] = NULL; + arr[1][0] = NULL; + arr[1][1] = NULL; + + UNSAFE_LOAD(arr[0][0]); + UNSAFE_LOAD(arr[0][1]); + UNSAFE_LOAD(arr[1][0]); + UNSAFE_LOAD(arr[1][1]); +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/array_2d_small_partial_null.c b/src/ae_nullptr_deref_tests/array_2d_small_partial_null.c new file mode 100644 index 00000000..54a187fd --- /dev/null +++ b/src/ae_nullptr_deref_tests/array_2d_small_partial_null.c @@ -0,0 +1,21 @@ +#include +#include + +extern void SAFE_LOAD(void *ptr); +extern void UNSAFE_LOAD(void *ptr); + +int main() { + int *arr[2][2]; + arr[0][0] = NULL; + arr[0][1] = NULL; + arr[1][0] = malloc(sizeof(int)); + arr[1][1] = malloc(sizeof(int)); + + *arr[1][0] = 123; + *arr[1][1] = 456; + + UNSAFE_LOAD(arr[0][0]); + UNSAFE_LOAD(arr[0][1]); + SAFE_LOAD(arr[1][0]); + SAFE_LOAD(arr[1][1]); +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/array_all_nullptr.c b/src/ae_nullptr_deref_tests/array_all_nullptr.c new file mode 100644 index 00000000..2d9fcbec --- /dev/null +++ b/src/ae_nullptr_deref_tests/array_all_nullptr.c @@ -0,0 +1,13 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + int *n = NULL; + int *ptrs[5] = {n, n, n, n, n}; + for (int i = 0; i < 5; i++) { + UNSAFE_LOAD(ptrs[i]); + } + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/array_of_struct.c b/src/ae_nullptr_deref_tests/array_of_struct.c new file mode 100644 index 00000000..fb801260 --- /dev/null +++ b/src/ae_nullptr_deref_tests/array_of_struct.c @@ -0,0 +1,23 @@ +#include + +extern void SAFE_LOAD(void *ptr); +extern void UNSAFE_LOAD(void *ptr); + +struct S { + int *intPtr; +}; + +int main() { + struct S arrStruct[3]; + + arrStruct[0].intPtr = malloc(sizeof(int)); + *arrStruct[0].intPtr = 1024; + + arrStruct[1].intPtr = NULL; + + SAFE_LOAD(arrStruct[0].intPtr); // malloc + UNSAFE_LOAD(arrStruct[1].intPtr); // NULL + UNSAFE_LOAD(arrStruct[2].intPtr); // uninitialized + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/char_ptr_arg.c b/src/ae_nullptr_deref_tests/char_ptr_arg.c new file mode 100644 index 00000000..9c56c434 --- /dev/null +++ b/src/ae_nullptr_deref_tests/char_ptr_arg.c @@ -0,0 +1,15 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +void foo(char *ptr) { + UNSAFE_LOAD(ptr); // Dereferencing the NULL pointer +} + +int main() { + char *ptr = NULL; + + foo(ptr); // Passing a NULL pointer to the function + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/char_ptr_arithmetic.c b/src/ae_nullptr_deref_tests/char_ptr_arithmetic.c new file mode 100644 index 00000000..e927a633 --- /dev/null +++ b/src/ae_nullptr_deref_tests/char_ptr_arithmetic.c @@ -0,0 +1,13 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + char *ptr = NULL; + + char *newPtr = ptr + 5; // Perform pointer arithmetic on NULL pointer + + UNSAFE_LOAD(newPtr); // Dereference the result + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/char_ptr_branch.c b/src/ae_nullptr_deref_tests/char_ptr_branch.c new file mode 100644 index 00000000..43e9aacf --- /dev/null +++ b/src/ae_nullptr_deref_tests/char_ptr_branch.c @@ -0,0 +1,18 @@ +#include +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + char *ptr = (char *)malloc(sizeof(char)); // Allocate memory + + int a = 0; + + if (a >= 0) { + ptr = NULL; + } + + UNSAFE_LOAD(ptr); + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/char_ptr_doubleptr.c b/src/ae_nullptr_deref_tests/char_ptr_doubleptr.c new file mode 100644 index 00000000..c6bd5865 --- /dev/null +++ b/src/ae_nullptr_deref_tests/char_ptr_doubleptr.c @@ -0,0 +1,11 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + + char **double_ptr = NULL; + UNSAFE_LOAD(double_ptr); // This will trigger a null pointer dereference + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/char_ptr_func_return_val.c b/src/ae_nullptr_deref_tests/char_ptr_func_return_val.c new file mode 100644 index 00000000..868e8aa3 --- /dev/null +++ b/src/ae_nullptr_deref_tests/char_ptr_func_return_val.c @@ -0,0 +1,15 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +char *getNullPointer() { + return NULL; // Function returns a NULL pointer +} + +int main() { + char *ptr = getNullPointer(); + + UNSAFE_LOAD(ptr); + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/char_ptr_in_struct_null.c b/src/ae_nullptr_deref_tests/char_ptr_in_struct_null.c new file mode 100644 index 00000000..ee898829 --- /dev/null +++ b/src/ae_nullptr_deref_tests/char_ptr_in_struct_null.c @@ -0,0 +1,20 @@ +// +// Created by Ethan Lin on 30/9/2024. +// + +#include + +extern void UNSAFE_LOAD(void *ptr); + +struct S { + char *ptr; +}; + +int main() { + struct S myStruct; + myStruct.ptr = NULL; + + UNSAFE_LOAD(myStruct.ptr); + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/char_ptr_in_struct_uninitialized.c b/src/ae_nullptr_deref_tests/char_ptr_in_struct_uninitialized.c new file mode 100644 index 00000000..417e706a --- /dev/null +++ b/src/ae_nullptr_deref_tests/char_ptr_in_struct_uninitialized.c @@ -0,0 +1,19 @@ +// +// Created by Ethan Lin on 30/9/2024. +// + +#include + +extern void UNSAFE_LOAD(void *ptr); + +struct S { + char *ptr; +}; + +int main() { + struct S myStruct; + + UNSAFE_LOAD(myStruct.ptr); + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/char_ptr_indirect_func_return_val.c b/src/ae_nullptr_deref_tests/char_ptr_indirect_func_return_val.c new file mode 100644 index 00000000..145269f0 --- /dev/null +++ b/src/ae_nullptr_deref_tests/char_ptr_indirect_func_return_val.c @@ -0,0 +1,20 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +char *getNullPointer() { + return NULL; // Function returns a NULL pointer +} + +char *foo() { + char *p = getNullPointer(); + return p; +} + +int main() { + char *ptr = foo(); + + UNSAFE_LOAD(ptr); // Dereferencing the NULL pointer + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/char_ptr_partial_nullptr.c b/src/ae_nullptr_deref_tests/char_ptr_partial_nullptr.c new file mode 100644 index 00000000..2ff02a4d --- /dev/null +++ b/src/ae_nullptr_deref_tests/char_ptr_partial_nullptr.c @@ -0,0 +1,11 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + char *p = malloc(sizeof(char) * 100); + *p = 'This string can be stored.'; + free(p); + p = NULL; + UNSAFE_LOAD(p); +} diff --git a/src/ae_nullptr_deref_tests/char_ptr_simple.c b/src/ae_nullptr_deref_tests/char_ptr_simple.c new file mode 100644 index 00000000..a4cfc6a8 --- /dev/null +++ b/src/ae_nullptr_deref_tests/char_ptr_simple.c @@ -0,0 +1,8 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + char *p = NULL; + UNSAFE_LOAD(p); +} diff --git a/src/ae_nullptr_deref_tests/char_ptr_uninit_ptr.c b/src/ae_nullptr_deref_tests/char_ptr_uninit_ptr.c new file mode 100644 index 00000000..80257e0f --- /dev/null +++ b/src/ae_nullptr_deref_tests/char_ptr_uninit_ptr.c @@ -0,0 +1,7 @@ + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + char *p; + UNSAFE_LOAD(p); +} diff --git a/src/ae_nullptr_deref_tests/dangleptr_safe_branch.c b/src/ae_nullptr_deref_tests/dangleptr_safe_branch.c new file mode 100644 index 00000000..e1a6c425 --- /dev/null +++ b/src/ae_nullptr_deref_tests/dangleptr_safe_branch.c @@ -0,0 +1,28 @@ +// +// Created by Ethan Lin on 11/11/2024. +// + +#include + +extern void SAFE_LOAD(void *p); +extern void UNSAFE_LOAD(void *p); + +int main() { + int a = 5; + + int *myPtr; + + myPtr = (int*)malloc(sizeof(int)); + free(myPtr); + UNSAFE_LOAD(myPtr); + if (a > 0) + { + myPtr = &a; + } else + { + /* Do nothing */ + } + + SAFE_LOAD(myPtr); + return 0; +} diff --git a/src/ae_nullptr_deref_tests/dangleptr_safe_free_and_reassign.c b/src/ae_nullptr_deref_tests/dangleptr_safe_free_and_reassign.c new file mode 100644 index 00000000..6bfcb156 --- /dev/null +++ b/src/ae_nullptr_deref_tests/dangleptr_safe_free_and_reassign.c @@ -0,0 +1,21 @@ +// +// Created by Ethan Lin on 11/11/2024. +// + +#include + +extern void SAFE_LOAD(void *p); +extern void UNSAFE_LOAD(void *p); + +int main() { + int a = 5; + + int *myPtr; + + myPtr = (int*)malloc(sizeof(int)); + free(myPtr); + // UNSAFE_LOAD(myPtr); + myPtr = &a; + SAFE_LOAD(myPtr); + return 0; +} diff --git a/src/ae_nullptr_deref_tests/dangleptr_safe_free_and_remalloc.c b/src/ae_nullptr_deref_tests/dangleptr_safe_free_and_remalloc.c new file mode 100644 index 00000000..6fb56dad --- /dev/null +++ b/src/ae_nullptr_deref_tests/dangleptr_safe_free_and_remalloc.c @@ -0,0 +1,19 @@ +// +// Created by Ethan Lin on 21/10/2024. +// +#include + +extern void SAFE_LOAD(void *p); +extern void UNSAFE_LOAD(void *p); +//extern void svf_assert(bool); + +int main() { + int *myPtr = (int*)malloc(sizeof(int)); + free(myPtr); + UNSAFE_LOAD(myPtr); + myPtr = (int*)malloc(sizeof(int)); + *myPtr = 200; + SAFE_LOAD(myPtr); + return 0; +} + diff --git a/src/ae_nullptr_deref_tests/dangleptr_safe_load.c b/src/ae_nullptr_deref_tests/dangleptr_safe_load.c new file mode 100644 index 00000000..a7d4c601 --- /dev/null +++ b/src/ae_nullptr_deref_tests/dangleptr_safe_load.c @@ -0,0 +1,14 @@ +// +// Created by Ethan Lin on 21/10/2024. +// +#include + +extern void SAFE_LOAD(void *p); + +int main() { + int *myPtr = malloc(sizeof(int)); + *myPtr = 123; + SAFE_LOAD(myPtr); + return 0; +} + diff --git a/src/ae_nullptr_deref_tests/dangleptr_safe_load_reassign.c b/src/ae_nullptr_deref_tests/dangleptr_safe_load_reassign.c new file mode 100644 index 00000000..72c27660 --- /dev/null +++ b/src/ae_nullptr_deref_tests/dangleptr_safe_load_reassign.c @@ -0,0 +1,24 @@ +// +// Created by Ethan Lin on 21/10/2024. +// +#include + +extern void SAFE_LOAD(void *p); +extern void UNSAFE_LOAD(void *p); +extern void svf_assert(bool); + +int main() { + int *safePtr = (int *)malloc(sizeof(int)); + *safePtr = 777; + SAFE_LOAD(safePtr); + + free(safePtr); + + safePtr = (int *)malloc(sizeof(int)); + *safePtr = 888; + SAFE_LOAD(safePtr); + svf_assert(*safePtr == 888); + + return 0; +} + diff --git a/src/ae_nullptr_deref_tests/dangleptr_unsafe_branch.c b/src/ae_nullptr_deref_tests/dangleptr_unsafe_branch.c new file mode 100644 index 00000000..aa12abdc --- /dev/null +++ b/src/ae_nullptr_deref_tests/dangleptr_unsafe_branch.c @@ -0,0 +1,28 @@ +// +// Created by Ethan Lin on 11/11/2024. +// + +#include + +extern void SAFE_LOAD(void *p); +extern void UNSAFE_LOAD(void *p); + +int main() { + int a = 5; + + int *myPtr; + + myPtr = (int*)malloc(sizeof(int)); + free(myPtr); + UNSAFE_LOAD(myPtr); + if (a < 0) + { + myPtr = &a; + } else + { + /* Do nothing */ + } + + UNSAFE_LOAD(myPtr); + return 0; +} diff --git a/src/ae_nullptr_deref_tests/dangleptr_unsafe_load_dangleptr.c b/src/ae_nullptr_deref_tests/dangleptr_unsafe_load_dangleptr.c new file mode 100644 index 00000000..20ce5b45 --- /dev/null +++ b/src/ae_nullptr_deref_tests/dangleptr_unsafe_load_dangleptr.c @@ -0,0 +1,18 @@ +// +// Created by Ethan Lin on 21/10/2024. +// +#include + +extern void SAFE_LOAD(void *p); +extern void UNSAFE_LOAD(void *p); + +int main() { + int *myPtr = (int*)malloc(sizeof(int)); + // SAFE_LOAD(myPtr); + *myPtr = 200; + free(myPtr); + UNSAFE_LOAD(myPtr); + *myPtr = 404; // Trigger dangling pointer dereference + return 0; +} + diff --git a/src/ae_nullptr_deref_tests/func_nullptr_func_1.c b/src/ae_nullptr_deref_tests/func_nullptr_func_1.c new file mode 100644 index 00000000..6ce839c7 --- /dev/null +++ b/src/ae_nullptr_deref_tests/func_nullptr_func_1.c @@ -0,0 +1,11 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + void (*funcPtr)() = NULL; + + UNSAFE_LOAD(funcPtr); // Attempting to call a function via a NULL function pointer + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/func_nullptr_func_2.c b/src/ae_nullptr_deref_tests/func_nullptr_func_2.c new file mode 100644 index 00000000..6a2430ec --- /dev/null +++ b/src/ae_nullptr_deref_tests/func_nullptr_func_2.c @@ -0,0 +1,16 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); +typedef void (*FuncPtr)(); // Define a function pointer type + +void invokeFunction(FuncPtr func) { + UNSAFE_LOAD(func); +} + +int main() { + FuncPtr funcPtr = NULL; // Initialize function pointer to NULL + + invokeFunction(funcPtr); // Attempt to call the function via the NULL pointer + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/int_ptr_arg.c b/src/ae_nullptr_deref_tests/int_ptr_arg.c new file mode 100644 index 00000000..5df69be1 --- /dev/null +++ b/src/ae_nullptr_deref_tests/int_ptr_arg.c @@ -0,0 +1,15 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +void foo(int *ptr) { + UNSAFE_LOAD(ptr); // Dereferencing the NULL pointer +} + +int main() { + int *ptr = NULL; + + foo(ptr); // Passing a NULL pointer to the function + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/int_ptr_arithmetic.c b/src/ae_nullptr_deref_tests/int_ptr_arithmetic.c new file mode 100644 index 00000000..cf501b8c --- /dev/null +++ b/src/ae_nullptr_deref_tests/int_ptr_arithmetic.c @@ -0,0 +1,13 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + int *ptr = NULL; + + int *newPtr = ptr + 5; // Perform pointer arithmetic on NULL pointer + + UNSAFE_LOAD(newPtr); // Dereference the result + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/int_ptr_branch.c b/src/ae_nullptr_deref_tests/int_ptr_branch.c new file mode 100644 index 00000000..47d0130f --- /dev/null +++ b/src/ae_nullptr_deref_tests/int_ptr_branch.c @@ -0,0 +1,18 @@ +#include +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + int *ptr = (int *)malloc(sizeof(int)); // Allocate memory + + int a = 0; + + if (a >= 0) { + ptr = NULL; + } + + UNSAFE_LOAD(ptr); + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/int_ptr_doubleptr.c b/src/ae_nullptr_deref_tests/int_ptr_doubleptr.c new file mode 100644 index 00000000..be09d968 --- /dev/null +++ b/src/ae_nullptr_deref_tests/int_ptr_doubleptr.c @@ -0,0 +1,11 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + + int **double_ptr = NULL; + UNSAFE_LOAD(double_ptr); // This will trigger a null pointer dereference + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/int_ptr_func_return_val.c b/src/ae_nullptr_deref_tests/int_ptr_func_return_val.c new file mode 100644 index 00000000..eed2cc2f --- /dev/null +++ b/src/ae_nullptr_deref_tests/int_ptr_func_return_val.c @@ -0,0 +1,15 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int* getNullPointer() { + return NULL; // Function returns a NULL pointer +} + +int main() { + int *ptr = getNullPointer(); + + UNSAFE_LOAD(ptr); + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/int_ptr_in_struct_null.c b/src/ae_nullptr_deref_tests/int_ptr_in_struct_null.c new file mode 100644 index 00000000..9ae9943e --- /dev/null +++ b/src/ae_nullptr_deref_tests/int_ptr_in_struct_null.c @@ -0,0 +1,21 @@ +// +// Created by Ethan Lin on 30/9/2024. +// + +#include + +extern void UNSAFE_LOAD(void *ptr); + +struct S { + int *ptr; +}; + +int main() { + struct S myStruct; + myStruct.ptr = NULL; + + UNSAFE_LOAD(myStruct.ptr); + *myStruct.ptr = 404; + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/int_ptr_in_struct_uninitialized.c b/src/ae_nullptr_deref_tests/int_ptr_in_struct_uninitialized.c new file mode 100644 index 00000000..e0163afe --- /dev/null +++ b/src/ae_nullptr_deref_tests/int_ptr_in_struct_uninitialized.c @@ -0,0 +1,20 @@ +// +// Created by Ethan Lin on 30/9/2024. +// + +#include + +extern void UNSAFE_LOAD(void *ptr); + +struct S { + int *ptr; +}; + +int main() { + struct S myStruct; + + UNSAFE_LOAD(myStruct.ptr); + *myStruct.ptr = 404; + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/int_ptr_indirect_func_return_val.c b/src/ae_nullptr_deref_tests/int_ptr_indirect_func_return_val.c new file mode 100644 index 00000000..e1ccd76c --- /dev/null +++ b/src/ae_nullptr_deref_tests/int_ptr_indirect_func_return_val.c @@ -0,0 +1,20 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int *getNullPointer() { + return NULL; // Function returns a NULL pointer +} + +int *foo() { + int *p = getNullPointer(); + return p; +} + +int main() { + int *ptr = foo(); + + UNSAFE_LOAD(ptr); // Dereferencing the NULL pointer + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/int_ptr_partial_nullptr.c b/src/ae_nullptr_deref_tests/int_ptr_partial_nullptr.c new file mode 100644 index 00000000..26e5b0eb --- /dev/null +++ b/src/ae_nullptr_deref_tests/int_ptr_partial_nullptr.c @@ -0,0 +1,11 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + int* p = malloc(sizeof(int)); + *p = 1; + free(p); + p = NULL; + UNSAFE_LOAD(p); +} diff --git a/src/ae_nullptr_deref_tests/int_ptr_simple.c b/src/ae_nullptr_deref_tests/int_ptr_simple.c new file mode 100644 index 00000000..8d886158 --- /dev/null +++ b/src/ae_nullptr_deref_tests/int_ptr_simple.c @@ -0,0 +1,8 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + int* p = NULL; + UNSAFE_LOAD(p); +} diff --git a/src/ae_nullptr_deref_tests/int_ptr_uninit_ptr.c b/src/ae_nullptr_deref_tests/int_ptr_uninit_ptr.c new file mode 100644 index 00000000..ee34de74 --- /dev/null +++ b/src/ae_nullptr_deref_tests/int_ptr_uninit_ptr.c @@ -0,0 +1,7 @@ + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + int* p; + UNSAFE_LOAD(p); +} diff --git a/src/ae_nullptr_deref_tests/safe_array_access.c b/src/ae_nullptr_deref_tests/safe_array_access.c new file mode 100644 index 00000000..e47e78c9 --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_array_access.c @@ -0,0 +1,9 @@ +#include + +extern void SAFE_LOAD(void *ptr); + +int main() { + int arr[10] = {0}; + for (int i = 0; i < 10; ++i) + SAFE_LOAD(&arr[i]); +} diff --git a/src/ae_nullptr_deref_tests/safe_array_of_struct_1.c b/src/ae_nullptr_deref_tests/safe_array_of_struct_1.c new file mode 100644 index 00000000..3cda2d46 --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_array_of_struct_1.c @@ -0,0 +1,16 @@ +#include + +extern void SAFE_LOAD(void *ptr); + +struct Data { + int number; + char character; +}; + +int main() { + struct Data arr[10] = {}; + for (int i = 0; i < 10; ++i) { + SAFE_LOAD(&arr[i].number); + SAFE_LOAD(&arr[i].character); + } +} diff --git a/src/ae_nullptr_deref_tests/safe_array_of_struct_2.c b/src/ae_nullptr_deref_tests/safe_array_of_struct_2.c new file mode 100644 index 00000000..20af8f4f --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_array_of_struct_2.c @@ -0,0 +1,16 @@ +#include + +extern void SAFE_LOAD(void *ptr); + +struct Data { + int *number; + char character; +}; + +int main() { + struct Data arr[10] = {}; + for (int i = 0; i < 10; ++i) { + *(arr[i].number) = 0; + SAFE_LOAD(&arr[i].number); + } +} diff --git a/src/ae_nullptr_deref_tests/safe_double_ptr.c b/src/ae_nullptr_deref_tests/safe_double_ptr.c new file mode 100644 index 00000000..a2f51ee9 --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_double_ptr.c @@ -0,0 +1,11 @@ +#include + +extern void SAFE_LOAD(void *ptr); + +int main() { + int **dp = malloc(sizeof(int *)); + *dp = malloc(sizeof(int)); + **dp = 1; + SAFE_LOAD(dp); + SAFE_LOAD(*dp); +} diff --git a/src/ae_nullptr_deref_tests/safe_func_arg.c b/src/ae_nullptr_deref_tests/safe_func_arg.c new file mode 100644 index 00000000..09230660 --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_func_arg.c @@ -0,0 +1,13 @@ +#include + +extern void SAFE_LOAD(void *ptr); + +void foo(int *a) { + SAFE_LOAD(a); +} + +int main() { + int* p = malloc(sizeof(int)); + *p = 1; + foo(p); +} diff --git a/src/ae_nullptr_deref_tests/safe_func_ptr.c b/src/ae_nullptr_deref_tests/safe_func_ptr.c new file mode 100644 index 00000000..22384935 --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_func_ptr.c @@ -0,0 +1,14 @@ +#include + +void testFunction() { + printf("Test function called\n"); +} + +int main() { + void (*funcPtr)(); + funcPtr = testFunction; + SAFE_LOAD(&funcPtr); + funcPtr(); + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/safe_func_return.c b/src/ae_nullptr_deref_tests/safe_func_return.c new file mode 100644 index 00000000..b7fd8e18 --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_func_return.c @@ -0,0 +1,14 @@ +#include + +extern void SAFE_LOAD(void *ptr); + +int *foo() { + int* p = malloc(sizeof(int)); + *p = 1; + return p; +} + +int main() { + int *myPtr = foo(); + SAFE_LOAD(myPtr); +} diff --git a/src/ae_nullptr_deref_tests/safe_pointer_access.c b/src/ae_nullptr_deref_tests/safe_pointer_access.c new file mode 100644 index 00000000..f455753b --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_pointer_access.c @@ -0,0 +1,9 @@ +#include + +extern void SAFE_LOAD(void *ptr); + +int main() { + int* p = malloc(sizeof(int)); + *p = 1; + SAFE_LOAD(p); +} diff --git a/src/ae_nullptr_deref_tests/safe_ptr_array_access.c b/src/ae_nullptr_deref_tests/safe_ptr_array_access.c new file mode 100644 index 00000000..29e4f2de --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_ptr_array_access.c @@ -0,0 +1,15 @@ +#include + +extern void SAFE_LOAD(void *ptr); + +int main() { + int *n = malloc(sizeof(int)); + *n = 0; + int *ptrs[5] = {n, n, n, n, n}; + for (int i = 0; i < 5; i++) { + SAFE_LOAD(ptrs[i]); + *ptrs[i] = 1; + } + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/safe_ptr_assign.c b/src/ae_nullptr_deref_tests/safe_ptr_assign.c new file mode 100644 index 00000000..6b223a6a --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_ptr_assign.c @@ -0,0 +1,18 @@ +// +// Created by Ethan Lin on 21/10/2024. +// +#include + +extern void SAFE_LOAD(void *p); +extern void UNSAFE_LOAD(void *p); + +int main() { + int x = 6; + int *myPtr2; + myPtr2 = &x; + SAFE_LOAD(myPtr2); + *myPtr2 = 5; + + return 0; +} + diff --git a/src/ae_nullptr_deref_tests/safe_single_array_access.c b/src/ae_nullptr_deref_tests/safe_single_array_access.c new file mode 100644 index 00000000..e94330fa --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_single_array_access.c @@ -0,0 +1,8 @@ +#include + +extern void SAFE_LOAD(void *ptr); + +int main() { + int arr[1] = {0}; + SAFE_LOAD(arr); +} diff --git a/src/ae_nullptr_deref_tests/safe_struct_access.c b/src/ae_nullptr_deref_tests/safe_struct_access.c new file mode 100644 index 00000000..6404acae --- /dev/null +++ b/src/ae_nullptr_deref_tests/safe_struct_access.c @@ -0,0 +1,20 @@ +#include + +extern void SAFE_LOAD(void *ptr); + +struct Data { + int number; + char character; +}; + +int main() { + struct Data *dataPtr = malloc(sizeof(struct Data)); + + dataPtr->number = 0; + dataPtr->character = 'a'; + + SAFE_LOAD(&dataPtr->number); + SAFE_LOAD(&dataPtr->character); + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/struct_func_ptr_1.c b/src/ae_nullptr_deref_tests/struct_func_ptr_1.c new file mode 100644 index 00000000..a69d268a --- /dev/null +++ b/src/ae_nullptr_deref_tests/struct_func_ptr_1.c @@ -0,0 +1,13 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +struct Operations { + void (*op_function)(int); // function ptr +}; + +int main() { + struct Operations ops; + ops.op_function = NULL; + UNSAFE_LOAD(ops.op_function); // Triggers a null pointer dereference +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/struct_func_ptr_2.c b/src/ae_nullptr_deref_tests/struct_func_ptr_2.c new file mode 100644 index 00000000..f67b1553 --- /dev/null +++ b/src/ae_nullptr_deref_tests/struct_func_ptr_2.c @@ -0,0 +1,12 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +struct Operations { + void (*op_function)(int); // function ptr +}; + +int main() { + struct Operations *ops = NULL; + UNSAFE_LOAD(&ops->op_function); // Triggers a null pointer dereference +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests/struct_nullptr.c b/src/ae_nullptr_deref_tests/struct_nullptr.c new file mode 100644 index 00000000..e3865283 --- /dev/null +++ b/src/ae_nullptr_deref_tests/struct_nullptr.c @@ -0,0 +1,17 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +struct Data { + int number; + char character; +}; + +int main() { + struct Data *dataPtr = NULL; + + UNSAFE_LOAD(&dataPtr->number); // Accessing a member of the structure via NULL pointer + UNSAFE_LOAD(&dataPtr->character); + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/struct_uninit_struct.c b/src/ae_nullptr_deref_tests/struct_uninit_struct.c new file mode 100644 index 00000000..1e833a1c --- /dev/null +++ b/src/ae_nullptr_deref_tests/struct_uninit_struct.c @@ -0,0 +1,17 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +struct Data { + int number; + char character; +}; + +int main() { + struct Data *dataPtr; + + UNSAFE_LOAD(&dataPtr->number); // Accessing a member of the structure via NULL pointer + UNSAFE_LOAD(&dataPtr->character); + + return 0; +} diff --git a/src/ae_nullptr_deref_tests/union_nullptr_member.c b/src/ae_nullptr_deref_tests/union_nullptr_member.c new file mode 100644 index 00000000..f770ca8b --- /dev/null +++ b/src/ae_nullptr_deref_tests/union_nullptr_member.c @@ -0,0 +1,16 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +union Data { + int* int_ptr; + float* float_ptr; +}; + +int main() { + union Data data; + data.int_ptr = NULL; + UNSAFE_LOAD(data.int_ptr); // This will trigger a null pointer dereference + + return 0; +} diff --git a/src/ae_nullptr_deref_tests_failed/array_2d_big_partial_null.c b/src/ae_nullptr_deref_tests_failed/array_2d_big_partial_null.c new file mode 100644 index 00000000..52828014 --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/array_2d_big_partial_null.c @@ -0,0 +1,33 @@ +#include +#include + +extern void SAFE_LOAD(void *ptr); +extern void UNSAFE_LOAD(void *ptr); + +#define SIZE 100 + +int main() { + int *arr[SIZE][SIZE]; + + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + if (j < SIZE / 2) { + arr[i][j] = NULL; + } else { + arr[i][j] = malloc(sizeof(int)); + *arr[i][j] = 1024; + } + } + } + + for (int m = 0; m < SIZE; m++) { + for (int n = 0; n < SIZE; n++) { + if (n < SIZE / 2) + UNSAFE_LOAD(arr[m][n]); + else + SAFE_LOAD(arr[m][n]); + } + } + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests_failed/array_of_struct_func_ptr.c b/src/ae_nullptr_deref_tests_failed/array_of_struct_func_ptr.c new file mode 100644 index 00000000..332c0111 --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/array_of_struct_func_ptr.c @@ -0,0 +1,27 @@ +#include +#include + +extern void SAFE_LOAD(void *ptr); +extern void UNSAFE_LOAD(void *ptr); + +struct S { + void (*funcPtr)(); +}; + +void foo() { + printf("This is a function\n"); +} + +int main() { + struct S arrStruct[3]; + + arrStruct[0].funcPtr = &foo; + + arrStruct[1].funcPtr = NULL; + + SAFE_LOAD(arrStruct[0].funcPtr); // malloc + UNSAFE_LOAD(arrStruct[1].funcPtr); // NULL + UNSAFE_LOAD(arrStruct[2].funcPtr); // uninitialized + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests_failed/array_partial_nullptr.c b/src/ae_nullptr_deref_tests_failed/array_partial_nullptr.c new file mode 100644 index 00000000..01b1b46f --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/array_partial_nullptr.c @@ -0,0 +1,21 @@ +#include +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + int *arr[5]; + arr[0] = malloc(sizeof(int)); + arr[1] = malloc(sizeof(int)); + arr[2] = malloc(sizeof(int)); + arr[3] = malloc(sizeof(int)); + + arr[4] = NULL; + + for (int i = 0; i < 5; i++) + { + UNSAFE_LOAD(arr[i]); + } + + return 0; +} diff --git a/src/ae_nullptr_deref_tests_failed/char_ptr_loop_branch_nullptr.c b/src/ae_nullptr_deref_tests_failed/char_ptr_loop_branch_nullptr.c new file mode 100644 index 00000000..42e508dd --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/char_ptr_loop_branch_nullptr.c @@ -0,0 +1,21 @@ +#include +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + char *p; + int i = 0; + while (i < 100) { + if (i == 50) { + p = NULL; + } + else { + p = malloc(sizeof(char)); + } + UNSAFE_LOAD(p); + i++; + } + + return 0; +} diff --git a/src/ae_nullptr_deref_tests_failed/int_ptr_loop_branch_nullptr.c b/src/ae_nullptr_deref_tests_failed/int_ptr_loop_branch_nullptr.c new file mode 100644 index 00000000..f0841109 --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/int_ptr_loop_branch_nullptr.c @@ -0,0 +1,21 @@ +#include +#include + +extern void UNSAFE_LOAD(void *ptr); + +int main() { + int *p; + int i = 0; + while (i < 100) { + if (i == 50) { + p = NULL; + } + else { + p = malloc(sizeof(int)); + } + UNSAFE_LOAD(p); + i++; + } + + return 0; +} diff --git a/src/ae_nullptr_deref_tests_failed/nullptr_func.c b/src/ae_nullptr_deref_tests_failed/nullptr_func.c new file mode 100644 index 00000000..4356bd7d --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/nullptr_func.c @@ -0,0 +1,8 @@ +#include +int main() { + void (*funcPtr)() = NULL; + + funcPtr(); // Attempting to call a function via a NULL function pointer + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests_failed/recursive_return_null.c b/src/ae_nullptr_deref_tests_failed/recursive_return_null.c new file mode 100644 index 00000000..cd74cfbb --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/recursive_return_null.c @@ -0,0 +1,21 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +int *recursive_function(int depth) { + if (depth > 0) { + // Do nothing and keep calling itself + recursive_function(depth - 1); + } else { + // Base case reached, dereferencing NULL pointer + return NULL; + } +} + +int main() { + int *intPtr = recursive_function(5); + + UNSAFE_LOAD(intPtr); + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests_failed/recursive_safe.c b/src/ae_nullptr_deref_tests_failed/recursive_safe.c new file mode 100644 index 00000000..93472eff --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/recursive_safe.c @@ -0,0 +1,22 @@ +#include + +extern void SAFE_LOAD(void *ptr); + +void recursive_function(void *ptr, int depth) { + if (depth > 0) { + // Do nothing and keep calling itself + recursive_function(ptr, depth - 1); + } else { + // Base case reached + SAFE_LOAD(ptr); + } +} + +int main() { + int *intPtr = malloc(sizeof(int)); + char *charPtr = malloc(sizeof(char)); + recursive_function(intPtr, 3); + recursive_function(charPtr, 3); + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests_failed/recursive_simple.c b/src/ae_nullptr_deref_tests_failed/recursive_simple.c new file mode 100644 index 00000000..3e22d4f2 --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/recursive_simple.c @@ -0,0 +1,22 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +void recursive_function(void *ptr, int depth) { + if (depth > 0) { + // Do nothing and keep calling itself + recursive_function(ptr, depth - 1); + } else { + // Base case reached, dereferencing NULL pointer + UNSAFE_LOAD(ptr); // This will trigger a null pointer dereference + } +} + +int main() { + int *intPtr = NULL; + char *charPtr = NULL; + recursive_function(intPtr, 3); + recursive_function(charPtr, 3); + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests_failed/recursive_simple_once.c b/src/ae_nullptr_deref_tests_failed/recursive_simple_once.c new file mode 100644 index 00000000..888323a6 --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/recursive_simple_once.c @@ -0,0 +1,22 @@ +#include + +extern void UNSAFE_LOAD(void *ptr); + +void recursive_function(void *ptr, int depth) { + if (depth > 0) { + // Do nothing and keep calling itself + recursive_function(ptr, depth - 1); + } else { + // Base case reached, dereferencing NULL pointer + UNSAFE_LOAD(ptr); // This will trigger a null pointer dereference + } +} + +int main() { + int *intPtr = NULL; + char *charPtr = NULL; + recursive_function(intPtr, 1); + recursive_function(charPtr, 1); + + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests_failed/recursive_struct.c b/src/ae_nullptr_deref_tests_failed/recursive_struct.c new file mode 100644 index 00000000..ff526257 --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/recursive_struct.c @@ -0,0 +1,35 @@ +#include +#include + +extern void UNSAFE_LOAD(void *ptr); + +struct S { + int *intPtr; + char *charPtr; + int64_t *int64Ptr; + wchar_t *wcharPtr; +}; + +void recursive_function(struct S s, int depth) { + if (depth > 0) { + // Do nothing and keep calling itself + recursive_function(s, depth - 1); + } else { + // Base case reached, dereferencing NULL pointer + UNSAFE_LOAD(s.intPtr); + UNSAFE_LOAD(s.charPtr); + UNSAFE_LOAD(s.int64Ptr); + UNSAFE_LOAD(s.wcharPtr); + } +} + +int main() { + struct S myStruct; + myStruct.intPtr = NULL; + myStruct.charPtr = NULL; + myStruct.int64Ptr = NULL; + myStruct.wcharPtr = NULL; + + recursive_function(myStruct, 3); + return 0; +} \ No newline at end of file diff --git a/src/ae_nullptr_deref_tests_failed/safe_loop_access.c b/src/ae_nullptr_deref_tests_failed/safe_loop_access.c new file mode 100644 index 00000000..e870a0be --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/safe_loop_access.c @@ -0,0 +1,27 @@ +#include +#include + +extern void SAFE_LOAD(void *ptr); + +#define LEN 3 + +int main() { + int *arr[LEN]; + + for (int i = 0; i < LEN; i++) + { + arr[i] = malloc(sizeof(int)); + if (arr[i] == NULL) { + printf("Memory allocation failed\n"); + return 1; + } + *arr[i] = 0; + } + + for (int j = 0; j < LEN; j++) + { + SAFE_LOAD(&arr[j]); + } + + return 0; +} diff --git a/src/ae_nullptr_deref_tests_failed/struct_func_ptr.c b/src/ae_nullptr_deref_tests_failed/struct_func_ptr.c new file mode 100644 index 00000000..007dad94 --- /dev/null +++ b/src/ae_nullptr_deref_tests_failed/struct_func_ptr.c @@ -0,0 +1,11 @@ +#include + +struct Operations { + void (*op_function)(int); // function ptr +}; + +int main() { + struct Operations ops; + ops.op_function = NULL; + ops.op_function(10); // Triggers a null pointer dereference +} \ No newline at end of file diff --git a/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__c_CWE680_int_overflow_01.c b/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__c_CWE680_int_overflow_01.c new file mode 100644 index 00000000..b6806041 --- /dev/null +++ b/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__c_CWE680_int_overflow_01.c @@ -0,0 +1,94 @@ +/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE680_int_overflow_01.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE680.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Set dataSize to a large value causing integer overflow + * GoodSource: Set dataSize to a small, safe value + * Sink: malloc + * BadSink : Allocate memory using malloc() and initialize it + * Flow Variant: 01 Baseline + * + * */ + +#include "std_testcase.h" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE680_int_overflow_01_bad() +{ + int * data; + int dataSize; + /* FLAW: Set dataSize to a value that will cause an integer overflow in malloc */ + dataSize = INT_MAX / sizeof(int) + 2; + /* POTENTIAL FLAW: dataSize * sizeof(int) may overflow to a small value */ + data = (int *)malloc(dataSize * sizeof(int)); + if (data == NULL) {exit(-1);} + { + size_t i; + /* POTENTIAL FLAW: May write beyond allocated memory if dataSize * sizeof(int) overflows */ + for (i = 0; i < (size_t)dataSize; i++) + { + data[i] = 0; + } + UNSAFE_BUFACCESS(data, dataSize * sizeof(int) - 1); + printIntLine(data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static void goodG2B() +{ + int * data; + int dataSize; + /* FIX: Set dataSize to a small, safe value */ + dataSize = 20; + data = (int *)malloc(dataSize * sizeof(int)); + if (data == NULL) {exit(-1);} + { + size_t i; + /* SAFE: dataSize is small and does not cause overflow */ + for (i = 0; i < (size_t)dataSize; i++) + { + data[i] = 0; + SAFE_BUFACCESS(data, i * sizeof(int)); + } + printIntLine(data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE680_int_overflow_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine("Calling good()..."); + CWE122_Heap_Based_Buffer_Overflow__c_CWE680_int_overflow_01_good(); + printLine("Finished good()"); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine("Calling bad()..."); + CWE122_Heap_Based_Buffer_Overflow__c_CWE680_int_overflow_01_bad(); + printLine("Finished bad()"); +#endif /* OMITBAD */ + return 0; +} + +#endif diff --git a/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_scanf_01.c b/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_scanf_01.c new file mode 100644 index 00000000..ee3cf828 --- /dev/null +++ b/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_scanf_01.c @@ -0,0 +1,85 @@ +/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_scanf_01.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate buffer of insufficient size + * GoodSource: Allocate buffer with sufficient size + * Sink: scanf + * BadSink : Read data from the console using scanf without limit + * Flow Variant: 01 Baseline + * + * */ + +#include "std_testcase.h" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_scanf_01_bad() +{ + char * data; + data = NULL; + /* FLAW: Allocate a small buffer */ + data = (char *)malloc(10 * sizeof(char)); + if (data == NULL) {exit(-1);} + /* POTENTIAL FLAW: Using scanf without specifying length limit */ + printLine("Enter a string:"); + scanf("%s", data); /* May cause buffer overflow */ + UNSAFE_BUFACCESS(data, strlen(data) * sizeof(char)); + printLine(data); + free(data); +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static void goodG2B() +{ + char * data; + data = NULL; + /* FIX: Allocate a larger buffer */ + data = (char *)malloc(100 * sizeof(char)); + if (data == NULL) {exit(-1);} + /* FIX: Use scanf with length limit */ + printLine("Enter a string:"); + scanf("%99s", data); /* Limits input to 99 characters */ + SAFE_BUFACCESS(data, 99 * sizeof(char)); + printLine(data); + free(data); +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_scanf_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is used when building this testcase on its own + * for testing or for building a binary to use in testing binary analysis tools. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine("Calling good()..."); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_scanf_01_good(); + printLine("Finished good()"); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine("Calling bad()..."); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_char_scanf_01_bad(); + printLine("Finished bad()"); +#endif /* OMITBAD */ + return 0; +} + +#endif diff --git a/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_01.c b/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_01.c new file mode 100644 index 00000000..2207c6cb --- /dev/null +++ b/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_01.c @@ -0,0 +1,106 @@ +/* TEMPLATE GENERATED TESTCASE FILE +Filename: CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_01.c +Label Definition File: CWE122_Heap_Based_Buffer_Overflow__c_CWE805.label.xml +Template File: sources-sink-01.tmpl.c +*/ +/* + * @description + * CWE: 122 Heap Based Buffer Overflow + * BadSource: Allocate buffer for fewer elements than needed + * GoodSource: Allocate buffer with sufficient elements + * Sink: loop + * BadSink : Copy struct array to data using a loop + * Flow Variant: 01 Baseline + * + * */ + +#include "std_testcase.h" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_01_bad() +{ + twoIntsStruct * data; + data = NULL; + /* FLAW: Allocate buffer for 5 elements */ + data = (twoIntsStruct *)malloc(5 * sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + { + twoIntsStruct source[10]; + size_t i; + /* Initialize source array */ + for (i = 0; i < 10; i++) + { + source[i].intOne = (int)i; + source[i].intTwo = (int)i; + } + /* POTENTIAL FLAW: Possible buffer overflow if data has fewer than 10 elements */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + if (i > 5) + UNSAFE_BUFACCESS(data, i * sizeof(twoIntsStruct)); + } + printStructLine(&data[0]); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static void goodG2B() +{ + twoIntsStruct * data; + data = NULL; + /* FIX: Allocate buffer for 10 elements */ + data = (twoIntsStruct *)malloc(10 * sizeof(twoIntsStruct)); + if (data == NULL) {exit(-1);} + { + twoIntsStruct source[10]; + size_t i; + /* Initialize source array */ + for (i = 0; i < 10; i++) + { + source[i].intOne = (int)i; + source[i].intTwo = (int)i; + } + /* SAFE: data has enough space for the copy operation */ + for (i = 0; i < 10; i++) + { + data[i] = source[i]; + SAFE_BUFACCESS(data, i * sizeof(twoIntsStruct)); + } + printStructLine(&data[0]); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine("Calling good()..."); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_01_good(); + printLine("Finished good()"); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine("Calling bad()..."); + CWE122_Heap_Based_Buffer_Overflow__c_CWE805_struct_loop_01_bad(); + printLine("Finished bad()"); +#endif /* OMITBAD */ + return 0; +} + +#endif diff --git a/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__realloc_01.c b/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__realloc_01.c new file mode 100644 index 00000000..2f32164f --- /dev/null +++ b/src/ae_overflow_tests/CWE122_Heap_Based_Buffer_Overflow__realloc_01.c @@ -0,0 +1,94 @@ +#include "std_testcase.h" + +#ifndef OMITBAD + +void CWE122_Heap_Based_Buffer_Overflow__realloc_01_bad() +{ + char * data; + data = NULL; + /* Allocate initial memory */ + data = (char *)malloc(100 * sizeof(char)); + if (data == NULL) {exit(-1);} + strcpy(data, "This is a long string that exceeds the reallocated buffer size."); + /* FLAW: Reallocate to a smaller buffer without checking */ + data = (char *)realloc(data, 50 * sizeof(char)); + if (data == NULL) {exit(-1);} + { + char dest[50] = ""; + size_t i; + /* POTENTIAL FLAW: Possible buffer overflow if data is larger than dest */ + for (i = 0; i < strlen(data); i++) + { + dest[i] = data[i]; + } + UNSAFE_BUFACCESS(dest, (strlen(data) - 1) * sizeof(char)); + dest[49] = '\0'; /* Ensure null termination */ + printLine(dest); + free(data); + } +} + +#endif /* OMITBAD */ + +#ifndef OMITGOOD + +static void goodG2B() +{ + char * data; + data = NULL; + /* Allocate initial memory */ + data = (char *)malloc(50 * sizeof(char)); + if (data == NULL) {exit(-1);} + strcpy(data, "Short string"); + /* FIX: Reallocate to a larger buffer if necessary */ + data = (char *)realloc(data, 100 * sizeof(char)); + if (data == NULL) {exit(-1);} + strcat(data, " with additional data that fits."); + { + char dest[100] = ""; + size_t i; + /* SAFE: Copy data to dest safely */ + for (i = 0; i < 99; i++) + { + dest[i] = data[i]; + SAFE_BUFACCESS(dest, i * sizeof(char)); + } + dest[99] = '\0'; /* Ensure null termination */ + printLine(dest); + free(data); + } +} + +void CWE122_Heap_Based_Buffer_Overflow__realloc_01_good() +{ + goodG2B(); +} + +#endif /* OMITGOOD */ + +/* Below is the main(). It is only used when building this testcase on + * its own for testing or for building a binary to use in testing binary + * analysis tools. It is not used when compiling all the testcases as one + * application, which is how source code analysis tools are tested. + */ + +#ifdef INCLUDEMAIN + +int main(int argc, char * argv[]) +{ + /* seed randomness */ + srand( (unsigned)time(NULL) ); +#ifndef OMITGOOD + printLine("Calling good()..."); + CWE122_Heap_Based_Buffer_Overflow__realloc_01_good(); + printLine("Finished good()"); +#endif /* OMITGOOD */ +#ifndef OMITBAD + printLine("Calling bad()..."); + CWE122_Heap_Based_Buffer_Overflow__realloc_01_bad(); + printLine("Finished bad()"); +#endif /* OMITBAD */ + return 0; +} + +#endif \ No newline at end of file diff --git a/test_cases_bc/ae_assert_tests/CVE-2022-27239-0.c.bc b/test_cases_bc/ae_assert_tests/CVE-2022-27239-0.c.bc deleted file mode 100644 index fff82fc4..00000000 --- a/test_cases_bc/ae_assert_tests/CVE-2022-27239-0.c.bc +++ /dev/null @@ -1,456 +0,0 @@ -; ModuleID = '/home/runner/work/Test-Suite/Test-Suite/test_cases_bc/ae_assert_tests/CVE-2022-27239-0.c.bc' -source_filename = "/home/runner/work/Test-Suite/Test-Suite/src/ae_assert_tests/CVE-2022-27239-0.c" -target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" - -%struct.parsed_mount_info = type { [45 x i8], i8, [2 x i8] } - -@.str = private unnamed_addr constant [28 x i8] c"parse opt token, token: %s\0A\00", align 1, !dbg !0 -@.str.1 = private unnamed_addr constant [3 x i8] c"ip\00", align 1, !dbg !7 -@.str.2 = private unnamed_addr constant [5 x i8] c"addr\00", align 1, !dbg !12 -@.str.3 = private unnamed_addr constant [25 x i8] c"parse option, buffer:%s\0A\00", align 1, !dbg !17 -@.str.4 = private unnamed_addr constant [2 x i8] c",\00", align 1, !dbg !22 -@stderr = external global ptr, align 8 -@.str.5 = private unnamed_addr constant [34 x i8] c"ip address %s override specified\0A\00", align 1, !dbg !27 -@.str.6 = private unnamed_addr constant [74 x i8] c"keyword,ip=VapodinGmVAFzAbsPWGkWdPQI2gozcQulsHW1hJRsyVlaZ,keyword3=value3\00", align 1, !dbg !32 - -; Function Attrs: noinline nounwind optnone uwtable -define dso_local i32 @parse_opt_token(ptr noundef %token) #0 !dbg !50 { -entry: - %retval = alloca i32, align 4 - %token.addr = alloca ptr, align 8 - store ptr %token, ptr %token.addr, align 8 - call void @llvm.dbg.declare(metadata ptr %token.addr, metadata !57, metadata !DIExpression()), !dbg !58 - %0 = load ptr, ptr %token.addr, align 8, !dbg !59 - %call = call i32 (ptr, ...) @printf(ptr noundef @.str, ptr noundef %0), !dbg !60 - %1 = load ptr, ptr %token.addr, align 8, !dbg !61 - %cmp = icmp eq ptr %1, null, !dbg !63 - br i1 %cmp, label %if.then, label %if.end, !dbg !64 - -if.then: ; preds = %entry - store i32 -1, ptr %retval, align 4, !dbg !65 - br label %return, !dbg !65 - -if.end: ; preds = %entry - %2 = load ptr, ptr %token.addr, align 8, !dbg !66 - %call1 = call i32 @strcmp(ptr noundef %2, ptr noundef @.str.1) #7, !dbg !68 - %cmp2 = icmp eq i32 %call1, 0, !dbg !69 - br i1 %cmp2, label %if.then5, label %lor.lhs.false, !dbg !70 - -lor.lhs.false: ; preds = %if.end - %3 = load ptr, ptr %token.addr, align 8, !dbg !71 - %call3 = call i32 @strcmp(ptr noundef %3, ptr noundef @.str.2) #7, !dbg !72 - %cmp4 = icmp eq i32 %call3, 0, !dbg !73 - br i1 %cmp4, label %if.then5, label %if.end6, !dbg !74 - -if.then5: ; preds = %lor.lhs.false, %if.end - store i32 6, ptr %retval, align 4, !dbg !75 - br label %return, !dbg !75 - -if.end6: ; preds = %lor.lhs.false - store i32 -1, ptr %retval, align 4, !dbg !76 - br label %return, !dbg !76 - -return: ; preds = %if.end6, %if.then5, %if.then - %4 = load i32, ptr %retval, align 4, !dbg !77 - ret i32 %4, !dbg !77 -} - -; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - -declare i32 @printf(ptr noundef, ...) #2 - -; Function Attrs: nounwind willreturn memory(read) -declare i32 @strcmp(ptr noundef, ptr noundef) #3 - -; Function Attrs: noinline nounwind optnone uwtable -define dso_local i32 @parse_options(ptr noundef %data, ptr noundef %parsed_info) #0 !dbg !78 { -entry: - %retval = alloca i32, align 4 - %data.addr = alloca ptr, align 8 - %parsed_info.addr = alloca ptr, align 8 - %value = alloca ptr, align 8 - %equals = alloca ptr, align 8 - %next_keyword = alloca ptr, align 8 - %saved_stack = alloca ptr, align 8 - %__vla_expr0 = alloca i64, align 8 - %token = alloca ptr, align 8 - store ptr %data, ptr %data.addr, align 8 - call void @llvm.dbg.declare(metadata ptr %data.addr, metadata !90, metadata !DIExpression()), !dbg !91 - store ptr %parsed_info, ptr %parsed_info.addr, align 8 - call void @llvm.dbg.declare(metadata ptr %parsed_info.addr, metadata !92, metadata !DIExpression()), !dbg !93 - call void @llvm.dbg.declare(metadata ptr %value, metadata !94, metadata !DIExpression()), !dbg !96 - %0 = load ptr, ptr %data.addr, align 8, !dbg !97 - %call = call i64 @strlen(ptr noundef %0) #7, !dbg !98 - %add = add i64 %call, 1, !dbg !99 - %call1 = call noalias ptr @malloc(i64 noundef %add) #8, !dbg !100 - store ptr %call1, ptr %value, align 8, !dbg !96 - call void @llvm.dbg.declare(metadata ptr %equals, metadata !101, metadata !DIExpression()), !dbg !102 - %1 = load ptr, ptr %data.addr, align 8, !dbg !103 - %call2 = call i64 @strlen(ptr noundef %1) #7, !dbg !104 - %add3 = add i64 %call2, 1, !dbg !105 - %call4 = call noalias ptr @malloc(i64 noundef %add3) #8, !dbg !106 - store ptr %call4, ptr %equals, align 8, !dbg !102 - call void @llvm.dbg.declare(metadata ptr %next_keyword, metadata !107, metadata !DIExpression()), !dbg !108 - %2 = load ptr, ptr %data.addr, align 8, !dbg !109 - %call5 = call i64 @strlen(ptr noundef %2) #7, !dbg !110 - %add6 = add i64 %call5, 1, !dbg !111 - %call7 = call noalias ptr @malloc(i64 noundef %add6) #8, !dbg !112 - store ptr %call7, ptr %next_keyword, align 8, !dbg !108 - %3 = load ptr, ptr %data.addr, align 8, !dbg !113 - %tobool = icmp ne ptr %3, null, !dbg !113 - br i1 %tobool, label %if.end, label %if.then, !dbg !115 - -if.then: ; preds = %entry - store i32 1, ptr %retval, align 4, !dbg !116 - br label %return, !dbg !116 - -if.end: ; preds = %entry - %4 = load ptr, ptr %data.addr, align 8, !dbg !117 - %call8 = call i64 @strlen(ptr noundef %4) #7, !dbg !118 - %add9 = add i64 %call8, 1, !dbg !119 - %5 = call ptr @llvm.stacksave(), !dbg !120 - store ptr %5, ptr %saved_stack, align 8, !dbg !120 - %vla = alloca i8, i64 %add9, align 16, !dbg !120 - store i64 %add9, ptr %__vla_expr0, align 8, !dbg !120 - call void @llvm.dbg.declare(metadata ptr %__vla_expr0, metadata !121, metadata !DIExpression()), !dbg !123 - call void @llvm.dbg.declare(metadata ptr %vla, metadata !124, metadata !DIExpression()), !dbg !128 - %6 = load ptr, ptr %data.addr, align 8, !dbg !129 - %call10 = call ptr @strcpy(ptr noundef %vla, ptr noundef %6) #9, !dbg !130 - %call11 = call i32 (ptr, ...) @printf(ptr noundef @.str.3, ptr noundef %vla), !dbg !131 - call void @llvm.dbg.declare(metadata ptr %token, metadata !132, metadata !DIExpression()), !dbg !133 - %call12 = call ptr @strtok(ptr noundef %vla, ptr noundef @.str.4) #9, !dbg !134 - store ptr %call12, ptr %token, align 8, !dbg !133 - br label %while.cond, !dbg !135 - -while.cond: ; preds = %if.end31, %if.end - %7 = load ptr, ptr %token, align 8, !dbg !136 - %cmp = icmp ne ptr %7, null, !dbg !137 - br i1 %cmp, label %while.body, label %while.end, !dbg !135 - -while.body: ; preds = %while.cond - %8 = load ptr, ptr %next_keyword, align 8, !dbg !138 - %9 = load ptr, ptr %token, align 8, !dbg !140 - %call13 = call ptr @strcpy(ptr noundef %8, ptr noundef %9) #9, !dbg !141 - store ptr null, ptr %value, align 8, !dbg !142 - %10 = load ptr, ptr %next_keyword, align 8, !dbg !143 - %call14 = call ptr @strchr(ptr noundef %10, i32 noundef 61) #7, !dbg !145 - store ptr %call14, ptr %equals, align 8, !dbg !146 - %cmp15 = icmp ne ptr %call14, null, !dbg !147 - br i1 %cmp15, label %if.then16, label %if.end17, !dbg !148 - -if.then16: ; preds = %while.body - %11 = load ptr, ptr %equals, align 8, !dbg !149 - store i8 0, ptr %11, align 1, !dbg !151 - %12 = load ptr, ptr %equals, align 8, !dbg !152 - %add.ptr = getelementptr inbounds i8, ptr %12, i64 1, !dbg !153 - store ptr %add.ptr, ptr %value, align 8, !dbg !154 - br label %if.end17, !dbg !155 - -if.end17: ; preds = %if.then16, %while.body - %13 = load ptr, ptr %value, align 8, !dbg !156 - %tobool18 = icmp ne ptr %13, null, !dbg !156 - br i1 %tobool18, label %land.lhs.true, label %if.end31, !dbg !158 - -land.lhs.true: ; preds = %if.end17 - %14 = load ptr, ptr %next_keyword, align 8, !dbg !159 - %call19 = call i32 @parse_opt_token(ptr noundef %14), !dbg !160 - %cmp20 = icmp eq i32 %call19, 6, !dbg !161 - br i1 %cmp20, label %if.then21, label %if.end31, !dbg !162 - -if.then21: ; preds = %land.lhs.true - %15 = load ptr, ptr %value, align 8, !dbg !163 - %call22 = call i64 @strnlen(ptr noundef %15, i64 noundef 46) #7, !dbg !166 - %cmp23 = icmp ule i64 %call22, 46, !dbg !167 - br i1 %cmp23, label %if.then24, label %if.end30, !dbg !168 - -if.then24: ; preds = %if.then21 - %16 = load ptr, ptr %parsed_info.addr, align 8, !dbg !169 - %addrlist = getelementptr inbounds %struct.parsed_mount_info, ptr %16, i32 0, i32 0, !dbg !171 - %arraydecay = getelementptr inbounds [45 x i8], ptr %addrlist, i64 0, i64 0, !dbg !169 - %17 = load ptr, ptr %value, align 8, !dbg !172 - %call25 = call ptr @strcpy(ptr noundef %arraydecay, ptr noundef %17) #9, !dbg !173 - %18 = load ptr, ptr %parsed_info.addr, align 8, !dbg !174 - %verboseflag = getelementptr inbounds %struct.parsed_mount_info, ptr %18, i32 0, i32 1, !dbg !176 - %bf.load = load i8, ptr %verboseflag, align 1, !dbg !176 - %bf.clear = and i8 %bf.load, 1, !dbg !176 - %bf.cast = zext i8 %bf.clear to i32, !dbg !176 - %tobool26 = icmp ne i32 %bf.cast, 0, !dbg !174 - br i1 %tobool26, label %if.then27, label %if.end29, !dbg !177 - -if.then27: ; preds = %if.then24 - %19 = load ptr, ptr @stderr, align 8, !dbg !178 - %20 = load ptr, ptr %value, align 8, !dbg !179 - %call28 = call i32 (ptr, ptr, ...) @fprintf(ptr noundef %19, ptr noundef @.str.5, ptr noundef %20), !dbg !180 - br label %if.end29, !dbg !180 - -if.end29: ; preds = %if.then27, %if.then24 - br label %if.end30, !dbg !181 - -if.end30: ; preds = %if.end29, %if.then21 - br label %if.end31, !dbg !182 - -if.end31: ; preds = %if.end30, %land.lhs.true, %if.end17 - %call32 = call ptr @strtok(ptr noundef null, ptr noundef @.str.4) #9, !dbg !183 - store ptr %call32, ptr %token, align 8, !dbg !184 - br label %while.cond, !dbg !135, !llvm.loop !185 - -while.end: ; preds = %while.cond - store i32 0, ptr %retval, align 4, !dbg !188 - %21 = load ptr, ptr %saved_stack, align 8, !dbg !189 - call void @llvm.stackrestore(ptr %21), !dbg !189 - br label %return - -return: ; preds = %while.end, %if.then - %22 = load i32, ptr %retval, align 4, !dbg !189 - ret i32 %22, !dbg !189 -} - -; Function Attrs: nounwind allocsize(0) -declare noalias ptr @malloc(i64 noundef) #4 - -; Function Attrs: nounwind willreturn memory(read) -declare i64 @strlen(ptr noundef) #3 - -; Function Attrs: nocallback nofree nosync nounwind willreturn -declare ptr @llvm.stacksave() #5 - -; Function Attrs: nounwind -declare ptr @strcpy(ptr noundef, ptr noundef) #6 - -; Function Attrs: nounwind -declare ptr @strtok(ptr noundef, ptr noundef) #6 - -; Function Attrs: nounwind willreturn memory(read) -declare ptr @strchr(ptr noundef, i32 noundef) #3 - -; Function Attrs: nounwind willreturn memory(read) -declare i64 @strnlen(ptr noundef, i64 noundef) #3 - -declare i32 @fprintf(ptr noundef, ptr noundef, ...) #2 - -; Function Attrs: nocallback nofree nosync nounwind willreturn -declare void @llvm.stackrestore(ptr) #5 - -; Function Attrs: noinline nounwind optnone uwtable -define dso_local i32 @main() #0 !dbg !190 { -entry: - %parsed_info = alloca %struct.parsed_mount_info, align 4 - call void @llvm.dbg.declare(metadata ptr %parsed_info, metadata !193, metadata !DIExpression()), !dbg !194 - %call = call i32 @parse_options(ptr noundef @.str.6, ptr noundef %parsed_info), !dbg !195 - ret i32 0, !dbg !196 -} - -attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } -attributes #2 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #3 = { nounwind willreturn memory(read) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #4 = { nounwind allocsize(0) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #5 = { nocallback nofree nosync nounwind willreturn } -attributes #6 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #7 = { nounwind willreturn memory(read) } -attributes #8 = { nounwind allocsize(0) } -attributes #9 = { nounwind } - -!llvm.dbg.cu = !{!37} -!llvm.module.flags = !{!42, !43, !44, !45, !46, !47, !48} -!llvm.ident = !{!49} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(scope: null, file: !2, line: 23, type: !3, isLocal: true, isDefinition: true) -!2 = !DIFile(filename: "src/ae_assert_tests/CVE-2022-27239-0.c", directory: "/home/runner/work/Test-Suite/Test-Suite", checksumkind: CSK_MD5, checksum: "87345d07ce6c01618dd80423f5b6b0b5") -!3 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 224, elements: !5) -!4 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -!5 = !{!6} -!6 = !DISubrange(count: 28) -!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression()) -!8 = distinct !DIGlobalVariable(scope: null, file: !2, line: 31, type: !9, isLocal: true, isDefinition: true) -!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 24, elements: !10) -!10 = !{!11} -!11 = !DISubrange(count: 3) -!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression()) -!13 = distinct !DIGlobalVariable(scope: null, file: !2, line: 31, type: !14, isLocal: true, isDefinition: true) -!14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 40, elements: !15) -!15 = !{!16} -!16 = !DISubrange(count: 5) -!17 = !DIGlobalVariableExpression(var: !18, expr: !DIExpression()) -!18 = distinct !DIGlobalVariable(scope: null, file: !2, line: 48, type: !19, isLocal: true, isDefinition: true) -!19 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 200, elements: !20) -!20 = !{!21} -!21 = !DISubrange(count: 25) -!22 = !DIGlobalVariableExpression(var: !23, expr: !DIExpression()) -!23 = distinct !DIGlobalVariable(scope: null, file: !2, line: 49, type: !24, isLocal: true, isDefinition: true) -!24 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 16, elements: !25) -!25 = !{!26} -!26 = !DISubrange(count: 2) -!27 = !DIGlobalVariableExpression(var: !28, expr: !DIExpression()) -!28 = distinct !DIGlobalVariable(scope: null, file: !2, line: 66, type: !29, isLocal: true, isDefinition: true) -!29 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 272, elements: !30) -!30 = !{!31} -!31 = !DISubrange(count: 34) -!32 = !DIGlobalVariableExpression(var: !33, expr: !DIExpression()) -!33 = distinct !DIGlobalVariable(scope: null, file: !2, line: 78, type: !34, isLocal: true, isDefinition: true) -!34 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 592, elements: !35) -!35 = !{!36} -!36 = !DISubrange(count: 74) -!37 = distinct !DICompileUnit(language: DW_LANG_C11, file: !38, producer: "clang version 16.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !39, globals: !41, splitDebugInlining: false, nameTableKind: None) -!38 = !DIFile(filename: "/home/runner/work/Test-Suite/Test-Suite/src/ae_assert_tests/CVE-2022-27239-0.c", directory: "/home/runner/work/Test-Suite/Test-Suite", checksumkind: CSK_MD5, checksum: "87345d07ce6c01618dd80423f5b6b0b5") -!39 = !{!40} -!40 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) -!41 = !{!0, !7, !12, !17, !22, !27, !32} -!42 = !{i32 7, !"Dwarf Version", i32 5} -!43 = !{i32 2, !"Debug Info Version", i32 3} -!44 = !{i32 1, !"wchar_size", i32 4} -!45 = !{i32 8, !"PIC Level", i32 2} -!46 = !{i32 7, !"PIE Level", i32 2} -!47 = !{i32 7, !"uwtable", i32 2} -!48 = !{i32 7, !"frame-pointer", i32 2} -!49 = !{!"clang version 16.0.0"} -!50 = distinct !DISubprogram(name: "parse_opt_token", scope: !2, file: !2, line: 22, type: !51, scopeLine: 22, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !56) -!51 = !DISubroutineType(types: !52) -!52 = !{!53, !54} -!53 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!54 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !55, size: 64) -!55 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !4) -!56 = !{} -!57 = !DILocalVariable(name: "token", arg: 1, scope: !50, file: !2, line: 22, type: !54) -!58 = !DILocation(line: 22, column: 33, scope: !50) -!59 = !DILocation(line: 23, column: 44, scope: !50) -!60 = !DILocation(line: 23, column: 5, scope: !50) -!61 = !DILocation(line: 24, column: 6, scope: !62) -!62 = distinct !DILexicalBlock(scope: !50, file: !2, line: 24, column: 6) -!63 = !DILocation(line: 24, column: 12, scope: !62) -!64 = !DILocation(line: 24, column: 6, scope: !50) -!65 = !DILocation(line: 25, column: 3, scope: !62) -!66 = !DILocation(line: 31, column: 13, scope: !67) -!67 = distinct !DILexicalBlock(scope: !50, file: !2, line: 31, column: 6) -!68 = !DILocation(line: 31, column: 6, scope: !67) -!69 = !DILocation(line: 31, column: 26, scope: !67) -!70 = !DILocation(line: 31, column: 31, scope: !67) -!71 = !DILocation(line: 31, column: 41, scope: !67) -!72 = !DILocation(line: 31, column: 34, scope: !67) -!73 = !DILocation(line: 31, column: 56, scope: !67) -!74 = !DILocation(line: 31, column: 6, scope: !50) -!75 = !DILocation(line: 32, column: 3, scope: !67) -!76 = !DILocation(line: 34, column: 2, scope: !50) -!77 = !DILocation(line: 35, column: 1, scope: !50) -!78 = distinct !DISubprogram(name: "parse_options", scope: !2, file: !2, line: 38, type: !79, scopeLine: 38, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !56) -!79 = !DISubroutineType(types: !80) -!80 = !{!53, !54, !81} -!81 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !82, size: 64) -!82 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "parsed_mount_info", file: !2, line: 17, size: 384, elements: !83) -!83 = !{!84, !88} -!84 = !DIDerivedType(tag: DW_TAG_member, name: "addrlist", scope: !82, file: !2, line: 18, baseType: !85, size: 360) -!85 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 360, elements: !86) -!86 = !{!87} -!87 = !DISubrange(count: 45) -!88 = !DIDerivedType(tag: DW_TAG_member, name: "verboseflag", scope: !82, file: !2, line: 19, baseType: !89, size: 1, offset: 360, flags: DIFlagBitField, extraData: i64 360) -!89 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) -!90 = !DILocalVariable(name: "data", arg: 1, scope: !78, file: !2, line: 38, type: !54) -!91 = !DILocation(line: 38, column: 31, scope: !78) -!92 = !DILocalVariable(name: "parsed_info", arg: 2, scope: !78, file: !2, line: 38, type: !81) -!93 = !DILocation(line: 38, column: 63, scope: !78) -!94 = !DILocalVariable(name: "value", scope: !78, file: !2, line: 39, type: !95) -!95 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64) -!96 = !DILocation(line: 39, column: 8, scope: !78) -!97 = !DILocation(line: 39, column: 30, scope: !78) -!98 = !DILocation(line: 39, column: 23, scope: !78) -!99 = !DILocation(line: 39, column: 36, scope: !78) -!100 = !DILocation(line: 39, column: 16, scope: !78) -!101 = !DILocalVariable(name: "equals", scope: !78, file: !2, line: 40, type: !95) -!102 = !DILocation(line: 40, column: 8, scope: !78) -!103 = !DILocation(line: 40, column: 31, scope: !78) -!104 = !DILocation(line: 40, column: 24, scope: !78) -!105 = !DILocation(line: 40, column: 37, scope: !78) -!106 = !DILocation(line: 40, column: 17, scope: !78) -!107 = !DILocalVariable(name: "next_keyword", scope: !78, file: !2, line: 41, type: !95) -!108 = !DILocation(line: 41, column: 8, scope: !78) -!109 = !DILocation(line: 41, column: 37, scope: !78) -!110 = !DILocation(line: 41, column: 30, scope: !78) -!111 = !DILocation(line: 41, column: 43, scope: !78) -!112 = !DILocation(line: 41, column: 23, scope: !78) -!113 = !DILocation(line: 43, column: 7, scope: !114) -!114 = distinct !DILexicalBlock(scope: !78, file: !2, line: 43, column: 6) -!115 = !DILocation(line: 43, column: 6, scope: !78) -!116 = !DILocation(line: 44, column: 3, scope: !114) -!117 = !DILocation(line: 46, column: 24, scope: !78) -!118 = !DILocation(line: 46, column: 17, scope: !78) -!119 = !DILocation(line: 46, column: 30, scope: !78) -!120 = !DILocation(line: 46, column: 5, scope: !78) -!121 = !DILocalVariable(name: "__vla_expr0", scope: !78, type: !122, flags: DIFlagArtificial) -!122 = !DIBasicType(name: "unsigned long", size: 64, encoding: DW_ATE_unsigned) -!123 = !DILocation(line: 0, scope: !78) -!124 = !DILocalVariable(name: "buffer", scope: !78, file: !2, line: 46, type: !125) -!125 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, elements: !126) -!126 = !{!127} -!127 = !DISubrange(count: !121) -!128 = !DILocation(line: 46, column: 10, scope: !78) -!129 = !DILocation(line: 47, column: 20, scope: !78) -!130 = !DILocation(line: 47, column: 5, scope: !78) -!131 = !DILocation(line: 48, column: 5, scope: !78) -!132 = !DILocalVariable(name: "token", scope: !78, file: !2, line: 49, type: !95) -!133 = !DILocation(line: 49, column: 11, scope: !78) -!134 = !DILocation(line: 49, column: 19, scope: !78) -!135 = !DILocation(line: 50, column: 5, scope: !78) -!136 = !DILocation(line: 50, column: 11, scope: !78) -!137 = !DILocation(line: 50, column: 17, scope: !78) -!138 = !DILocation(line: 51, column: 16, scope: !139) -!139 = distinct !DILexicalBlock(scope: !78, file: !2, line: 50, column: 26) -!140 = !DILocation(line: 51, column: 30, scope: !139) -!141 = !DILocation(line: 51, column: 9, scope: !139) -!142 = !DILocation(line: 54, column: 15, scope: !139) -!143 = !DILocation(line: 55, column: 24, scope: !144) -!144 = distinct !DILexicalBlock(scope: !139, file: !2, line: 55, column: 7) -!145 = !DILocation(line: 55, column: 17, scope: !144) -!146 = !DILocation(line: 55, column: 15, scope: !144) -!147 = !DILocation(line: 55, column: 44, scope: !144) -!148 = !DILocation(line: 55, column: 7, scope: !139) -!149 = !DILocation(line: 56, column: 5, scope: !150) -!150 = distinct !DILexicalBlock(scope: !144, file: !2, line: 55, column: 53) -!151 = !DILocation(line: 56, column: 12, scope: !150) -!152 = !DILocation(line: 57, column: 12, scope: !150) -!153 = !DILocation(line: 57, column: 19, scope: !150) -!154 = !DILocation(line: 57, column: 10, scope: !150) -!155 = !DILocation(line: 58, column: 3, scope: !150) -!156 = !DILocation(line: 60, column: 12, scope: !157) -!157 = distinct !DILexicalBlock(scope: !139, file: !2, line: 60, column: 12) -!158 = !DILocation(line: 60, column: 18, scope: !157) -!159 = !DILocation(line: 60, column: 37, scope: !157) -!160 = !DILocation(line: 60, column: 21, scope: !157) -!161 = !DILocation(line: 60, column: 51, scope: !157) -!162 = !DILocation(line: 60, column: 12, scope: !139) -!163 = !DILocation(line: 61, column: 16, scope: !164) -!164 = distinct !DILexicalBlock(scope: !165, file: !2, line: 61, column: 8) -!165 = distinct !DILexicalBlock(scope: !157, file: !2, line: 60, column: 62) -!166 = !DILocation(line: 61, column: 8, scope: !164) -!167 = !DILocation(line: 61, column: 40, scope: !164) -!168 = !DILocation(line: 61, column: 8, scope: !165) -!169 = !DILocation(line: 64, column: 12, scope: !170) -!170 = distinct !DILexicalBlock(scope: !164, file: !2, line: 61, column: 60) -!171 = !DILocation(line: 64, column: 25, scope: !170) -!172 = !DILocation(line: 64, column: 35, scope: !170) -!173 = !DILocation(line: 64, column: 5, scope: !170) -!174 = !DILocation(line: 65, column: 9, scope: !175) -!175 = distinct !DILexicalBlock(scope: !170, file: !2, line: 65, column: 9) -!176 = !DILocation(line: 65, column: 22, scope: !175) -!177 = !DILocation(line: 65, column: 9, scope: !170) -!178 = !DILocation(line: 66, column: 14, scope: !175) -!179 = !DILocation(line: 66, column: 60, scope: !175) -!180 = !DILocation(line: 66, column: 6, scope: !175) -!181 = !DILocation(line: 67, column: 4, scope: !170) -!182 = !DILocation(line: 68, column: 3, scope: !165) -!183 = !DILocation(line: 70, column: 17, scope: !139) -!184 = !DILocation(line: 70, column: 15, scope: !139) -!185 = distinct !{!185, !135, !186, !187} -!186 = !DILocation(line: 71, column: 5, scope: !78) -!187 = !{!"llvm.loop.mustprogress"} -!188 = !DILocation(line: 73, column: 2, scope: !78) -!189 = !DILocation(line: 74, column: 1, scope: !78) -!190 = distinct !DISubprogram(name: "main", scope: !2, file: !2, line: 76, type: !191, scopeLine: 76, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !56) -!191 = !DISubroutineType(types: !192) -!192 = !{!53} -!193 = !DILocalVariable(name: "parsed_info", scope: !190, file: !2, line: 77, type: !82) -!194 = !DILocation(line: 77, column: 30, scope: !190) -!195 = !DILocation(line: 78, column: 5, scope: !190) -!196 = !DILocation(line: 79, column: 1, scope: !190)