Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The shortcomings of memcpy #1498

Open
ZcoderL opened this issue Jul 11, 2024 · 5 comments
Open

The shortcomings of memcpy #1498

ZcoderL opened this issue Jul 11, 2024 · 5 comments
Labels

Comments

@ZcoderL
Copy link

ZcoderL commented Jul 11, 2024

SVF seems to have not considered the handling of memcpy when two pointer types are different.
An example is as follows:

#include "stdbool.h"
extern void svf_assert(bool);

int main() {
    int arr[2] = {0};
    arr[1] = 10;
    int *arr2 = (int*)malloc(2 * sizeof(int));
    memcpy(arr2, arr, sizeof(arr));
    svf_assert(arr2[1] == 10);
    return 0;
}

When processing the external function memcpy, the type of arr is displayed as llvm:: Type:: ArrayTyID, but the type of arr2 is llvm:: Type:: IntegerTyID
This will result in additional generated loadstmt and storestmt errors:
image
All values in arr should have been copied, but only one was copied here

The second issue is that when memcpy applies to the return value of a function, ae will fail. For example, Test Suite/test_cases_bc/aeassert_tests/BASICarray_fnc_2-0.c.bc

#include "stdbool.h"
extern void svf_assert(bool);

struct {
    int a;
    int b;
}typedef A;

A getValue(A* arr, int x) {
    return arr[x];
}

int main() {
    A a[2];
    a[0].a = 10;
    a[0].b = 11;
    a[1].a = 20;
    a[1].b = 21;
    A res = getValue(a, 1);
    svf_assert(res.b == 21);
    return 0;
}

I have output the values of two parameters in svf_assert, and the result indicates that res. b is (<[- ∞, ∞], ⊥>)

Can you help fix these two issues? thank you

@yuleisui
Copy link
Collaborator

@jumormt @bjjwwang could you take a look at this case. The type of arr2 looks incorrect to me. When handling memcpy, we will need to be conservative to use the largest memory object for mem copying?

@ZcoderL
Copy link
Author

ZcoderL commented Jul 15, 2024

@jumormt @bjjwwang could you take a look at this case. The type of arr2 looks incorrect to me. When handling memcpy, we will need to be conservative to use the largest memory object for mem copying?

Yes, I also think there is a problem with the type of arr2 in the first question, including the getValue function in the second question, which returns the struct of type A. I have checked its type and it is also llvm:: Type:: IntegrarTyID, but I think it should be llvm:: Type:: StructTyID like the input parameter A * arr

@jumormt
Copy link
Contributor

jumormt commented Jul 18, 2024

@ZcoderL Thanks for raising this issue. #1500 should fix the bug.

@ZcoderL
Copy link
Author

ZcoderL commented Jul 19, 2024

Thank you for the fix. The pointer types in memcpy are now the same,
However, there were errors when using ae to detect ae_assert_tests/BASIC_array_func_2-0. c in the Test Suite

Because memcpy directly performs gep, gep, and store operations on the retval, there is actually no stored value in the retval. But when returning, a load was applied to the retval
image
image

After processing ICFGNode, I output its abstract state as follows
image
The result of displaying load retrieval (ValID: 95) is<⊥, ⊥>

Although the final assessment passed, it was clearly incorrect
image

@yuleisui
Copy link
Collaborator

This is a good finding. @jumormt @bjjwwang could you take a look at this case.

@yuleisui yuleisui added the bug label Aug 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants