wrong function pointer targets
I am trying to analyze a library combined with a demo application. Currently some function pointers are wrong matched.
Following this, here a short example showing wrongly matched function pointers.
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
struct _FILE {
size_t (*write)(char);
char buffer[25];
};
size_t _fwrite(void *obj, struct _FILE *f) {
memcpy(f->buffer, obj, 25);
return f->write(' ');
}
size_t sticky_func(void* _) {
pause();
return 0;
}
struct stickyStruct {
size_t (*func_ptr)(void* _);
};
struct stickyStruct sticky_struct;
struct _FILE file_struct;
int main() {
sticky_struct.func_ptr = &sticky_func;
_fwrite(&sticky_struct, &file_struct);
sticky_struct.func_ptr(NULL);
}
Here is the LLVM IR code of this example: funcpointer_issue.tar.gz
The command ./wpa --ander --print-fp returns:
NodeID: 33
CallSite: %13 = call i64 %12(i8 signext 32) #4, !dbg !48 Location: { ln: 13 cl: 12 fl: funcpointer_issue.c } with Targets:
sticky_func
NodeID: 68
CallSite: %5 = call i64 %4(i8* null) #4, !dbg !43 Location: { ln: 31 cl: 5 fl: funcpointer_issue.c } with Targets:
sticky_func
The function pointer target at line 31 is correct. Why the function pointer at line 13 is matching to sticky_func, as well? By removing the memcpy() in line 12 the issue is gone and the function pointer matches correctly.
Did I find a bug?
This is an interesting test case. However, this is not a bug. The analysis is imprecise for your case.
Because when handling memcpy(f->buffer, obj, 25);, SVF will copy the points-to targets of pointer obj to each field of f, since we did not consider the number of bytes to be copied.
https://github.com/SVF-tools/SVF/blob/master/lib/SVF-FE/PAGBuilder.cpp#L1056 https://github.com/SVF-tools/SVF/blob/master/lib/SVF-FE/PAGBuilder.cpp#L921-L946
It seems that this can be improved to avoid imprecision, you feel free to contribute or propose any solutions.
Thank you.
If I get it right, the SVF currently resolves function pointer two fold:
- If a function pointer cannot be resolved at all, the SVF does not connect it with anything (partly #280).
- Under certain circumstances, the connection in the ICFG is wrong (like in this example).
So, if there is a connection, the target can be wrong, if there is no connection, the missing target can be wrong, too. For me, this is unsound. I would have expected that in the minimal example above the pointer in line 13 is not connected to anything.
Is it possible to (optionally) make the analysis sound in regard to that, if a connection is returned, this connection is correct?