-
Notifications
You must be signed in to change notification settings - Fork 20
Probe-generic functions, auto-specialization, 32 & 64-bit layouts #175
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
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
… Front-end support to follow
…to type-correct F*
…rating cleaner C code
…s; remove many stray debug print messages
… with `--makefile`
…stead of copying from EverParse
… be used with `--makefile`" This reverts commit ce031bd.
…n duplicate extern functions; support in concrete syntax for SkipRead and SkipWrite
…asserts files in specialize test cases
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Background
Pointer probing is a feature of 3D since PR #118. This allows validating
structures that contain pointers by checking that those pointers are valid, and
then copying the pointed-to contents into a destination buffer, and validating
the copied bytes.
This PR extends probing to support validating structures that may contain either
32-bit or 64-bit pointers, depending on the architecture for which the sending
process is compiled. Structures that contains such pointers may have different
layouts depending on the architecture, due to differences in alignment padding
etc.
We want a smooth way to specify that a 3D description of a data structure should
handle multiple pointer widths, enabling a single specification that can be
specialized to either 32 or 64-bit layouts. Additionally, we want to be able to
easily copy a 32 bit structure to 64-bit layout, so that the downstream code can
proceed uniformly with the two cases.
Three new features
Pointer type with explicit representations
This PR adds a new qualifier to pointer types, to give them an explicit
representation, as shown by the following example:
Only the following unsigned integer type can be a legal pointer qualifier:
• pointer(UINT32)
• pointer(UINT64)
The current default behavior is retained, i.e., an unqualified pointer type
defaults to UINT64.
Fine-grained probing (for traversing 32-bit pointers)
We want to allow probing and reading structures with 32-bit pointers into 64-bit
kernel data structures. This involves copying pieces of 32-bit structures
carefully, adding padding as needed, coercing pointers from 32 to 64-bit
representations.
For this, this PR introduces a new sub-language for fine-grained probing of
pointers, as the following example illustrates.
Let’s start with a simple structure A: nothing fancy here, just two UINT32 fields.
Next, we have a structure B, which contains a pointer to an A. The
representation of A is the same on both 32-bit and 64-bit architectures. So, we
can just probe and copy the referenced A structure in a single shot to an out
parameter, a_out.
Next, we have a structure C, which contains a 32-bit pointer to a B. When
following a 32-bit user mode pointer, we assume that the data pointed to is in a
32-bit layout, including all the pointers it contains.
As such, when following the pointer pb, B is in 32-bit representation, different
from the 64-bit representation expected by the kernel. So, we probe the pointer
pb repeatedly, and copy pieces of B over to the out parameter b_out.
Note, instead of a single call to ProbeAndCopy, we have a block with several
operations writing into the destination buffer b_out. The result is the b_out
contains representation of the 32-bit data converted to 64 bit layout. After the
copy is completed into b_out, we run the validator B(a_out) on the copied data,
ensuring that the data satisfies the expected 64-bit layout, as well as all
refinement constraints etc. that the type B may have.
Auto-specialization
Of course, explicitly writing fine-grained probes is very tedious and
error-prone. Also, we would like to define the data format compactly once, for a
64-bit layout, and obtain the equivalent 32-bit layout almost for free.
So, we support the following automated specialization feature:
The semantics of the specialize directive is to specialize the given type
C64to use the given pointer size (pointer(UINT32)) and name the specialized type
C32. This elaborates to the explicit fine-grained probing definition shown
earlier.
Now, one can define a uniform entry point function that multiplexes the two
definitions, based on the requestor mode.
Generated code
The example above produces the following code:
The header file contains signatures for the extern declarations.
Internally, the generated validators are produced in a higher-order style, passing probe functions as arguments, to copy or coerce-and-copy the pointed-to data, though the external signature hides this altogether.