-
Notifications
You must be signed in to change notification settings - Fork 58
Add RAPx tool description and CI workflow #491
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
base: main
Are you sure you want to change the base?
Conversation
Hi @DiuDiu777 ! Very excited to see another participant entering the contest. I'm trying to understand your approach. In particular, I'm reading the Unsafe Code Audit chapter of the RAPx Book. Could it be that there are some typos in the code examples?
Is there a paper arguing the soundness of your unsafe code audit approach with respect to a formal semantics of the programming language (such as I do in Featherweight VeriFast)? I found this paper but it does not seem to make any soundness claims. |
Also, your example in the book is still somewhat complex. It would be very helpful, I think, if you could do a similar walkthrough for |
Hi, @btj . Thank you so much for your careful review and thoughtful feedback! Regarding your questions:
As for the soundness and complexity of examples, we're currently refining the document to better explain soundness guarantees and simplify examples where possible. Thanks again for your valuable input! |
Hi @btj , thanks for reviewing our work. I have written a short article that explains why our core methodology, tracing-based verification, is sound. |
Hi @hxuhack , many thanks for the article. However, I had hoped that it would clarify the key concepts of your approach, such as unsafety propagation graph, object flow edge, basic unit, audit unit, safety property, dominated graphs, contractual invariant states, operational trace states, vulnerable paths, constructor analysis, and method sequence analysis. It would be very useful to see a formal definition of (simplified versions of) these concepts, and a formal definition of the overall unsafe code audit approach, and then a rigorous proof relating these concepts to a formal syntax and semantics of (a simplified version of) Rust, showing that if the approach accepts the program, then the program has no Undefined Behavior. Something like what we did in the Featherweight VeriFast paper. Here are some specific questions to which I did not immediately find an answer in the materials currently available: A. Would your tool detect the error in the following incorrect version of pub fn into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A) {
let mut me = self; // was: let mut me = ManuallyDrop::new(self);
let len = me.len();
let capacity = me.capacity();
let ptr = me.as_mut_ptr();
let alloc = unsafe { ptr::read(me.allocator()) };
(ptr, len, capacity, alloc)
} B. Would your tool detect the error in the following incorrect version of pub fn into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A, A) {
let mut me = ManuallyDrop::new(self);
let len = me.len();
let capacity = me.capacity();
let ptr = me.as_mut_ptr();
let alloc = unsafe { ptr::read(me.allocator()) };
let alloc2 = unsafe { ptr::read(me.allocator()) }; // I added this line
(ptr, len, capacity, alloc, alloc2)
} C. Would your tool detect the error in the following incorrect version of pub fn into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A) {
let mut me = Box::new(self);
let len = me.len();
let capacity = me.capacity();
let ptr = me.as_mut_ptr();
let allocator_ptr = me.allocator() as *const A;
drop(me);
let alloc = unsafe { ptr::read(allocator_ptr) };
(ptr, len, capacity, alloc)
} |
The mechanism of RAPx for verification is similar to taint analysis, where unsafe code serves as the taint source and function exits act as the sink. RAPx begins the verification process by identifying all unsafe callees, including intrinsic operations such as raw pointer dereferencing. In the case of the #[cfg_attr(rapx, safety {ValidPtr(src, T, 1)})]
#[cfg_attr(rapx, safety {Typed(src, T)})]
#[cfg_attr(rapx, safety {Align(src, T)})]
#[cfg_attr(rapx, safety { any { hazard.Alias(src, ret), Trait(T, Copy)})]
pub const unsafe fn read<T>(src: *const T) -> T RAPx considers a method sound if, in all possible executions reaching the unsafe call site, the safety constraints are satisfied. Case A. No, RAPx will not directly detect this error, because the safety constraint of RAPx will ultimately detect the unsoundness when verifying another method of the same struct, pub fn into_chunks<const N: usize>(mut self) -> Vec<[T; N], A> {
...
let (ptr, _, _, alloc) = self.into_raw_parts_with_alloc();
unsafe { Vec::from_raw_parts_in(ptr.cast(), len / N, cap / N, alloc) }
} Case B. The only potential source of undefined behavior I can tell lies in a possible aliasing hazard caused by Case C. Yes. Since In practice, when verifying the soundness of a struct method, we must also account for the influence of its constructors and other methods within the same struct. The soundness criteria and encapsulation requirements are discussed in our arXiv paper, A Trace-based Approach for Code Safety Analysis. We plan to incorporate the abstract interpretation component once it is completed, along with the formal definitions of the key concepts you mentioned by that time. Thank you very much for your insightful questions and thoughtful suggestions. By the way, I will be giving a talk about the entire idea at RFMIG later this month, and you are warmly invited to attend. |
Dear @hxuhack , Many thanks for your elaborate response; it's very helpful and kind. I hope you don't mind if I go on a little longer with my questions :-) Do I understand correctly that your tool reasons about the On the other hand, your tool does not require a driver or test harness, i.e. a For my case A, notice that the method returns not just a dangling pointer in the first component of the return value, but also a dropped allocator in the fourth component. Would your tool detect it if a (safe or unsafe) client tried to use the dropped allocator? Looking forward to your talk! I look forward to learning more about the algorithms and data structures underlying your approach, perhaps as applied to |
This PR adds the tool description and workflow for RAPx.
Since we plan to try challenge 23 for verifying Vec, we use the
vec::into_raw_parts_with_alloc
API as an example in this PR. It demonstrates how to annotate the target function and mark relevant unsafe callees with safety tags for RAPx verification.Related issue: Add Tool: RAPx