Skip to content

Assignment 3

Jiawei Wang edited this page Jul 22, 2024 · 35 revisions

Assignment-3 folder layout

$tree Assignment-3
├── Assignment-3-Helper.cpp
├── Assignment-3.cpp
├── Assignment-3.h
├── CMakeLists.txt
└── Tests
    ├── CMakeLists.txt
    ├── ae
    │   ├── test1.c
    │   ├── test1.ll    
    │   ├── test2.c
    │   ├── test2.ll
    │   ├── test3.c
    │   ├── test3.ll
    │   ├── test4.c
    │   ├── test4.ll
    │   ├── test5.c
    │   ├── test5.ll
    │   ├── test6.c
    │   └── test6.ll
    ├── buf
    │   ├── test1.c
    │   ├── test1.ll
    │   ├── test2.c
    │   └── test2.ll
    └── test-ae.cpp

1. Get the latest code template

* Before coding, please type cd $HOME/Software-Security-Analysis and git pull in your terminal to make sure you always have the latest version of the code template before each assignment.

Make sure to switch your program to ass3 before coding.

2. Assignment 3 task

  1. Implement updateStateOnCopy, updateStateOnStore, updateStateOnLoad, updateStateOnGep, updateStateOnBinary, updateStateOnPhi, bufOverflowDetection, handleCycleWTO, methods of class AbstractExecution in Assignment-3.cpp
  2. Run ctest -R ass3 -VV Pass the test without any assertion by test-ae.cpp.
  3. Upload Assignment-3.cpp to UNSW WebCMS for your submission when you are finished with this assignment. Your implementation will be evaluated against our internal tests. You will get full marks if your code can pass them all. Unfortunately, our internal tests are publicly unavailable. Here, we only provided limited test cases 3 test cases under Assignment-3/Tests/testcases. You are encouraged to add more test cases by yourself to validate the correctness of your implementation.

*You will be working on Assignment-3.cpp only and there is NO need to modify other files under the Assignment-3 folder

SVF AE APIs to help with your implementation SVF AE API.

2.1 Write updateStateOnCopy, updateStateOnBinary, updateStateOnStore, updateStateOnLoad, updateStateOnGep, and updateStateOnPhi

In Assignment-3.cpp, we provide implementations for functions such as updateStateOnAddr and updateStateOnSelect. These functions translate SVF Statements, including AddrStmt, CmpStmt, LoadStmt, etc.

Your task is to implement CopyStmt, BinaryOpStmt, StoreStmt, LoadStmt, GepStmt, and PhiStmt. The updateStateOnStore function should store the RHS value at the memory address corresponding to the LHS value in AEState which is from calling getAbsStateFromTrace. Note that the RHS variable can be either IntervalValue or AddressValue.

The updateStateOnGep function aims to compute the virtual address by adding an offset to the base pointer and then store the updated state in LHS value in AEState which is from calling getAbsStateFromTrace.

The updateStateOnCopy function should copy the RHS value to the LHS value in AEState which is from calling getAbsStateFromTrace.

The updateStateOnBinary function should perform the binary operation specified by the BinaryStmt and store the result in the LHS value in AEState which is from calling getAbsStateFromTrace.

The updateStateOnLoad function should load the value from the memory address corresponding to the RHS value and store it in the LHS value in AEState which is from calling getAbsStateFromTrace.

The updateStateOnPhi function should merge the values from the predecessor blocks and store the merged value in the LHS value in AEState which is from calling getAbsStateFromTrace.

2.2 Implement handleCycleWTO

The handleCycleWTO function needs enhancements to include widening and narrowing logic. This will enable the function to handle large loop bounds efficiently (e.g., for i = 0; i < 10000; ++i), allowing it to exit the loop after several iterations and determine the correct value of i.

2.3 Implement Buffer Overflow Detection

This task involves implementing the function bufOverflowDetection. This function takes an SVFStmt as input. If the statement is a GepStmt, it indicates an attempt to access an offset of a pointer or array.

The provided framework already includes the following steps:

  1. Identifying if the statement is a GepStmt.
  2. Using the updateGepObjOffsetFromBase function to update the offsets for the GEP objects.

You need to complete the following tasks:

  1. Check Object Sizes and Access Offsets: After updating the offsets using updateGepObjOffsetFromBase, you need to check if the access offset exceeds the effective byte size of the object.
  2. Report Buffer Overflow: If an access offset is found to exceed the object's size, you should report a buffer overflow.

Specifically, in the bufOverflowDetection function, you need to:

  • Retrieve the base address and size of the object.
  • Get the access offset.
  • Compare the access offset with the object's size. If the offset exceeds the size, report a buffer overflow.

Ensure you use the provided tools and functions correctly to perform these checks and report any buffer overflows.

It is important to note that a buffer overflow bug may occur during a GepStmt. For example:

int arr[5];
arr[10] = 1;

A buffer overflow might also emerge after multiple GepStmts, such as:

int arr[5];
int* ptr = arr + 3;
ptr[4] = 1;

Therefore, each GepStmt must be checked to ensure that the RHS variable's effective length still supports the current offset. If a bug is detected, an Assign3Exception should be thrown.

3. Configuration && debugging

To enable debugging and running, switch your executable by setting the program and args fields as described here or follow the below screenshot.

3.2 Debugging

If you want to see the value of AbstractValue, you can call toString() to print the value (either IntervalValue or AddressValue).

int main() {
    AbstractValue a = IntervalValue(1, 1);
    std::cout << a.toString() << std::end;
}

More information about C++

Clone this wiki locally