You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The topical issue is that it is common for FFI libraries (and even pure-Rust libraries, sometimes) to use &(), &[Align; 0], &c_void, or some newtype wrappers of such as an opaque shared pointer to "some opaque object" which otherwise fits with Rust's & semantics.
The rustnomicon recommends this ZST approach (with ?Sync, ?Send, ?Unpin markers) for opaque objects, and bindgen uses it, but both manage to only ever mention using it with raw pointers, never with references. However, they also don't warn off using references, and I know it's not uncommon to see in practice (e.g. cxx will freely emit references to extern FFI types).
The problem comes from SB's reborrowing: this reduces the provenance of the reference to just what the ZST type indicates – zero bytes – even though it's trying to represent a type of unknown size rather than one of known zero size.
The proper solution is extern type (and SB to accommodate it), no questions asked. But extern type has been unstable for a long time, and the longer it's unstable, the more code which is using &ZST will emerge.
So I thought of a really sad way of handling this without invasively changing a lot of SB's provenance handling: relax reborrowing for just reference-to-ZST. This explicitly ignores the &Header-to-VLA use-case in favor of minimally patching SB to support &OpaqueZST.
I don't think it'd be as simple as just not emitting reborrow guards for reference-to-ZST, but since real reference-to-ZST can't be used to access memory locations anyway, it should be sound to allow them to carry around (potentially invalidated) provenance, which could be then used when cast back to a pointer.
More formally, with the snippet
let a:*const[u8;8];let b = &*(a as*const[u8;0]);let c = a as*const[u8;0]as*const[u8;8];
No matter a's provenance, current SB (AIUI) would give bShr provenance over 0 bytes, and thus c also has provenance over 0 bytes. Under this "solution", because b is a reference-to-ZST, it would retain Raw provenance equal to that of a (note that gaining Shr provenance to more than 0 bytes would be potentially an unsound race introduction), which would then be inherited by c as well, allowing c to be validly used.
I describe this as a sad solution, because the full solution would relax the requirements to handle &Header-to-VLA as well, and this is an ugly special case in an otherwise very uniform model.
The text was updated successfully, but these errors were encountered:
The topical issue is that it is common for FFI libraries (and even pure-Rust libraries, sometimes) to use
&()
,&[Align; 0]
,&c_void
, or some newtype wrappers of such as an opaque shared pointer to "some opaque object" which otherwise fits with Rust's&
semantics.The rustnomicon recommends this ZST approach (with
?Sync
,?Send
,?Unpin
markers) for opaque objects, and bindgen uses it, but both manage to only ever mention using it with raw pointers, never with references. However, they also don't warn off using references, and I know it's not uncommon to see in practice (e.g. cxx will freely emit references to extern FFI types).The problem comes from SB's reborrowing: this reduces the provenance of the reference to just what the ZST type indicates – zero bytes – even though it's trying to represent a type of unknown size rather than one of known zero size.
The proper solution is
extern type
(and SB to accommodate it), no questions asked. Butextern type
has been unstable for a long time, and the longer it's unstable, the more code which is using&ZST
will emerge.So I thought of a really sad way of handling this without invasively changing a lot of SB's provenance handling: relax reborrowing for just reference-to-ZST. This explicitly ignores the
&Header
-to-VLA use-case in favor of minimally patching SB to support&OpaqueZST
.I don't think it'd be as simple as just not emitting reborrow guards for reference-to-ZST, but since real reference-to-ZST can't be used to access memory locations anyway, it should be sound to allow them to carry around (potentially invalidated) provenance, which could be then used when cast back to a pointer.
More formally, with the snippet
No matter
a
's provenance, current SB (AIUI) would giveb
Shr
provenance over 0 bytes, and thusc
also has provenance over 0 bytes. Under this "solution", becauseb
is a reference-to-ZST, it would retainRaw
provenance equal to that ofa
(note that gainingShr
provenance to more than 0 bytes would be potentially an unsound race introduction), which would then be inherited byc
as well, allowingc
to be validly used.I describe this as a sad solution, because the full solution would relax the requirements to handle
&Header
-to-VLA as well, and this is an ugly special case in an otherwise very uniform model.The text was updated successfully, but these errors were encountered: