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

Are there any methods provided by haybale for constraining certain variables? #19

Closed
Just1ceP4rtn3r opened this issue Feb 20, 2022 · 7 comments

Comments

@Just1ceP4rtn3r
Copy link

Just1ceP4rtn3r commented Feb 20, 2022

e.g.

int foo(struct Context* context) {
  //assert(context->x == 1);
  if (context->x == 0)
     return 0;
  
  if (context->y < 0)
     return -1;
  else 
     return 1;
} 

So I just want to take "context->y" as a symbolic value and restrict "context->x" to 1. Can we reach this but not modify the origin LLVM IR ?

@Just1ceP4rtn3r
Copy link
Author

I found that symex_function provides a parameter named "params: Option<Vec>". But how to set some initial value for a pointer of struct?

@Just1ceP4rtn3r Just1ceP4rtn3r changed the title Are there some methods provided by haybale for restricting certain variables? Are there any methods provided by haybale for restricting certain variables? Feb 22, 2022
@cdisselkoen
Copy link
Collaborator

One way to do this is:

  1. use symex_function with params=None to get an ExecutionManager
  2. use ExecutionManager::mut_state() to access the State, from which you can allocate some bits representing the struct Context you want to pass in, receiving a BV pointer to the new allocation
  3. constrain the x field of that allocation to be 1
  4. finally, use ExecutionManager::param_bvs() to access the context parameter, and then constrain it to be equal to the pointer received in step 2.

For a more thorough solution, you can take a look at what pitchfork built on top of haybale, in particular pitchfork's AbstractData.

@Just1ceP4rtn3r

This comment was marked as abuse.

@cdisselkoen
Copy link
Collaborator

You can do

let context_inmem = mutState.read(&contextPtr, struct_size_bits).unwrap();
context_inmem._eq(&context).assert().unwrap();

Or, even better, just constrain the x field of context_inmem directly, without creating a separate BV:

let context = mutState.read(&contextPtr, struct_size_bits).unwrap();  // instead of BV::new
// use `context` as in the above comment

@Just1ceP4rtn3r
Copy link
Author

Just1ceP4rtn3r commented Mar 1, 2022

Thanks, I see now what you mean!
But the struct Context is more complex in the real code. For example, Haybale will throw errors Error::NullPointerDereference when access context->next->a because we didn't allocate next:

struct Context{
    struct Context * next;
    char a;
    char b;
    char x;
    char y;
}

Is necessary for us to allocate the next field and other global variables(cause haybale is used to analyze a function that is not main) that may lead to a Null Pointer error?

@Just1ceP4rtn3r Just1ceP4rtn3r changed the title Are there any methods provided by haybale for restricting certain variables? Are there any methods provided by haybale for constraining certain variables? Mar 2, 2022
@cdisselkoen
Copy link
Collaborator

Sorry for the delayed response (to this and the other thread) -- a lot on my plate right now.

Yes, you will have to initialize those other fields if you want Haybale to consider specific values for them. If you don't initialize them, Haybale will consider that memory to be unconstrained, i.e., could have any value, including NULL, hence the null pointer error.

For null pointer errors specifically, you may want to configure Config.null_pointer_checking instead; this has a few different options for how Haybale treats and reports possible null pointer dereferences.

@Just1ceP4rtn3r
Copy link
Author

Haha, no problem. Then I need to initialize those fields. Otherwise, not only it will lead to the null pointer error, but also may consume a large of time to solve constraints. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants