-
Notifications
You must be signed in to change notification settings - Fork 58
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
caprevoke fork fixes #1724
caprevoke fork fixes #1724
Conversation
The local parts of rc already skip .sample files; we add .pkgsave to the list, and add logic for base. Thanks to @RhodiumToad for getting this started. Differential Revision: https://reviews.freebsd.org/D27962 Reviewed by: imp Pull Request: freebsd/freebsd-src#662 (cherry picked from commit 3693d91)
* with a newly quarantined neighbor. | ||
*/ | ||
if (old_entry == old_map->rev_entry) | ||
new_map->rev_entry = new_entry; |
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.
vm_map_entry_quarantine() will compare the neighbours of new_entry
with new_map->rev_entry
to see if they can be merged with new_entry
. So this assignment doesn't prevent merging from happening at the point where this entry is being added. It's not obvious to me that this is what we want, but I'm also not too familiar with the quarantine mechanism yet so could easily be missing something.
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.
There's a further check in vm_map_mergeable_neighbors()
(called from vm_map_try_merge_entries()
) that will prevent the entry in rev_entry from being merged. That suggests the checks in vm_map_entry_quarantine()
are redundant.
As background, we can't allow the entry pointed to by rev_entry
to be merged (enlarged) because we may have already examined capabilities that were outside the current entry, but would be inside the new one and thus we'd fail to revoke those capabilities.
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.
Got it, thank you.
ac003a5
to
22d72dc
Compare
I've completely redone the core changes. I now believe the issue was that we weren't copying the CLG state to the new pmap in pmap_vmspace_copy(). By doing copying the state it aligns with the CLG in capdirty pages and thus we don't try to revoke on fault when we've never started a revocation in this particular process. |
22d72dc
to
975ae66
Compare
It was hard to tell what the if conditions were.
When the parent is GEN1, capdirty pages will also be GEN1, but now the child will be GEN0 so there will be a mismatch leading to faulted capdirty pages being revoked when revocation isn't in progress. If no revocation is triggered before the fault happens then vm_map.vm_cheri_revoke_test may be NULL leading to a panic.
975ae66
to
b290f6f
Compare
b290f6f
to
94775ff
Compare
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.
Generally looks good to me; I'm sorry to have left you with such a mess. One comment about vmspace_fork
, and one stylistic question, but even with those I think it's good to go as is.
94775ff
to
f93e1a7
Compare
This is a potentially expensive check we we might not want to keep it on by default even under invariants.
When called from exec_new_vmspace() to empty an unshared vmspace prior to exec, the vm_map will be initialized with a zeroed enqueue and dequeue epoch in the info page. When the process had previously revoked and we failed to reset the state and zero the kernel's notion of the epoch we ended up in an infinite loop were the kernel would see no work to do (passed start epoch in the past) and thus would not update the info page resulting in no progress being made. One could alternatively reset the state in exec_new_vmspace(), but the extra store seems harmless in the vm_map_free() case.
Verify that the empty vmspace is not revoking and has a zero epoch.
If the epoch is open then vm_cheri_revoke_test has been set and we need to copy it was that we can test capabilities when we come back to finish this epoch.
If the epoch is open we may be in the midst of a revocation and thus rev_entry may be set in old_map. In that case, set the corresponding entry in new_map.
f93e1a7
to
eb2863c
Compare
Add a somewhat unprincipled set of __has_feature(capabilities) checks to allow cheri/revoke.h to be included unconditionally by libsysdecode's implementation.
3ae4fce
to
352dc36
Compare
352dc36
to
b2db563
Compare
Support the flags arguments of cheri_revoke(2) and cheri_revoke_get_shadow(2). Use compressed names (sysdecode_cr*()) as otherwise the formatting of the manpage is completely trashed (mandoc uses too much space between columns).
Add two new modes to cheribsdtest_cheri_revoke_lib_run which start or end a revocation of the entire array (rather than looping over it to process a random number of times (average should be)). Use this to open an epoch prior to forking and close it in the child process.
b2db563
to
db2ac6a
Compare
I've fixed a lame hack in mktables in the libsysdecode commit after @jrtc27 pointed out I'd missed the exclude feature. Should be ready to land at this point (CI failures are out of disk space errors) |
Fix/work around some issues present in the caprevoke tree.