GaloisInc / saw-script

The SAW scripting language.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Limiting values inside char array parameter

Plants999 opened this issue · comments

I have some C code I am verifying through SAW:

            void ExampleMethod(char *options, uint64_t  value){

//carries out code

}

Saw verification:

module <- llvm_load_module "cfile.bc"

let exampleMethod_spec length = do {

(options, options_ptr) <- pointer_to_fresh (llvm_array length (llvm_int 64)) "options";



value <- llvm_fresh_var "value" (llvm_int 64);



/*

    code needed to limit values of options to certain letters and certain numbers

*/



llvm_execute_func [options_ptr, llvm_term value];



//llvm post conditions

};

llvm_verify module "ExampleMethod" [] true (exampleMethod_spec 78) z3;

However I want to limit the value inside the char array to specific values (some range of letters and some range of numbers).

But I haven’t been able to find a so far to do it. Is there an inbuilt function in SAW such as llvm_precond that can limit values inside an array.

Thanks

The options array that you bind on this line:

(options, options_ptr) <- pointer_to_fresh (llvm_array length (llvm_int 64)) "options";

Can be used as a Cryptol sequence within an llvm_precond statement. For instance, let's suppose that you wanted to assert that every element of options was equal to the letter 'A'. You could do this like so:

llvm_precond {{ and [ (options @ i) == zext 'A' | i <- [0 .. < length] ] }};

Here is an explanation of what this is doing:

  • [ ... | i <- [0 .. < length] ] is a sequence comprehension. This constructs a sequence where each element is derived from i, where i ranges over 0, 1, ..., length-1.
  • options @ i indexes into the options sequence using i as an index, returning a 64-bit integer.
  • In Cryptol, 'A' is an 8-bit integer, so we must extend it to a 64-bit integer with zext 'A' so that it can be checked against options @ i for equality.
  • Finally, and [ ... ] checks that every element of the sequence is true.

Of course, this is just a small example. You can change the ... == zext 'A' line to include a more sophisticated precondition if you'd like.

Does this answer your question?

The options array that you bind on this line:

(options, options_ptr) <- pointer_to_fresh (llvm_array length (llvm_int 64)) "options";

Can be used as a Cryptol sequence within an llvm_precond statement. For instance, let's suppose that you wanted to assert that every element of options was equal to the letter 'A'. You could do this like so:

llvm_precond {{ and [ (options @ i) == zext 'A' | i <- [0 .. < length] ] }};

Here is an explanation of what this is doing:

  • [ ... | i <- [0 .. < length] ] is a sequence comprehension. This constructs a sequence where each element is derived from i, where i ranges over 0, 1, ..., length-1.
  • options @ i indexes into the options sequence using i as an index, returning a 64-bit integer.
  • In Cryptol, 'A' is an 8-bit integer, so we must extend it to a 64-bit integer with zext 'A' so that it can be checked against options @ i for equality.
  • Finally, and [ ... ] checks that every element of the sequence is true.

Of course, this is just a small example. You can change the ... == zext 'A' line to include a more sophisticated precondition if you'd like.

Does this answer your question?

When I used that code above, it is setting the value of the char array to 65, which is A in ascii.

I am comparing it to cryptol code, that returns a value based on what the char is. But when I have set all values to 'A',

the cryptol code:

                else if char == 'a' then ...

                else error "invalid char"

It returns the error. I have also tried checking if the char is equal to 65.

Do you know after changing all the values of the char array to 'A' what would the equivalent be in Cryptol?

I'm not sure I understand what you are trying to do based on the small amount of Cryptol code you've provided. Can you post a more complete example?