<!-- Leave your topic starting with ### in the relevant sections below --> ## Critical <!-- bugs, soundness issues, urgent patches/reviews etc. --> ## Status Reports <!-- You want to report on something you are working on/request reviews. Or you want to know the status of something someone else is doing --> ## Discussion Questions <!-- Anything that requires lengthy discussion/more general questions also fit here --> ### Aliasing rules for dereferencing raw pointers Following discussion on when to use `UnsafeCell` on [Zulip](https://rust-for-linux.zulipchat.com/#narrow/stream/291565-Help/topic/Unsafecell.20deref.20trait/near/367084988) I referenced our "Reviewers Recommendations" and found them a bit lacking. I got to thinking about why we do not need `UnsafeCell` when we mutate through a pointer to an FFI struct, and I confused myself a bit in the process. I started digging, but I did not really find a definitive answer. I think we should discuss so that we can update the "Reviewers Recommendations" with clear guidelines. I would like to understand clearly what requirements Rust has for mutating and reading through raw pointers that point to data allocated by Rust and FFI (C) code. #### Docs For owned data, the guidelines in `UnsafeCell` [docs](https://doc.rust-lang.org/stable/core/cell/struct.UnsafeCell.html) and the [nomicon](https://doc.rust-lang.org/nomicon/aliasing.html) are quite clear. The rules for creating a reference from a raw pointer also seem to be well defined. For reading and mutating through raw pointers the documentation is not so clear. The nomicon on aliasing contains the following text: > ... raw pointers (which have no aliasing requirements on their own), The documentation for `core::ptr` talks about conditions for pointers being valid for read and write but also states: > The precise rules for validity are not determined yet. and > All accesses performed by functions in this module are non-atomic in the sense > of atomic operations used to synchronize between threads. This means it is > undefined behavior to perform two concurrent accesses to the same location > from different threads unless both accesses only read from memory. Notice that > this explicitly includes read_volatile and write_volatile: Volatile accesses > cannot be used for inter-thread synchronization. but does not talk about mutating through `*mut` or reading from `*mut` or `*const`. The Rust reference [section](https://doc.rust-lang.org/stable/reference/behavior-considered-undefined.html) on UB states that breaking the LLVM "[pointer aliasing rules](https://llvm.org/docs/LangRef.html#pointer-aliasing-rules)" is UB. The latter states the following about pointers passed from FFI: > An integer constant other than zero or a pointer value returned from a > function not defined within LLVM may be associated with address ranges > allocated through mechanisms other than those provided by LLVM. Such ranges > shall not overlap with any ranges of addresses allocated by mechanisms > provided by LLVM. Interestingly, [this](https://stackoverflow.com/a/57366017) stackoverflow answer seems to indicate that dereferencing a raw pointer is semantically equivalent to turning the pointer into a reference: > There are no "rules of raw pointers". Raw pointers (*const T and *mut T) can > alias anything, anywhere, or they can point to nothing at all. > > Undefined behavior can happen when you dereference a raw pointer, implicitly > or explicitly turning it into a reference. This reference still must obey the > rules of references, even when the & isn't explicit in the source code. Finally, Alice states in chat that: > As a general rule, if ptr::read is ok, then creating an immutable reference, > reading, and then not using the immutable reference again is also sound. The > same applies to mutable references and ptr::write. > References are always created by field accesses, though just doing *ptr = 5; > doesn't actually make a reference for Copy types. For last paragraph I am not sure what a "field access" is. Q: is `*p = x;` equivalent to `core::ptr::write(p, x);`? A: No! `*p = x;` first does `core::ptr::drop_in_place(p);` and then does `core::ptr::write(p, x);`. ```rust unsafe { let thing: *const Thing = from_c_land(); let val1 = *thing; some_c_func(); let val2 = *thing; println!("{}", val1 == val2); // might print false } ``` Subdiscussion about `struct file` unsynchronized reads/writes: Wedson: `struct file` has some unsynchronized reads/writes what should we do about it on the rust side? ### [Safety Extensions](https://hackmd.io/b_EHIsQHSQaVMVyyoGhpmA?view) Benno: Do we want it to be this structured? Or more along the lines of natural language as Alice suggested/preferred? Boqun: I think a few notations are helpful, honestly, I think they are natural language as well ;-) ## Miscellaneous <!-- stuff that does not fit into other categories --> ### LPC proposal https://rust-for-linux.zulipchat.com/#narrow/stream/348125-Weekly-Meeting-Wed-1900-UTC/topic/LPC.20BoF.20proposal.3A.20Rust-for-Linux.20clinic/near/366893694 * Whos planning on attending LPC * Kangrejos happening? * Logo banner for Level3 contributing companies https://www.kernel.org/doc/html/latest/process/contribution-maturity-model.html