AdaCore / RecordFlux

Formal specification and generation of verifiable binary parsers, message generators and protocol state machines
Apache License 2.0
106 stars 7 forks source link

Prevent Valid_Message without Verify_Message #70

Open senier opened 5 years ago

senier commented 5 years ago

When building the IP sniffer test, I forgot to run Verify_Message before checking Structural_Valid_Message. While this was not a correctness issue (the context of cause was invalid), it took me some time to realize that. I wonder if we should add a predicate to those convenience operations that work on a whole message that states/requires that a verification has been attempted on a context. This way we could spot such oversights during proof.

treiher commented 5 years ago

We should make sure that such a predicate also works with Verify, not only with Verify_Message. I think the simplest solution would be to let the Initialize procedure add a predicate Unchanged to the context, which is automatically removed by any procedure with an in-out context parameter (i.e. Verify, Verify_Message, Take_Buffer, Switch and Update). All validation functions would then need a not Unchanged as precondition.

senier commented 5 years ago

Suggested name for the predicate: No_Verification_Attempted

treiher commented 5 years ago

The envisioned solution is not applicable, as the value of the predicate is unknown after a procedure with an in-out parameter. After some discussion we think there is no simple solution, which has no drawbacks.

A good solution is able to statically analyze, if the code could lead to a valid message before Valid_Message is called. The following properties should be fulfilled, before Valid_Message can be used:

Initialize (C, Buffer);

Verify (C, Field_A);
if Valid (C, Field_A) then
   Verify (C, Field_B);
   if Valid (C, Field_B) then
      ...
   end if;
end if;

For a good usability it should be possible to call Valid_Message (C) after this nested if-statements (if a correct incremental verification was done before). But I guess the verification tools would be only able to show the correct usage if Valid_Message is used inside of the nested if-statements.

treiher commented 5 years ago

After further discussion we came to the following idea as solution:

This covers the first three aspects mentioned in the comment above. As field conditions are checked internally by Verify, it is not necessary to enforce the user to do same again. Calling Valid_Message after nested if-statements will be not possible in the way shown above (a workaround would be to bind the proof-state to a boolean value in a branch where the necessary verifications have been done - that value has to be checked before using Valid_Message).

The implementation comprises the following tasks: