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
Copy file name to clipboardExpand all lines: src/advanced_unsafety/invalid_values.md
+11-2Lines changed: 11 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -34,6 +34,12 @@ It's also currently invalid for `Vec<T>` to have a null pointer for its buffer!
34
34
35
35
There are a lot of other reasons that a pointer type may not be valid, but these are the ones where the bit pattern is statically known to be invalid regardless of context. We'll be covering these in more depth in other chapters (@@note: where?), but, for example, all of these pointers must not only be non-null, they must also point to an actual valid instance of that type at all times (except `Vec<T>`, which is allowed to refer to invalid-but-aligned-and-non-null memory when it is empty)
36
36
37
+
#### "shallow" vs "deep" validity
38
+
39
+
40
+
An open question in Rust's model is whether references and reference-like types have "shallow" validity (roughly, the rules above), or "deep" validity (where a reference is valid only when the pointed-to data is valid, and that applies transitively). This issue is tracked upstream as [UGC #77](https://github.com/rust-lang/unsafe-code-guidelines/issues/77). The current discussion seems to skew towards shallow validity as opposed to deep validity, but this may change.
41
+
42
+
For the purposes of _writing_ unsafe code, it is convenient to imagine the boundary as being such that `&`/`&mut` references should never point to invalid memory. However, when auditing existing unsafe code it may be okay to allow scenarios that assume only shallow validity is required, depending on your risk appetite.
37
43
38
44
### Enums with invalid values
39
45
@@ -90,9 +96,11 @@ As a library user you may not assume anything about the representation of a libr
90
96
## When you might end up making an invalid value
91
97
92
98
93
-
Invalid values have a chance to crop up when you're reinterpreting a chunk of memory as a value of a different type. This can happen when calling [`mem::transmute()`], [`mem::transmute_copy()`], or [`mem::zeroed()`], when casting a reference to a region of memory into one of a different type, or when accessing the wrong variant of a `union`. The value need not be on the stack to be considered invalid: if you gin up an `&bool` that points to a bit pattern that is not a valid `bool`, that is instantly UB even if you don't read from the reference.
99
+
Invalid values have a chance to crop up when you're reinterpreting a chunk of memory as a value of a different type. This can happen when calling [`mem::transmute()`], [`mem::transmute_copy()`], or [`mem::zeroed()`], when casting a reference to a region of memory into one of a different type, or when accessing the wrong variant of a `union`. The value need not be on the stack to be considered invalid: if you gin up an `&bool` that points to a bit pattern that is not a valid `bool`, that can instantly be UB (in a "deep validity" world) even if you don't read from the reference.
100
+
101
+
Note that since [uninitialized memory][uninit-chapter] is a type of invalid value, any way to produce uninitialized memory (including [`mem::uninitialized()`]) is also a way of producing invalid values.
94
102
95
-
They can also happen when receiving values over FFI where either the signature of the function is incorrect (e.g. saying an FFI function accepts `bool` when the other side thinks it accepts a `u8`), or where there are differences in notions of validity across languages.
103
+
Invalid values can also be created when receiving values over FFI where either the signature of the function is incorrect (e.g. saying an FFI function accepts `bool` when the other side thinks it accepts a `u8`), or where there are differences in notions of validity across languages.
96
104
97
105
A subtle case of this comes up occasionally in FFI code due to differences in expectations between how enums are used in Rust and C.
98
106
@@ -131,6 +139,7 @@ This is not an exhaustive list: ultimately, having an invalid value is UB and it
0 commit comments