312
312
//! For instance, ARM explicitly supports high-bit tagging, and so CHERI on ARM inherits
313
313
//! that and should support it.
314
314
//!
315
- //! ## Pointer-usize-pointer roundtrips and 'exposed' provenance
315
+ //! ## Exposed Provenance
316
316
//!
317
- //! **This section is *non-normative* and is part of the [Strict Provenance] experiment.**
317
+ //! **This section is *non-normative* and is an extension to the [Strict Provenance] experiment.**
318
318
//!
319
319
//! As discussed above, pointer-usize-pointer roundtrips are not possible under [Strict Provenance].
320
- //! However, there exists legacy Rust code that is full of such roundtrips, and legacy platform APIs
321
- //! regularly assume that `usize` can capture all the information that makes up a pointer. There
322
- //! also might be code that cannot be ported to Strict Provenance (which is something we would [like
323
- //! to hear about][Strict Provenance]).
324
- //!
325
- //! For situations like this, there is a fallback plan, a way to 'opt out' of Strict Provenance.
326
- //! However, note that this makes your code a lot harder to specify, and the code will not work
327
- //! (well) with tools like [Miri] and [CHERI].
328
- //!
329
- //! This fallback plan is provided by the [`expose_addr`] and [`from_exposed_addr`] methods (which
330
- //! are equivalent to `as` casts between pointers and integers). [`expose_addr`] is a lot like
320
+ //! This is by design: the goal of Strict Provenance is to provide a clear specification that we are
321
+ //! confident can be formalized unambiguously and can be subject to precise formal reasoning.
322
+ //!
323
+ //! However, there exist situations where pointer-usize-pointer roundtrips cannot be avoided, or
324
+ //! where avoiding them would require major refactoring. Legacy platform APIs also regularly assume
325
+ //! that `usize` can capture all the information that makes up a pointer. The goal of Strict
326
+ //! Provenance is not to rule out such code; the goal is to put all the *other* pointer-manipulating
327
+ //! code onto a more solid foundation. Strict Provenance is about improving the situation where
328
+ //! possible (all the code that can be written with Strict Provenance) without making things worse
329
+ //! for situations where Strict Provenance is insufficient.
330
+ //!
331
+ //! For these situations, there is a highly experimental extension to Strict Provenance called
332
+ //! *Exposed Provenance*. This extension permits pointer-usize-pointer roundtrips. However, its
333
+ //! semantics are on much less solid footing than Strict Provenance, and at this point it is not yet
334
+ //! clear where a satisfying unambiguous semantics can be defined for Exposed Provenance.
335
+ //! Furthermore, Exposed Provenance will not work (well) with tools like [Miri] and [CHERI].
336
+ //!
337
+ //! Exposed Provenance is provided by the [`expose_addr`] and [`from_exposed_addr`] methods, which
338
+ //! are meant to replace `as` casts between pointers and integers. [`expose_addr`] is a lot like
331
339
//! [`addr`], but additionally adds the provenance of the pointer to a global list of 'exposed'
332
340
//! provenances. (This list is purely conceptual, it exists for the purpose of specifying Rust but
333
341
//! is not materialized in actual executions, except in tools like [Miri].) [`from_exposed_addr`]
341
349
//! there is *no* previously 'exposed' provenance that justifies the way the returned pointer will
342
350
//! be used, the program has undefined behavior.
343
351
//!
344
- //! Using [`expose_addr`] or [`from_exposed_addr`] (or the equivalent `as` casts) means that code is
352
+ //! Using [`expose_addr`] or [`from_exposed_addr`] (or the `as` casts) means that code is
345
353
//! *not* following Strict Provenance rules. The goal of the Strict Provenance experiment is to
346
- //! determine whether it is possible to use Rust without [`expose_addr`] and [`from_exposed_addr`].
347
- //! If this is successful, it would be a major win for avoiding specification complexity and to
354
+ //! determine how far one can get in Rust without the use of [`expose_addr`] and
355
+ //! [`from_exposed_addr`], and to encourage code to be written with Strict Provenance APIs only.
356
+ //! Maximizing the amount of such code is a major win for avoiding specification complexity and to
348
357
//! facilitate adoption of tools like [CHERI] and [Miri] that can be a big help in increasing the
349
358
//! confidence in (unsafe) Rust code.
350
359
//!
@@ -619,12 +628,12 @@ pub const fn invalid_mut<T>(addr: usize) -> *mut T {
619
628
620
629
/// Convert an address back to a pointer, picking up a previously 'exposed' provenance.
621
630
///
622
- /// This is equivalent to `addr as *const T`. The provenance of the returned pointer is that of *any*
623
- /// pointer that was previously exposed by passing it to [`expose_addr`][pointer::expose_addr],
624
- /// or a `ptr as usize` cast. In addition, memory which is outside the control of the Rust abstract
625
- /// machine (MMIO registers, for example) is always considered to be exposed, so long as this memory
626
- /// is disjoint from memory that will be used by the abstract machine such as the stack, heap,
627
- /// and statics.
631
+ /// This is a more rigorously specified alternative to `addr as *const T`. The provenance of the
632
+ /// returned pointer is that of *any* pointer that was previously exposed by passing it to
633
+ /// [`expose_addr`][pointer::expose_addr], or a `ptr as usize` cast. In addition, memory which is
634
+ /// outside the control of the Rust abstract machine (MMIO registers, for example) is always
635
+ /// considered to be exposed, so long as this memory is disjoint from memory that will be used by
636
+ /// the abstract machine such as the stack, heap, and statics.
628
637
///
629
638
/// If there is no 'exposed' provenance that justifies the way this pointer will be used,
630
639
/// the program has undefined behavior. In particular, the aliasing rules still apply: pointers
@@ -639,7 +648,8 @@ pub const fn invalid_mut<T>(addr: usize) -> *mut T {
639
648
/// On platforms with multiple address spaces, it is your responsibility to ensure that the
640
649
/// address makes sense in the address space that this pointer will be used with.
641
650
///
642
- /// Using this method means that code is *not* following strict provenance rules. "Guessing" a
651
+ /// Using this function means that code is *not* following [Strict
652
+ /// Provenance][../index.html#strict-provenance] rules. "Guessing" a
643
653
/// suitable provenance complicates specification and reasoning and may not be supported by
644
654
/// tools that help you to stay conformant with the Rust memory model, so it is recommended to
645
655
/// use [`with_addr`][pointer::with_addr] wherever possible.
@@ -649,13 +659,13 @@ pub const fn invalid_mut<T>(addr: usize) -> *mut T {
649
659
/// since it is generally not possible to actually *compute* which provenance the returned
650
660
/// pointer has to pick up.
651
661
///
652
- /// This API and its claimed semantics are part of the Strict Provenance experiment, see the
653
- /// [module documentation][crate::ptr] for details .
662
+ /// It is unclear whether this function can be given a satisfying unambiguous specification. This
663
+ /// API and its claimed semantics are part of [Exposed Provenance][../index.html#exposed-provenance] .
654
664
#[ must_use]
655
665
#[ inline( always) ]
656
- #[ unstable( feature = "strict_provenance " , issue = "95228" ) ]
666
+ #[ unstable( feature = "exposed_provenance " , issue = "95228" ) ]
657
667
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
658
- #[ allow( fuzzy_provenance_casts) ] // this *is* the strict provenance API one should use instead
668
+ #[ allow( fuzzy_provenance_casts) ] // this *is* the explicit provenance API one should use instead
659
669
pub fn from_exposed_addr < T > ( addr : usize ) -> * const T
660
670
where
661
671
T : Sized ,
@@ -666,18 +676,20 @@ where
666
676
667
677
/// Convert an address back to a mutable pointer, picking up a previously 'exposed' provenance.
668
678
///
669
- /// This is equivalent to `addr as *mut T`. The provenance of the returned pointer is that of *any*
670
- /// pointer that was previously passed to [`expose_addr`][pointer::expose_addr] or a `ptr as usize`
671
- /// cast. If there is no previously 'exposed' provenance that justifies the way this pointer will be
672
- /// used, the program has undefined behavior. Note that there is no algorithm that decides which
673
- /// provenance will be used. You can think of this as "guessing" the right provenance, and the guess
674
- /// will be "maximally in your favor", in the sense that if there is any way to avoid undefined
675
- /// behavior, then that is the guess that will be taken.
679
+ /// This is a more rigorously specified alternative to `addr as *mut T`. The provenance of the
680
+ /// returned pointer is that of *any* pointer that was previously passed to
681
+ /// [`expose_addr`][pointer::expose_addr] or a `ptr as usize` cast. If there is no previously
682
+ /// 'exposed' provenance that justifies the way this pointer will be used, the program has undefined
683
+ /// behavior. Note that there is no algorithm that decides which provenance will be used. You can
684
+ /// think of this as "guessing" the right provenance, and the guess will be "maximally in your
685
+ /// favor", in the sense that if there is any way to avoid undefined behavior, then that is the
686
+ /// guess that will be taken.
676
687
///
677
688
/// On platforms with multiple address spaces, it is your responsibility to ensure that the
678
689
/// address makes sense in the address space that this pointer will be used with.
679
690
///
680
- /// Using this method means that code is *not* following strict provenance rules. "Guessing" a
691
+ /// Using this function means that code is *not* following [Strict
692
+ /// Provenance][../index.html#strict-provenance] rules. "Guessing" a
681
693
/// suitable provenance complicates specification and reasoning and may not be supported by
682
694
/// tools that help you to stay conformant with the Rust memory model, so it is recommended to
683
695
/// use [`with_addr`][pointer::with_addr] wherever possible.
@@ -687,13 +699,13 @@ where
687
699
/// since it is generally not possible to actually *compute* which provenance the returned
688
700
/// pointer has to pick up.
689
701
///
690
- /// This API and its claimed semantics are part of the Strict Provenance experiment, see the
691
- /// [module documentation][crate::ptr] for details .
702
+ /// It is unclear whether this function can be given a satisfying unambiguous specification. This
703
+ /// API and its claimed semantics are part of [Exposed Provenance][../index.html#exposed-provenance] .
692
704
#[ must_use]
693
705
#[ inline( always) ]
694
- #[ unstable( feature = "strict_provenance " , issue = "95228" ) ]
706
+ #[ unstable( feature = "exposed_provenance " , issue = "95228" ) ]
695
707
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
696
- #[ allow( fuzzy_provenance_casts) ] // this *is* the strict provenance API one should use instead
708
+ #[ allow( fuzzy_provenance_casts) ] // this *is* the explicit provenance API one should use instead
697
709
pub fn from_exposed_addr_mut < T > ( addr : usize ) -> * mut T
698
710
where
699
711
T : Sized ,
0 commit comments