-
Notifications
You must be signed in to change notification settings - Fork 15
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
Support for validating pointer-rich formats given a probe to check for pointer validity #118
Conversation
…er and extern instantiations
… eloc and inv; things work again
…s locations in the interpreter ... all or nothing!
match t.v with | ||
| Pointer _ -> None | ||
| Pointer _ -> typ_weak_kind env tuint64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, pointers widths are fixed to UINT64
@@ -93,7 +93,7 @@ let size_and_alignment_of_typ (env:env_t) (t:typ) | |||
: ML (size & alignment) | |||
= match t.v with | |||
| Type_app i _ _ -> size_and_alignment_of_typename env i | |||
| Pointer _ -> Variable, Some 8 | |||
| Pointer _ -> Fixed 8, Some 8 //pointers are 64 bit and aligned |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cf. previous remark re pointers
|
||
inline_for_extraction | ||
noextract | ||
let probe_then_validate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the main new functionality: turning a validator into an action
…mple (thanks Tahina for reporting)
This PR provides support for a "probe and copy" feature, allowing input formats to contain pointers that will be followed by the validator after a user-provided "probe" function checks that the pointer refers to legal memory for a given extent.
The following example illustrates (from tests/Probe.3d)
This function should probe the pointer_value, and if successful, it will copy length bytes into destination. You can use whatever existing (typically kernel) primitive you have for this and it should take care of the exception handling etc. and just return a boolean.
In the specification of the type
S
above, we take aEVERPARSE_COPY_BUFFER_T dest
as an argument.The field
t
ofS
is a pointer to aT
, and the annotation says that it should be probed and copied (using the declaredProbeAndCopy
in scope) and then the contents ofdest
will be validated to contain aT
.You chose how to implement EVERPARSE_COPY_BUFFER_T: EverParse.h defines
typedef void* EVERPARSE_COPY_BUFFER_T
. So, you can implement that type as you like and call the validator with a pointer to your type; a typical choice is that it can itself be a UINT8* with a length. See https://github.com/project-everest/everparse/blob/8572ec9cf8d3abb49ac76e2a218dbf7fcbb48fbc/src/3d/tests/probe/README.md for more details.At the top-level, EverParse gives you the following function to validate an
S
. When calling it fromC
, you should make sure thatdest
does not aliasbase
(or any other out parameters you may have).
Disjointness preconditions
This required a change to the abstraction of validators and actions. Now, they are indexed by an additional "disjointness precondition", which is used ensure that when validating the contents of a copy buffer, that an action running during that process does not modify the copy buffer itself. For example, the disjointness precondition causes us to (rightfully) reject this specification---to validate
S *s
we copy intodest
, but in the process of validatingS
we again copy intodest
when encounteringT *t
. This is detected and rejected.Compiler performance
The addition of the disjointness precondition adds an overhead to the verification of all 3D specs, even those that do not use copy buffers, since the abstraction forces us to compute the disjointness precondition anyway. On small specifications, this overhead does not seem to be observable significantly. However, on a large internal benchmark, I measured an end-to-end overhead of around a 20% slowdown in verification time. I am still contemplating ways to reduce that overhead, though at least some overhead seems unavoidable, since we do have to compute this disjointness precondition for soundness. Perhaps there's a way to avoid computing it for the common case in which probing is not used.