Hi list,
I’ve been trying to build a checker for a function that is defined in a shared library. The prototype of these functions look (example for simplicity) like this:
int
alloc_t(type_t **, int, int)
void
free_t(type_t *);
In the actual code I want to check (thus not the library rather code that uses the library) I do:
type_t *ptr;
if (alloc_t(&ptr, 0, 0) != 0) {
// means alloc failure usually return
return (1);
}
// do something with *ptr
free_t(ptr);
The checker I wrote is more or less, a hybrid of the existing checkers in the clang repo and I used the PDF/video “writing a checker in 24 hours”.
Its been well past 24 hours and I have a checker that works. However, the problem is is that I cant seem to educate the checker well enough, that if it finds the snippet:
if (alloc_t(&ptr, 0, 0) != 0)
return
It should not “mark” the ptr because != 0 means the allocation failed.
When I create a simple stubs for the function I like to track and have it either return 0 or return 1, I can get it to work. I get the return value of the function and create a new SVal, and have it check if its 0 or anything larger then 0 (using evalBinOp).
When linking against the real library however, it does not work. (it seems the analyser cant figure out what the external library is returning) I also tried the approach used in the StreamChecker example, but those examples check for the arguments being non NULL which does not work in my case. (as the type_t is “untouched” when the alloc fails)
So then I continued trying to wrap my head around check::BranchCondition, but to be honest, I have no clue how to unwind the things to a point where I can update the state (update the state using what? the function? arg0? create a new SymbolRef of what?) or how I can get my hands on the actual values confined with in the if(). Even if I could that far, I’d still would be in the dark on how to proceed.
Im pretty sure this all due to my incomplete understanding of all of this, so any help is much appreciated!
Thank you,
/DF