From 718104f9d2b92860896490c3f4dea4a7ca273be5 Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Tue, 16 Dec 2025 03:30:26 +0900 Subject: [PATCH 01/28] feat: split into own file --- .../values/gui_uyp3mCj77FS8.rst.inc | 203 ++++++++++++++++++ src/coding-guidelines/values/index.rst | 1 + 2 files changed, 204 insertions(+) create mode 100644 src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc new file mode 100644 index 000000000..c250f0bc9 --- /dev/null +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -0,0 +1,203 @@ +.. SPDX-License-Identifier: MIT OR Apache-2.0 + SPDX-FileCopyrightText: The Coding Guidelines Subcommittee Contributors + +.. default-domain:: coding-guidelines + +.. guideline:: Do not create values from uninitialized memory except for union fields + :id: gui_uyp3mCj77FS8 + :category: mandatory + :status: draft + :release: + :fls: fls_6lg0oaaopc26 + :decidability: undecidable + :scope: system + :tags: undefined-behavior, unsafe + + A program shall not create a value of any type from uninitialized memory, + except when accessing a field of a union type, + where such reads are explicitly defined to be permitted even if the bytes of that field are uninitialized. + It is prohibited to interpret uninitialized memory as a value of any Rust type such as a + primitive, aggregate, reference, pointer, struct, enum, array, or tuple. + + **Exception:** You can access a field of a union even when the backing bytes of that field are uninitialized provided that: + + - The resulting value has an unspecified but well-defined bit pattern. + - Interpreting that value must still comply with the requirements of the accessed type + (e.g., no invalid enum discriminants, no invalid pointer values, etc.). + + For example, reading an uninitialized u32 field of a union is allowed; + reading an uninitialized bool field is disallowed because not all bit patterns are valid. + + .. rationale:: + :id: rat_kjFRrhpS8Wu6 + :status: draft + + Rust's memory model treats all types except unions as having an invariant that all bytes must be initialized before a value may be constructed. + Reading uninitialized memory: + + - creates undefined behavior for most types, + - may violate niche or discriminant validity, + - may create invalid pointer values, or + - may produce values that violate type invariants. + + The sole exception is that unions work like C unions: any union field may be read, even if it was never written. + The resulting bytes must, however, form a valid representation for the field's type, + which is not guaranteed if the union contains arbitrary data. + + .. non_compliant_example:: + :id: non_compl_ex_Qb5GqYTP6db1 + :status: draft + + This noncompliant example creates a value of type ``u32`` from uninitialized memory via + `assume_init `_: + + .. rust-example:: + + use std::mem::MaybeUninit; + + # fn main() { + let x: u32 = unsafe { MaybeUninit::uninit().assume_init() }; // UB + # } + + .. compliant_example:: + :id: compl_ex_Ke869nSXuShU + :status: draft + + Types such as ``u8``, ``u16``, ``u32``, and ``i128`` allow all possible bit patterns. + Provided the memory is initialized, there is no undefined behavior. + + .. rust-example:: + + union U { + n: u32, + bytes: [u8; 4], + } + + # fn main() { + let u = U { bytes: [0xFF, 0xEE, 0xDD, 0xCC] }; + let n = unsafe { u.n }; // OK — all bit patterns valid for u32 + # } + + .. compliant_example:: + :id: compl_ex_Ke869nSXuShV + :status: draft + + This compliant example calls the ``write`` function to fully initialize low-level memory. + + .. rust-example:: + + use std::mem::MaybeUninit; + + # fn main() { + let mut x = MaybeUninit::::uninit(); + x.write(42); + let val = unsafe { x.assume_init() }; // OK — value was fully initialized + # } + + .. non_compliant_example:: + :id: non_compl_ex_Qb5GqYTP6db2 + :status: draft + + Creating a reference from arbitrary or uninitialized bytes is always undefined behavior. + References must be valid, aligned, properly dereferenceable, and non-null. + Uninitialized memory cannot satisfy these invariants. + + .. rust-example:: + + use std::mem::MaybeUninit; + + # fn main() { + let r: &u32 = unsafe { MaybeUninit::uninit().assume_init() }; // UB — invalid reference + # } + + .. non_compliant_example:: + :id: non_compl_ex_Qb5GqYTP6db4 + :status: draft + + Not all bit patterns are valid pointers for all operations (e.g., provenance rules). + You cannot create a pointer from unspecified bytes. + Even a raw pointer type (e.g., ``*const T``) has validity rules. + + .. rust-example:: + + use std::mem::MaybeUninit; + + # fn main() { + let p: *const u32 = unsafe { MaybeUninit::uninit().assume_init() }; // UB + # } + .. non_compliant_example:: + :id: non_compl_ex_Qb5GqYTP6db5 + :status: draft + + Array elements must individually be valid values. + + .. rust-example:: + + use std::mem::MaybeUninit; + + # fn main() { + let mut arr: [MaybeUninit; 4] = unsafe { MaybeUninit::uninit().assume_init() }; + let a = unsafe { std::mem::transmute::<_, [u8; 4]>(arr) }; // UB — not all elements initialized + # } + + .. compliant_example:: + :id: compl_ex_Ke869nSXuShT + :status: draft + + The following code reads a union field: + + .. rust-example:: + + union U { + x: u32, + y: f32, + } + + # fn main() { + let u = U { x: 123 }; // write to one field + let f = unsafe { u.y }; // reading the other field is allowed + # } + + .. non_compliant_example:: + :id: non_compl_ex_Qb5GqYTP6db3 + :status: draft + + Even though unions allow reads of any field, not all bit patterns are valid for a ``bool``. + Unions do not relax type validity requirements. + Only the read itself is allowed; + the resulting bytes must still be a valid bool. + + .. rust-example:: + + union U { + b: bool, + x: u8, + } + + # fn main() { + let u = U { x: 255 }; // 255 is not a valid bool representation + let b = unsafe { u.b }; // UB — invalid bool + # } + + .. compliant_example:: + :id: compl_ex_Ke869nSXuShW + :status: draft + + Accessing padding bytes is allowed if not interpreted as typed data: + + .. rust-example:: + + #[repr(C)] + struct S { + a: u8, + b: u32, + } + + # fn main() { + let mut buf = [0u8; std::mem::size_of::()]; + buf[0] = 10; + buf[1] = 20; // writing padding is fine + + let p = buf.as_ptr() as *const S; + let s = unsafe { p.read_unaligned() }; // OK — all *fields* are initialized (padding doesn't matter) + # } diff --git a/src/coding-guidelines/values/index.rst b/src/coding-guidelines/values/index.rst index c2419fc7b..16eb6636c 100644 --- a/src/coding-guidelines/values/index.rst +++ b/src/coding-guidelines/values/index.rst @@ -6,3 +6,4 @@ Values ====== +.. include:: gui_uyp3mCj77FS8.rst.inc From 0d91f92ada7c1fd79eace35af089698c45f31c6c Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Mon, 15 Dec 2025 18:23:37 -0500 Subject: [PATCH 02/28] feat: remove description related to union deunionfied --- .../values/gui_uyp3mCj77FS8.rst.inc | 82 ++----------------- 1 file changed, 5 insertions(+), 77 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index c250f0bc9..6f979401c 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -3,7 +3,7 @@ .. default-domain:: coding-guidelines -.. guideline:: Do not create values from uninitialized memory except for union fields +.. guideline:: Do not create values from uninitialized memory :id: gui_uyp3mCj77FS8 :category: mandatory :status: draft @@ -13,21 +13,11 @@ :scope: system :tags: undefined-behavior, unsafe - A program shall not create a value of any type from uninitialized memory, - except when accessing a field of a union type, - where such reads are explicitly defined to be permitted even if the bytes of that field are uninitialized. + A program shall not create a value of any non-``union`` type from uninitialized memory. + Reading from a union is covered by a separate rule, "Do not read from union fields that may contain uninitialized bytes". It is prohibited to interpret uninitialized memory as a value of any Rust type such as a primitive, aggregate, reference, pointer, struct, enum, array, or tuple. - - **Exception:** You can access a field of a union even when the backing bytes of that field are uninitialized provided that: - - - The resulting value has an unspecified but well-defined bit pattern. - - Interpreting that value must still comply with the requirements of the accessed type - (e.g., no invalid enum discriminants, no invalid pointer values, etc.). - - For example, reading an uninitialized u32 field of a union is allowed; - reading an uninitialized bool field is disallowed because not all bit patterns are valid. - + .. rationale:: :id: rat_kjFRrhpS8Wu6 :status: draft @@ -39,11 +29,7 @@ - may violate niche or discriminant validity, - may create invalid pointer values, or - may produce values that violate type invariants. - - The sole exception is that unions work like C unions: any union field may be read, even if it was never written. - The resulting bytes must, however, form a valid representation for the field's type, - which is not guaranteed if the union contains arbitrary data. - + .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db1 :status: draft @@ -59,25 +45,6 @@ let x: u32 = unsafe { MaybeUninit::uninit().assume_init() }; // UB # } - .. compliant_example:: - :id: compl_ex_Ke869nSXuShU - :status: draft - - Types such as ``u8``, ``u16``, ``u32``, and ``i128`` allow all possible bit patterns. - Provided the memory is initialized, there is no undefined behavior. - - .. rust-example:: - - union U { - n: u32, - bytes: [u8; 4], - } - - # fn main() { - let u = U { bytes: [0xFF, 0xEE, 0xDD, 0xCC] }; - let n = unsafe { u.n }; // OK — all bit patterns valid for u32 - # } - .. compliant_example:: :id: compl_ex_Ke869nSXuShV :status: draft @@ -140,45 +107,6 @@ let a = unsafe { std::mem::transmute::<_, [u8; 4]>(arr) }; // UB — not all elements initialized # } - .. compliant_example:: - :id: compl_ex_Ke869nSXuShT - :status: draft - - The following code reads a union field: - - .. rust-example:: - - union U { - x: u32, - y: f32, - } - - # fn main() { - let u = U { x: 123 }; // write to one field - let f = unsafe { u.y }; // reading the other field is allowed - # } - - .. non_compliant_example:: - :id: non_compl_ex_Qb5GqYTP6db3 - :status: draft - - Even though unions allow reads of any field, not all bit patterns are valid for a ``bool``. - Unions do not relax type validity requirements. - Only the read itself is allowed; - the resulting bytes must still be a valid bool. - - .. rust-example:: - - union U { - b: bool, - x: u8, - } - - # fn main() { - let u = U { x: 255 }; // 255 is not a valid bool representation - let b = unsafe { u.b }; // UB — invalid bool - # } - .. compliant_example:: :id: compl_ex_Ke869nSXuShW :status: draft From 476b76adc3bf20ad7061279da7d5e37b96a8935f Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 17 Dec 2025 12:14:44 -0500 Subject: [PATCH 03/28] Update gui_uyp3mCj77FS8.rst.inc had a slightly older version, so I replaced it with the latest. --- .../values/gui_uyp3mCj77FS8.rst.inc | 99 +++++++++++++------ 1 file changed, 71 insertions(+), 28 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 6f979401c..b6fe02334 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -13,10 +13,10 @@ :scope: system :tags: undefined-behavior, unsafe - A program shall not create a value of any non-``union`` type from uninitialized memory. - Reading from a union is covered by a separate rule, "Do not read from union fields that may contain uninitialized bytes". - It is prohibited to interpret uninitialized memory as a value of any Rust type such as a - primitive, aggregate, reference, pointer, struct, enum, array, or tuple. + A program shall not create a value of any non-union type from uninitialized memory. + Reading from a union is covered by a separate rule, `Do not read from union fields that may contain uninitialized bytes + `_. + It is prohibited to interpret uninitialized memory as a value of any type. .. rationale:: :id: rat_kjFRrhpS8Wu6 @@ -34,38 +34,45 @@ :id: non_compl_ex_Qb5GqYTP6db1 :status: draft - This noncompliant example creates a value of type ``u32`` from uninitialized memory via + This noncompliant example attempts to create a value of type ``u32`` from uninitialized memory by calling `assume_init `_: .. rust-example:: use std::mem::MaybeUninit; - # fn main() { - let x: u32 = unsafe { MaybeUninit::uninit().assume_init() }; // UB - # } + fn main() { + // Reading uninitialized memory as a typed value is undefined behavior + let x: u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant + } .. compliant_example:: :id: compl_ex_Ke869nSXuShV :status: draft - This compliant example calls the ``write`` function to fully initialize low-level memory. + This compliant example creates an uninitialized allocation of type ``MaybeUninit``. + The code calls the ``write`` function to write the value 42 into the ``MaybeUninit``. + The call to ``assume_init`` asserts that the value is initialized and extracts the value of type ``u64``. + This is valid because the memory has been initialized by the call to ``write(42)``. + This is the canonical safe pattern for using ``MaybeUninit``. .. rust-example:: use std::mem::MaybeUninit; - # fn main() { - let mut x = MaybeUninit::::uninit(); - x.write(42); - let val = unsafe { x.assume_init() }; // OK — value was fully initialized - # } + fn main() { + let mut x = MaybeUninit::::uninit(); + x.write(42); + // x is fully initialized + let val = unsafe { x.assume_init() }; // compliant + } .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db2 :status: draft - Creating a reference from arbitrary or uninitialized bytes is always undefined behavior. + This noncompliant example creates a reference from uninitialized memory. + Creating a reference from arbitrary or uninitialized bytes is undefined behavior. References must be valid, aligned, properly dereferenceable, and non-null. Uninitialized memory cannot satisfy these invariants. @@ -74,13 +81,15 @@ use std::mem::MaybeUninit; # fn main() { - let r: &u32 = unsafe { MaybeUninit::uninit().assume_init() }; // UB — invalid reference + // Reading an invalid reference is undefined behavior + let r: &u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant # } .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db4 :status: draft + This noncompliant example creates a pointer from uninitialized memory. Not all bit patterns are valid pointers for all operations (e.g., provenance rules). You cannot create a pointer from unspecified bytes. Even a raw pointer type (e.g., ``*const T``) has validity rules. @@ -89,14 +98,26 @@ use std::mem::MaybeUninit; - # fn main() { - let p: *const u32 = unsafe { MaybeUninit::uninit().assume_init() }; // UB - # } + fn main() { + let p: *const u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant + } + .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db5 :status: draft Array elements must individually be valid values. + This noncompliant example creates an uninitialized array of four ``u8`` values. + The call to ``.assume_init`` asserting that the array is initialized is valid here because + an array of ``MaybeUninit`` can contain uninitialized bytes. + The call to ``std::mem::transmute`` reinterprets the ``[MaybeUninit; 4]`` as ``[u8; 4]``. + This is undefined behavior, because the bytes were never initialized. + Even though all bit patterns (0-255) are valid for the ``u8`` type, the values must be initalized. + + ``MaybeUninit`` can hold uninitialized memory — that's its purpose. + ``u8`` cannot hold uninitialized memory — all 8 bits must be defined. + The ``transmute`` performs a typed read that asserts the bytes are valid ``u8`` values. + Reading uninitialized bytes as a concrete type is always undefined behavior. .. rust-example:: @@ -104,28 +125,50 @@ # fn main() { let mut arr: [MaybeUninit; 4] = unsafe { MaybeUninit::uninit().assume_init() }; - let a = unsafe { std::mem::transmute::<_, [u8; 4]>(arr) }; // UB — not all elements initialized + // Undefined behavior constructing an array of 'u8' from uninitialized memory. + let a = unsafe { std::mem::transmute::<_, [u8; 4]>(arr) }; // noncompliant # } .. compliant_example:: :id: compl_ex_Ke869nSXuShW :status: draft - Accessing padding bytes is allowed if not interpreted as typed data: + This compliant example defines a C-layout ``struct`` with: + + * ``a``: 1 byte at offset 0 + * 3 bytes of padding (to align ``b`` to 4 bytes) + * ``b``: 4 bytes at offset 4 + * Total size: 8 bytes + + The variable ``buf`` is a fully, zero-initialized 8-byte buffer. + + The first wo bytes of ``buf`` are overwritten. + The byte buffer ``buf`` pointer is cast to a pointer to ``S``. + The call to ``read_unaligned`` reads the ``struct`` without requiring alignment. + + This example is compliant because: + + * All bytes are initialized (buffer was zero-initialized) + * All fields have valid values (``u8`` and ``u32`` accept any bit pattern) + * Padding bytes don't need to be any specific value + * ``read_unaligned`` handles the alignment issue .. rust-example:: #[repr(C)] + #[derive(Debug)] struct S { a: u8, b: u32, } - # fn main() { - let mut buf = [0u8; std::mem::size_of::()]; - buf[0] = 10; - buf[1] = 20; // writing padding is fine + fn main() { + let mut buf = [0u8; std::mem::size_of::()]; + buf[0] = 10; + buf[1] = 20; // writing padding is fine - let p = buf.as_ptr() as *const S; - let s = unsafe { p.read_unaligned() }; // OK — all *fields* are initialized (padding doesn't matter) - # } + let p = buf.as_ptr() as *const S; + // All fields are initialized (padding doesn't matter) + let s = unsafe { p.read_unaligned() }; // compliant + println!("{:?}", s); + } From 97430362d9735812ccd55cedf8d4068e69cda8de Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 17 Dec 2025 12:37:16 -0500 Subject: [PATCH 04/28] Update gui_uyp3mCj77FS8.rst.inc --- .../values/gui_uyp3mCj77FS8.rst.inc | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index b6fe02334..9d6435ee7 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -3,7 +3,7 @@ .. default-domain:: coding-guidelines -.. guideline:: Do not create values from uninitialized memory +.. guideline:: Do not read uninitialized memory as a typed value :id: gui_uyp3mCj77FS8 :category: mandatory :status: draft @@ -13,22 +13,19 @@ :scope: system :tags: undefined-behavior, unsafe - A program shall not create a value of any non-union type from uninitialized memory. + Do not read uninitialized memory of any non-union type as a typed value. + This is sometimes referred to as *transmuting* or *read-at-type*. + Memory can remain uninitialized if it is not read as a type. + Reading from a union is covered by a separate rule, `Do not read from union fields that may contain uninitialized bytes `_. - It is prohibited to interpret uninitialized memory as a value of any type. .. rationale:: :id: rat_kjFRrhpS8Wu6 :status: draft - Rust's memory model treats all types except unions as having an invariant that all bytes must be initialized before a value may be constructed. - Reading uninitialized memory: - - - creates undefined behavior for most types, - - may violate niche or discriminant validity, - - may create invalid pointer values, or - - may produce values that violate type invariants. + Rust's memory model requires that all bytes must be initialized before being read as a typed value. + Reading uninitialized memory as a typed value is undefined behavior. .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db1 @@ -80,10 +77,10 @@ use std::mem::MaybeUninit; - # fn main() { - // Reading an invalid reference is undefined behavior - let r: &u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant - # } + fn main() { + // Reading an invalid reference is undefined behavior + let r: &u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant + } .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db4 From 26eaa0f4b0a88713d748ded25faf15ccb86175fa Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 17 Dec 2025 15:47:40 -0500 Subject: [PATCH 05/28] Update gui_uyp3mCj77FS8.rst.inc --- .../values/gui_uyp3mCj77FS8.rst.inc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 9d6435ee7..ae7ff0951 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -19,6 +19,14 @@ Reading from a union is covered by a separate rule, `Do not read from union fields that may contain uninitialized bytes `_. + + Calling `assume_init `_, + or related functions, is treated in the same manner as a typed read. + Calling these function when on memory that is not yet fully initialized causes immediate undefined behavior. + The memory must be properly initialized according to the requirements of the variable’s type. + For example, a variable of reference type must be aligned and non-null. + Similarly, entirely uninitialized memory may have any content, while a ``bool`` must always be ``true`` or ``false``. + Consequently, reading an uninitialized ``bool`` is undefined behavior. .. rationale:: :id: rat_kjFRrhpS8Wu6 @@ -31,8 +39,8 @@ :id: non_compl_ex_Qb5GqYTP6db1 :status: draft - This noncompliant example attempts to create a value of type ``u32`` from uninitialized memory by calling - `assume_init `_: + This noncompliant example extracts a value of type ``u32`` from uninitialized memory within a ``MaybeUninit`` container, + which is undefined behavior. .. rust-example:: From 68c48f2788dafd7c39b436b0584317334c65967a Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 17 Dec 2025 19:51:42 -0500 Subject: [PATCH 06/28] Update gui_uyp3mCj77FS8.rst.inc added another example and some clarification for references --- .../values/gui_uyp3mCj77FS8.rst.inc | 54 ++++++++++++++++--- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index ae7ff0951..0574945fb 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -24,7 +24,7 @@ or related functions, is treated in the same manner as a typed read. Calling these function when on memory that is not yet fully initialized causes immediate undefined behavior. The memory must be properly initialized according to the requirements of the variable’s type. - For example, a variable of reference type must be aligned and non-null. + For example, a variable of reference type must be aligned, non-null, and point to valid memory. Similarly, entirely uninitialized memory may have any content, while a ``bool`` must always be ``true`` or ``false``. Consequently, reading an uninitialized ``bool`` is undefined behavior. @@ -71,6 +71,23 @@ // x is fully initialized let val = unsafe { x.assume_init() }; // compliant } + + .. non_compliant_example:: + :id: non_compl_ex_Qb5GqYTP6db4 + :status: draft + + This noncompliant example creates a pointer from uninitialized memory. + Not all bit patterns are valid pointers for all operations (e.g., provenance rules). + You cannot create a pointer from unspecified bytes. + Even a raw pointer type (e.g., ``*const T``) has validity rules. + + .. rust-example:: + + use std::mem::MaybeUninit; + + fn main() { + let p: *const u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant + } .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db2 @@ -78,7 +95,7 @@ This noncompliant example creates a reference from uninitialized memory. Creating a reference from arbitrary or uninitialized bytes is undefined behavior. - References must be valid, aligned, properly dereferenceable, and non-null. + References must be valid, aligned, dereferenceable, and non-null. Uninitialized memory cannot satisfy these invariants. .. rust-example:: @@ -91,20 +108,41 @@ } .. non_compliant_example:: - :id: non_compl_ex_Qb5GqYTP6db4 + :id: non_compl_ex_Qb5GqYTP6db3 :status: draft - This noncompliant example creates a pointer from uninitialized memory. - Not all bit patterns are valid pointers for all operations (e.g., provenance rules). - You cannot create a pointer from unspecified bytes. - Even a raw pointer type (e.g., ``*const T``) has validity rules. + This noncompliant example creates a reference from uninitialized memory. + The ``create_ref`` function has undefined behavior when creating a reference from a dangling pointer. + It creates uninitialized memory sized for a reference (``&u8``). + A reference is essentially a pointer (8 bytes on 64-bit systems). + ``&raw mut uninit`` retreives a raw mutable pointer to the ``MaybeUninit``. + The ``.cast::<*const u8>()`` reinterprets it as a pointer to a raw pointer. + The call to ``.write(ptr::dangling())`` writes a dangling pointer value. + This creates a pointer which is non-null, aligned, but does not point to valid, initialized value. + The call to ``assume_init`` asserts the ``MaybeUninit<&u8>`` is a valid ``&u8`` reference + A reference (``&T``) has stricter requirements than a raw pointer. + Even though the bit pattern looks like a valid pointer, + the semantic requirements for a reference are violated. + The compiler is allowed to assume references always point to valid data, + so this can cause miscompilation. .. rust-example:: use std::mem::MaybeUninit; + use std::ptr; + + fn create_ref() { + let mut uninit: MaybeUninit<&u8> = MaybeUninit::uninit(); + unsafe { + // write non-null and aligned address. + (&raw mut uninit).cast::<*const u8>().write(ptr::dangling()); + // Undefined behavior occurs when asseting 'uninit' is a valid reference. + let _init = uninit.assume_init(); // noncompliant + } + } fn main() { - let p: *const u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant + create_ref(); } .. non_compliant_example:: From aaa83a4f8c1ab420dcece37103d8a0a3683fdeb0 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 17 Dec 2025 20:10:23 -0500 Subject: [PATCH 07/28] Update gui_uyp3mCj77FS8.rst.inc --- .../values/gui_uyp3mCj77FS8.rst.inc | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 0574945fb..91ddcfe6a 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -20,9 +20,16 @@ Reading from a union is covered by a separate rule, `Do not read from union fields that may contain uninitialized bytes `_. - Calling `assume_init `_, - or related functions, is treated in the same manner as a typed read. - Calling these function when on memory that is not yet fully initialized causes immediate undefined behavior. + Calling `assume_init `_ or + any of the following related functions is treated in the same manner as a typed read: + + * ``assume_init_drop`` + * ``assume_init_mut`` + * ``assume_init_read`` + * ``assume_init_ref`` + * ``array_assume_init`` + + Calling any of these function when on memory that is not yet fully initialized is undefined behavior. The memory must be properly initialized according to the requirements of the variable’s type. For example, a variable of reference type must be aligned, non-null, and point to valid memory. Similarly, entirely uninitialized memory may have any content, while a ``bool`` must always be ``true`` or ``false``. @@ -166,11 +173,11 @@ use std::mem::MaybeUninit; - # fn main() { - let mut arr: [MaybeUninit; 4] = unsafe { MaybeUninit::uninit().assume_init() }; - // Undefined behavior constructing an array of 'u8' from uninitialized memory. - let a = unsafe { std::mem::transmute::<_, [u8; 4]>(arr) }; // noncompliant - # } + fn main() { + let mut arr: [MaybeUninit; 4] = unsafe { MaybeUninit::uninit().assume_init() }; + // Undefined behavior constructing an array of 'u8' from uninitialized memory. + let a = unsafe { std::mem::transmute::<_, [u8; 4]>(arr) }; // noncompliant + } .. compliant_example:: :id: compl_ex_Ke869nSXuShW From a4c6c8398d8acf3b7ba51220420a5a0f9af17860 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 17 Dec 2025 20:14:08 -0500 Subject: [PATCH 08/28] Update gui_uyp3mCj77FS8.rst.inc spelling --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 91ddcfe6a..4bc3cbc37 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -122,7 +122,7 @@ The ``create_ref`` function has undefined behavior when creating a reference from a dangling pointer. It creates uninitialized memory sized for a reference (``&u8``). A reference is essentially a pointer (8 bytes on 64-bit systems). - ``&raw mut uninit`` retreives a raw mutable pointer to the ``MaybeUninit``. + ``&raw mut uninit`` retrieves a raw mutable pointer to the ``MaybeUninit``. The ``.cast::<*const u8>()`` reinterprets it as a pointer to a raw pointer. The call to ``.write(ptr::dangling())`` writes a dangling pointer value. This creates a pointer which is non-null, aligned, but does not point to valid, initialized value. @@ -162,7 +162,7 @@ an array of ``MaybeUninit`` can contain uninitialized bytes. The call to ``std::mem::transmute`` reinterprets the ``[MaybeUninit; 4]`` as ``[u8; 4]``. This is undefined behavior, because the bytes were never initialized. - Even though all bit patterns (0-255) are valid for the ``u8`` type, the values must be initalized. + Even though all bit patterns (0-255) are valid for the ``u8`` type, the values must be initialized. ``MaybeUninit`` can hold uninitialized memory — that's its purpose. ``u8`` cannot hold uninitialized memory — all 8 bits must be defined. From 66b5a4b4f87e625ecd1e0fda56687c5bcf7c3f7f Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Thu, 18 Dec 2025 13:56:24 -0500 Subject: [PATCH 09/28] Update src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc Co-authored-by: increasing --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 4bc3cbc37..607e87ae1 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -143,7 +143,7 @@ unsafe { // write non-null and aligned address. (&raw mut uninit).cast::<*const u8>().write(ptr::dangling()); - // Undefined behavior occurs when asseting 'uninit' is a valid reference. + // Undefined behavior occurs when asserting 'uninit' is a valid reference. let _init = uninit.assume_init(); // noncompliant } } From e456a33269f05f1b988f8f7d38342e4451551968 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Fri, 2 Jan 2026 11:20:54 -0500 Subject: [PATCH 10/28] Update guideline on reading uninitialized memory Clarified guideline on reading uninitialized memory, specifying non-union types and adding citations for better understanding. --- .../values/gui_uyp3mCj77FS8.rst.inc | 126 +++++++++++++----- 1 file changed, 96 insertions(+), 30 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 607e87ae1..044c3d9bb 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -3,7 +3,7 @@ .. default-domain:: coding-guidelines -.. guideline:: Do not read uninitialized memory as a typed value +.. guideline:: Do not read uninitialized memory of any non-union type as a typed value :id: gui_uyp3mCj77FS8 :category: mandatory :status: draft @@ -13,15 +13,16 @@ :scope: system :tags: undefined-behavior, unsafe - Do not read uninitialized memory of any non-union type as a typed value. + Do not read uninitialized memory of any non-union type as a typed value + :cite:`RUSTNOMICON_UNINIT`. This is sometimes referred to as *transmuting* or *read-at-type*. Memory can remain uninitialized if it is not read as a type. - Reading from a union is covered by a separate rule, `Do not read from union fields that may contain uninitialized bytes + Reading from a union is covered by `Do not read from union fields that may contain uninitialized bytes `_. - Calling `assume_init `_ or - any of the following related functions is treated in the same manner as a typed read: + Calling `assume_init `_ + :cite:`MAYBEUNINIT_DOC` or any of the following related functions is treated in the same manner as a typed read: * ``assume_init_drop`` * ``assume_init_mut`` @@ -29,8 +30,8 @@ * ``assume_init_ref`` * ``array_assume_init`` - Calling any of these function when on memory that is not yet fully initialized is undefined behavior. - The memory must be properly initialized according to the requirements of the variable’s type. + Calling any of these function on memory that is not yet fully initialized is undefined behavior :cite:`RUST_REF_BEHAVIOR`. + The memory must be properly initialized according to the requirements of the variable's type :cite:`UCG_VALIDITY`. For example, a variable of reference type must be aligned, non-null, and point to valid memory. Similarly, entirely uninitialized memory may have any content, while a ``bool`` must always be ``true`` or ``false``. Consequently, reading an uninitialized ``bool`` is undefined behavior. @@ -39,8 +40,9 @@ :id: rat_kjFRrhpS8Wu6 :status: draft - Rust's memory model requires that all bytes must be initialized before being read as a typed value. - Reading uninitialized memory as a typed value is undefined behavior. + Rust's memory model requires that all bytes must be initialized before being read as a typed value :cite:`RUSTNOMICON_UNINIT` :cite:`FERROCENE_SPEC`. + Reading uninitialized memory as a typed value is undefined behavior :cite:`RUST_REF_BEHAVIOR`. + This guideline aligns with functional safety standards :cite:`ISO_26262` :cite:`IEC_61508` and secure coding practices :cite:`CERT_RUST`. .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db1 @@ -62,10 +64,10 @@ :id: compl_ex_Ke869nSXuShV :status: draft - This compliant example creates an uninitialized allocation of type ``MaybeUninit``. - The code calls the ``write`` function to write the value 42 into the ``MaybeUninit``. + This compliant example creates an uninitialized variable ``x`` of type ``MaybeUninit``. + The code calls the ``write`` function to write the value 42 to ``x``. The call to ``assume_init`` asserts that the value is initialized and extracts the value of type ``u64``. - This is valid because the memory has been initialized by the call to ``write(42)``. + This call is compliant with this rule because the memory has been properly initialized by the call to ``write(42)``. This is the canonical safe pattern for using ``MaybeUninit``. .. rust-example:: @@ -84,9 +86,9 @@ :status: draft This noncompliant example creates a pointer from uninitialized memory. - Not all bit patterns are valid pointers for all operations (e.g., provenance rules). + Not all bit patterns are valid pointers for all operations (e.g., provenance rules) :cite:`UCG_VALIDITY`. You cannot create a pointer from unspecified bytes. - Even a raw pointer type (e.g., ``*const T``) has validity rules. + Even a raw pointer type (e.g., ``*const T``) has validity rules :cite:`RUST_REF_BEHAVIOR`. .. rust-example:: @@ -101,9 +103,9 @@ :status: draft This noncompliant example creates a reference from uninitialized memory. - Creating a reference from arbitrary or uninitialized bytes is undefined behavior. - References must be valid, aligned, dereferenceable, and non-null. - Uninitialized memory cannot satisfy these invariants. + Creating a reference from arbitrary or uninitialized bytes is undefined behavior :cite:`RUST_REF_BEHAVIOR`. + References must be valid, aligned, dereferenceable, and non-null :cite:`UCG_VALIDITY`. + Uninitialized memory cannot satisfy these requirements. .. rust-example:: @@ -119,19 +121,6 @@ :status: draft This noncompliant example creates a reference from uninitialized memory. - The ``create_ref`` function has undefined behavior when creating a reference from a dangling pointer. - It creates uninitialized memory sized for a reference (``&u8``). - A reference is essentially a pointer (8 bytes on 64-bit systems). - ``&raw mut uninit`` retrieves a raw mutable pointer to the ``MaybeUninit``. - The ``.cast::<*const u8>()`` reinterprets it as a pointer to a raw pointer. - The call to ``.write(ptr::dangling())`` writes a dangling pointer value. - This creates a pointer which is non-null, aligned, but does not point to valid, initialized value. - The call to ``assume_init`` asserts the ``MaybeUninit<&u8>`` is a valid ``&u8`` reference - A reference (``&T``) has stricter requirements than a raw pointer. - Even though the bit pattern looks like a valid pointer, - the semantic requirements for a reference are violated. - The compiler is allowed to assume references always point to valid data, - so this can cause miscompilation. .. rust-example:: @@ -152,6 +141,19 @@ create_ref(); } + The ``create_ref`` function has undefined behavior when creating a reference from a dangling pointer. + It creates uninitialized memory sized for a reference (``&u8``). + ``&raw mut uninit`` retrieves a raw mutable pointer to the ``MaybeUninit``. + The ``.cast::<*const u8>()`` reinterprets it as a pointer to a raw pointer. + The call to ``.write(ptr::dangling())`` writes a dangling pointer value. + This creates a non-null, aligned pointer that does not point to a valid, initialized value. + The call to ``assume_init`` asserts the ``MaybeUninit<&u8>`` is a valid ``&u8`` reference + A reference (``&T``) has stricter requirements than a raw pointer. + Even though the bit pattern looks like a valid pointer, + the semantic requirements for a reference are violated. + The compiler is allowed to assume references always point to valid data, + so this can cause miscompilation. + .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db5 :status: draft @@ -222,3 +224,67 @@ let s = unsafe { p.read_unaligned() }; // compliant println!("{:?}", s); } + + .. bibliography:: + :id: bib_LoopTerminate + :status: draft + + .. list-table:: + :header-rows: 0 + :widths: auto + :class: bibliography-table + + * - .. [DO-178C] + - | RTCA, Inc. + | "DO-178C: Software Considerations in Airborne Systems and Equipment Certification." + | https://store.accuristech.com/standards/rtca-do-178c?product_id=2200105 + + * - .. [RUSTNOMICON_UNINIT] + - | The Rust Project Developers + | "The Rustonomicon - Uninitialized Memory" + | https://doc.rust-lang.org/nomicon/uninitialized.html + + * - .. [RUST_REF_BEHAVIOR] + - | The Rust Project Developers + | "The Rust Reference - Behavior considered undefined" + | https://doc.rust-lang.org/reference/behavior-considered-undefined.html + + * - .. [MAYBEUNINIT_DOC] + - | The Rust Project Developers + | "std::mem::MaybeUninit - Rust Standard Library Documentation" + | https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html + + * - .. [FERROCENE_SPEC] + - | Ferrocene GmbH + | "Ferrocene Language Specification" + | https://spec.ferrocene.dev/ + + * - .. [MISRA_RUST] + - | MISRA Consortium Limited + | "MISRA Rust Guidelines (Draft)" + | https://misra.org.uk/ + + * - .. [ISO_26262] + - | International Organization for Standardization + | "ISO 26262 - Road vehicles - Functional safety" + | https://www.iso.org/standard/68383.html + + * - .. [IEC_61508] + - | International Electrotechnical Commission + | "IEC 61508 - Functional Safety of Electrical/Electronic/Programmable Electronic Safety-related Systems" + | https://www.iec.ch/functional-safety + + * - .. [RUST_SAFETY_CRITICAL_WG] + - | Rust Foundation + | "Rust Safety-Critical Consortium" + | https://github.com/rust-lang/safety-critical-consortium + + * - .. [UCG_VALIDITY] + - | The Rust Project Developers + | "Unsafe Code Guidelines - Validity Invariants" + | https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#validity-and-safety-invariant + + * - .. [CERT_RUST] + - | Carnegie Mellon University Software Engineering Institute + | "SEI CERT Rust Coding Standard" + | https://wiki.sei.cmu.edu/confluence/display/rust From a95c0877d2373654555aba6d7ee058589e38e3c7 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Fri, 2 Jan 2026 11:39:49 -0500 Subject: [PATCH 11/28] Update citations in gui_uyp3mCj77FS8.rst.inc --- .../values/gui_uyp3mCj77FS8.rst.inc | 108 ++++++++---------- 1 file changed, 45 insertions(+), 63 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 044c3d9bb..5cb4ed825 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -13,8 +13,7 @@ :scope: system :tags: undefined-behavior, unsafe - Do not read uninitialized memory of any non-union type as a typed value - :cite:`RUSTNOMICON_UNINIT`. + Do not read uninitialized memory of any non-union type as a typed value :cite:`gui_xK9pLm2nQR4t:RUSTNOMICON-UNINIT`. This is sometimes referred to as *transmuting* or *read-at-type*. Memory can remain uninitialized if it is not read as a type. @@ -22,7 +21,7 @@ `_. Calling `assume_init `_ - :cite:`MAYBEUNINIT_DOC` or any of the following related functions is treated in the same manner as a typed read: + :cite:`gui_aE3fNc6dWX1v:MAYBEUNINIT-DOC` or any of the following related functions is treated in the same manner as a typed read: * ``assume_init_drop`` * ``assume_init_mut`` @@ -30,8 +29,8 @@ * ``assume_init_ref`` * ``array_assume_init`` - Calling any of these function on memory that is not yet fully initialized is undefined behavior :cite:`RUST_REF_BEHAVIOR`. - The memory must be properly initialized according to the requirements of the variable's type :cite:`UCG_VALIDITY`. + Calling any of these function on memory that is not yet fully initialized is undefined behavior :cite:`gui_vB7sHj5wYZ8u:RUST-REF-BEHAVIOR`. + The memory must be properly initialized according to the requirements of the variable's type :cite:`gui_uZ0zDq8rST1b:UCG-VALIDITY`. For example, a variable of reference type must be aligned, non-null, and point to valid memory. Similarly, entirely uninitialized memory may have any content, while a ``bool`` must always be ``true`` or ``false``. Consequently, reading an uninitialized ``bool`` is undefined behavior. @@ -40,10 +39,12 @@ :id: rat_kjFRrhpS8Wu6 :status: draft - Rust's memory model requires that all bytes must be initialized before being read as a typed value :cite:`RUSTNOMICON_UNINIT` :cite:`FERROCENE_SPEC`. - Reading uninitialized memory as a typed value is undefined behavior :cite:`RUST_REF_BEHAVIOR`. - This guideline aligns with functional safety standards :cite:`ISO_26262` :cite:`IEC_61508` and secure coding practices :cite:`CERT_RUST`. - + Rust's memory model requires that all bytes must be initialized before being read as a typed value + :cite:`gui_xK9pLm2nQR4t:RUSTNOMICON-UNINIT` :cite:`gui_kP8qTg4hUS2w:FERROCENE-SPEC`. + Reading uninitialized memory as a typed value is undefined behavior :cite:`gui_vB7sHj5wYZ8u:RUST-REF-BEHAVIOR`. + This guideline aligns with functional safety standards :cite:`gui_oT4tXk2lMN5y:ISO-26262` + :cite:`gui_qV6vZm4nOP7z:IEC-61508` and secure coding practices. + .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db1 :status: draft @@ -86,9 +87,9 @@ :status: draft This noncompliant example creates a pointer from uninitialized memory. - Not all bit patterns are valid pointers for all operations (e.g., provenance rules) :cite:`UCG_VALIDITY`. + Not all bit patterns are valid pointers for all operations (e.g., provenance rules) :cite:`gui_uZ0zDq8rST1b:UCG-VALIDITY`. You cannot create a pointer from unspecified bytes. - Even a raw pointer type (e.g., ``*const T``) has validity rules :cite:`RUST_REF_BEHAVIOR`. + Even a raw pointer type (e.g., ``*const T``) has validity rules `gui_vB7sHj5wYZ8u:RUST-REF-BEHAVIOR`. .. rust-example:: @@ -103,8 +104,8 @@ :status: draft This noncompliant example creates a reference from uninitialized memory. - Creating a reference from arbitrary or uninitialized bytes is undefined behavior :cite:`RUST_REF_BEHAVIOR`. - References must be valid, aligned, dereferenceable, and non-null :cite:`UCG_VALIDITY`. + Creating a reference from arbitrary or uninitialized bytes is undefined behavior :cite:`gui_vB7sHj5wYZ8u:RUST-REF-BEHAVIOR`. + References must be valid, aligned, dereferenceable, and non-null :cite:`gui_uZ0zDq8rST1b:UCG-VALIDITY`. Uninitialized memory cannot satisfy these requirements. .. rust-example:: @@ -226,7 +227,7 @@ } .. bibliography:: - :id: bib_LoopTerminate + :id: bib_WNCi5njUWLuY :status: draft .. list-table:: @@ -234,55 +235,36 @@ :widths: auto :class: bibliography-table - * - .. [DO-178C] - - | RTCA, Inc. - | "DO-178C: Software Considerations in Airborne Systems and Equipment Certification." - | https://store.accuristech.com/standards/rtca-do-178c?product_id=2200105 - - * - .. [RUSTNOMICON_UNINIT] - - | The Rust Project Developers - | "The Rustonomicon - Uninitialized Memory" - | https://doc.rust-lang.org/nomicon/uninitialized.html - - * - .. [RUST_REF_BEHAVIOR] - - | The Rust Project Developers - | "The Rust Reference - Behavior considered undefined" - | https://doc.rust-lang.org/reference/behavior-considered-undefined.html - - * - .. [MAYBEUNINIT_DOC] - - | The Rust Project Developers - | "std::mem::MaybeUninit - Rust Standard Library Documentation" - | https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html - - * - .. [FERROCENE_SPEC] - - | Ferrocene GmbH - | "Ferrocene Language Specification" - | https://spec.ferrocene.dev/ - - * - .. [MISRA_RUST] - - | MISRA Consortium Limited - | "MISRA Rust Guidelines (Draft)" - | https://misra.org.uk/ - - * - .. [ISO_26262] - - | International Organization for Standardization - | "ISO 26262 - Road vehicles - Functional safety" - | https://www.iso.org/standard/68383.html - - * - .. [IEC_61508] - - | International Electrotechnical Commission - | "IEC 61508 - Functional Safety of Electrical/Electronic/Programmable Electronic Safety-related Systems" - | https://www.iec.ch/functional-safety - - * - .. [RUST_SAFETY_CRITICAL_WG] - - | Rust Foundation - | "Rust Safety-Critical Consortium" - | https://github.com/rust-lang/safety-critical-consortium - - * - .. [UCG_VALIDITY] - - | The Rust Project Developers - | "Unsafe Code Guidelines - Validity Invariants" - | https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#validity-and-safety-invariant + * - :bibentry:`gui_wB2bFs0tUV3c:DO-178C` + - RTCA, Inc. "DO-178C: Software Considerations in Airborne Systems and Equipment Certification." https://store.accuristech.com/standards/rtca-do-178c?product_id=2200105. + + * - :bibentry:`gui_xK9pLm2nQR4t:RUSTNOMICON-UNINIT` + - The Rust Project Developers. "The Rustonomicon - Uninitialized Memory." https://doc.rust-lang.org/nomicon/uninitialized.html. + + * - :bibentry:`gui_vB7sHj5wYZ8u:RUST-REF-BEHAVIOR` + - The Rust Project Developers. "The Rust Reference - Behavior considered undefined." https://doc.rust-lang.org/reference/behavior-considered-undefined.html. + + * - :bibentry:`gui_aE3fNc6dWX1v:MAYBEUNINIT-DOC` + - The Rust Project Developers. "std::mem::MaybeUninit - Rust Standard Library Documentation." https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html. + + * - :bibentry:`gui_kP8qTg4hUS2w:FERROCENE-SPEC` + - Ferrocene GmbH. "Ferrocene Language Specification." https://spec.ferrocene.dev/. + + * - :bibentry:`gui_mR1rVi9jKL3x:MISRA-RUST` + - MISRA Consortium Limited. "MISRA Rust Guidelines (Draft)." https://misra.org.uk/. + + * - :bibentry:`gui_oT4tXk2lMN5y:ISO-26262` + - International Organization for Standardization. "ISO 26262 - Road vehicles - Functional safety." https://www.iso.org/standard/68383.html. + + * - :bibentry:`gui_qV6vZm4nOP7z:IEC-61508` + - International Electrotechnical Commission. "IEC 61508 - Functional Safety of Electrical/Electronic/Programmable Electronic Safety-related Systems." https://www.iec.ch/functional-safety. + + * - :bibentry:`gui_sX8xBo6pQR9a:RUST-SAFETY-CRITICAL-WG` + - Rust Foundation. "Rust Safety-Critical Consortium." https://github.com/rust-lang/safety-critical-consortium. + + * - :bibentry:`gui_uZ0zDq8rST1b:UCG-VALIDITY` + - The Rust Project Developers. "Unsafe Code Guidelines - Validity Invariants." https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#validity-and-safety-invariant. + * - .. [CERT_RUST] - | Carnegie Mellon University Software Engineering Institute From cebdd287a27aa5f9cf977ed4d96862a02bf16584 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Fri, 2 Jan 2026 11:42:42 -0500 Subject: [PATCH 12/28] Remove unnecessary newline in gui_uyp3mCj77FS8.rst.inc --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 5cb4ed825..999006e09 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -225,7 +225,6 @@ let s = unsafe { p.read_unaligned() }; // compliant println!("{:?}", s); } - .. bibliography:: :id: bib_WNCi5njUWLuY :status: draft From 6ce3ddb9f9a662d07ae401005ed43be8dcfa13c9 Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Mon, 19 Jan 2026 13:26:21 +0900 Subject: [PATCH 13/28] fix(guidelines): annotate unsafe examples Add miri directives and normalize citations/bibliography entries so the guideline builds cleanly. --- .../values/gui_uyp3mCj77FS8.rst.inc | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 999006e09..33b6ae42e 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -13,15 +13,15 @@ :scope: system :tags: undefined-behavior, unsafe - Do not read uninitialized memory of any non-union type as a typed value :cite:`gui_xK9pLm2nQR4t:RUSTNOMICON-UNINIT`. + Do not read uninitialized memory of any non-union type as a typed value :cite:`gui_uyp3mCj77FS8:RUSTNOMICON-UNINIT`. This is sometimes referred to as *transmuting* or *read-at-type*. Memory can remain uninitialized if it is not read as a type. Reading from a union is covered by `Do not read from union fields that may contain uninitialized bytes `_. - Calling `assume_init `_ - :cite:`gui_aE3fNc6dWX1v:MAYBEUNINIT-DOC` or any of the following related functions is treated in the same manner as a typed read: + Calling :std:`std::mem::MaybeUninit::assume_init` + :cite:`gui_uyp3mCj77FS8:MAYBEUNINIT-DOC` or any of the following related functions is treated in the same manner as a typed read: * ``assume_init_drop`` * ``assume_init_mut`` @@ -29,8 +29,8 @@ * ``assume_init_ref`` * ``array_assume_init`` - Calling any of these function on memory that is not yet fully initialized is undefined behavior :cite:`gui_vB7sHj5wYZ8u:RUST-REF-BEHAVIOR`. - The memory must be properly initialized according to the requirements of the variable's type :cite:`gui_uZ0zDq8rST1b:UCG-VALIDITY`. + Calling any of these function on memory that is not yet fully initialized is undefined behavior :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. + The memory must be properly initialized according to the requirements of the variable's type :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. For example, a variable of reference type must be aligned, non-null, and point to valid memory. Similarly, entirely uninitialized memory may have any content, while a ``bool`` must always be ``true`` or ``false``. Consequently, reading an uninitialized ``bool`` is undefined behavior. @@ -40,10 +40,10 @@ :status: draft Rust's memory model requires that all bytes must be initialized before being read as a typed value - :cite:`gui_xK9pLm2nQR4t:RUSTNOMICON-UNINIT` :cite:`gui_kP8qTg4hUS2w:FERROCENE-SPEC`. - Reading uninitialized memory as a typed value is undefined behavior :cite:`gui_vB7sHj5wYZ8u:RUST-REF-BEHAVIOR`. - This guideline aligns with functional safety standards :cite:`gui_oT4tXk2lMN5y:ISO-26262` - :cite:`gui_qV6vZm4nOP7z:IEC-61508` and secure coding practices. + :cite:`gui_uyp3mCj77FS8:RUSTNOMICON-UNINIT` :cite:`gui_uyp3mCj77FS8:FERROCENE-SPEC`. + Reading uninitialized memory as a typed value is undefined behavior :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. + This guideline aligns with functional safety standards :cite:`gui_uyp3mCj77FS8:ISO-26262` + :cite:`gui_uyp3mCj77FS8:IEC-61508` and secure coding practices. .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db1 @@ -53,6 +53,7 @@ which is undefined behavior. .. rust-example:: + :miri: expect_ub use std::mem::MaybeUninit; @@ -72,6 +73,7 @@ This is the canonical safe pattern for using ``MaybeUninit``. .. rust-example:: + :miri: use std::mem::MaybeUninit; @@ -87,11 +89,12 @@ :status: draft This noncompliant example creates a pointer from uninitialized memory. - Not all bit patterns are valid pointers for all operations (e.g., provenance rules) :cite:`gui_uZ0zDq8rST1b:UCG-VALIDITY`. + Not all bit patterns are valid pointers for all operations (e.g., provenance rules) :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. You cannot create a pointer from unspecified bytes. - Even a raw pointer type (e.g., ``*const T``) has validity rules `gui_vB7sHj5wYZ8u:RUST-REF-BEHAVIOR`. + Even a raw pointer type (e.g., ``*const T``) has validity rules :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. .. rust-example:: + :miri: expect_ub use std::mem::MaybeUninit; @@ -104,11 +107,12 @@ :status: draft This noncompliant example creates a reference from uninitialized memory. - Creating a reference from arbitrary or uninitialized bytes is undefined behavior :cite:`gui_vB7sHj5wYZ8u:RUST-REF-BEHAVIOR`. - References must be valid, aligned, dereferenceable, and non-null :cite:`gui_uZ0zDq8rST1b:UCG-VALIDITY`. + Creating a reference from arbitrary or uninitialized bytes is undefined behavior :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. + References must be valid, aligned, dereferenceable, and non-null :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. Uninitialized memory cannot satisfy these requirements. .. rust-example:: + :miri: expect_ub use std::mem::MaybeUninit; @@ -124,6 +128,7 @@ This noncompliant example creates a reference from uninitialized memory. .. rust-example:: + :miri: expect_ub use std::mem::MaybeUninit; use std::ptr; @@ -173,6 +178,7 @@ Reading uninitialized bytes as a concrete type is always undefined behavior. .. rust-example:: + :miri: expect_ub use std::mem::MaybeUninit; @@ -207,6 +213,7 @@ * ``read_unaligned`` handles the alignment issue .. rust-example:: + :miri: #[repr(C)] #[derive(Debug)] @@ -234,38 +241,35 @@ :widths: auto :class: bibliography-table - * - :bibentry:`gui_wB2bFs0tUV3c:DO-178C` + * - :bibentry:`gui_uyp3mCj77FS8:DO-178C` - RTCA, Inc. "DO-178C: Software Considerations in Airborne Systems and Equipment Certification." https://store.accuristech.com/standards/rtca-do-178c?product_id=2200105. - * - :bibentry:`gui_xK9pLm2nQR4t:RUSTNOMICON-UNINIT` + * - :bibentry:`gui_uyp3mCj77FS8:RUSTNOMICON-UNINIT` - The Rust Project Developers. "The Rustonomicon - Uninitialized Memory." https://doc.rust-lang.org/nomicon/uninitialized.html. - * - :bibentry:`gui_vB7sHj5wYZ8u:RUST-REF-BEHAVIOR` + * - :bibentry:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR` - The Rust Project Developers. "The Rust Reference - Behavior considered undefined." https://doc.rust-lang.org/reference/behavior-considered-undefined.html. - * - :bibentry:`gui_aE3fNc6dWX1v:MAYBEUNINIT-DOC` + * - :bibentry:`gui_uyp3mCj77FS8:MAYBEUNINIT-DOC` - The Rust Project Developers. "std::mem::MaybeUninit - Rust Standard Library Documentation." https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html. - * - :bibentry:`gui_kP8qTg4hUS2w:FERROCENE-SPEC` + * - :bibentry:`gui_uyp3mCj77FS8:FERROCENE-SPEC` - Ferrocene GmbH. "Ferrocene Language Specification." https://spec.ferrocene.dev/. - * - :bibentry:`gui_mR1rVi9jKL3x:MISRA-RUST` + * - :bibentry:`gui_uyp3mCj77FS8:MISRA-RUST` - MISRA Consortium Limited. "MISRA Rust Guidelines (Draft)." https://misra.org.uk/. - * - :bibentry:`gui_oT4tXk2lMN5y:ISO-26262` + * - :bibentry:`gui_uyp3mCj77FS8:ISO-26262` - International Organization for Standardization. "ISO 26262 - Road vehicles - Functional safety." https://www.iso.org/standard/68383.html. - * - :bibentry:`gui_qV6vZm4nOP7z:IEC-61508` + * - :bibentry:`gui_uyp3mCj77FS8:IEC-61508` - International Electrotechnical Commission. "IEC 61508 - Functional Safety of Electrical/Electronic/Programmable Electronic Safety-related Systems." https://www.iec.ch/functional-safety. - * - :bibentry:`gui_sX8xBo6pQR9a:RUST-SAFETY-CRITICAL-WG` + * - :bibentry:`gui_uyp3mCj77FS8:RUST-SAFETY-CRITICAL-WG` - Rust Foundation. "Rust Safety-Critical Consortium." https://github.com/rust-lang/safety-critical-consortium. - * - :bibentry:`gui_uZ0zDq8rST1b:UCG-VALIDITY` - - The Rust Project Developers. "Unsafe Code Guidelines - Validity Invariants." https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#validity-and-safety-invariant. + * - :bibentry:`gui_uyp3mCj77FS8:UCG-VALIDITY` + - Rust Unsafe Code Guidelines. "Validity and Safety Invariant." https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#validity-and-safety-invariant. - - * - .. [CERT_RUST] - - | Carnegie Mellon University Software Engineering Institute - | "SEI CERT Rust Coding Standard" - | https://wiki.sei.cmu.edu/confluence/display/rust + * - :bibentry:`gui_uyp3mCj77FS8:CERT-RUST` + - Carnegie Mellon University Software Engineering Institute. "SEI CERT Rust Coding Standard." https://wiki.sei.cmu.edu/confluence/display/rust From 26883e66af89ed65dcdfdb8b23ac77d09d5e75cf Mon Sep 17 00:00:00 2001 From: Pete LeVasseur Date: Mon, 19 Jan 2026 13:54:35 +0900 Subject: [PATCH 14/28] fix(guidelines): silence example warnings Allow warnings for UB demonstrations and prefix unused locals in the uninitialized-memory guideline to keep example tests clean. --- .../values/gui_uyp3mCj77FS8.rst.inc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 33b6ae42e..b20fb8fc8 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -54,12 +54,13 @@ .. rust-example:: :miri: expect_ub + :warn: allow use std::mem::MaybeUninit; fn main() { // Reading uninitialized memory as a typed value is undefined behavior - let x: u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant + let _x: u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant } .. compliant_example:: @@ -81,7 +82,7 @@ let mut x = MaybeUninit::::uninit(); x.write(42); // x is fully initialized - let val = unsafe { x.assume_init() }; // compliant + let _val = unsafe { x.assume_init() }; // compliant } .. non_compliant_example:: @@ -95,11 +96,12 @@ .. rust-example:: :miri: expect_ub + :warn: allow use std::mem::MaybeUninit; fn main() { - let p: *const u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant + let _p: *const u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant } .. non_compliant_example:: @@ -113,12 +115,13 @@ .. rust-example:: :miri: expect_ub + :warn: allow use std::mem::MaybeUninit; fn main() { // Reading an invalid reference is undefined behavior - let r: &u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant + let _r: &u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant } .. non_compliant_example:: @@ -183,9 +186,9 @@ use std::mem::MaybeUninit; fn main() { - let mut arr: [MaybeUninit; 4] = unsafe { MaybeUninit::uninit().assume_init() }; + let arr: [MaybeUninit; 4] = unsafe { MaybeUninit::uninit().assume_init() }; // Undefined behavior constructing an array of 'u8' from uninitialized memory. - let a = unsafe { std::mem::transmute::<_, [u8; 4]>(arr) }; // noncompliant + let _a = unsafe { std::mem::transmute::<_, [u8; 4]>(arr) }; // noncompliant } .. compliant_example:: From 39fcb24d4848e22f368ce8689e56e0c3219664b4 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Tue, 20 Jan 2026 04:21:11 -0500 Subject: [PATCH 15/28] Update src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc Co-authored-by: increasing --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index b20fb8fc8..4df545724 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -204,7 +204,7 @@ The variable ``buf`` is a fully, zero-initialized 8-byte buffer. - The first wo bytes of ``buf`` are overwritten. + The first two bytes of ``buf`` are overwritten. The byte buffer ``buf`` pointer is cast to a pointer to ``S``. The call to ``read_unaligned`` reads the ``struct`` without requiring alignment. From 13c0267da4a6226c32ec65c2fa83f5ddf8812463 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Tue, 20 Jan 2026 04:27:32 -0500 Subject: [PATCH 16/28] Update noncompliant example explanation Clarify the explanation of undefined behavior in the noncompliant example. --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 4df545724..2953c8013 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -128,7 +128,15 @@ :id: non_compl_ex_Qb5GqYTP6db3 :status: draft - This noncompliant example creates a reference from uninitialized memory. + This noncompliant example has undefined behavior because it creates an invalid reference. + + The ``&u8`` reference has stricter validity requirements than the raw pointer ``*const u8``. + While ``ptr::dangling()`` produces a non-null, well-aligned pointer, it does not point to valid, allocated memory. + + The code writes a dangling raw pointer into memory and then calls ``assume_init()``, + asserting that this memory contains a valid reference. + But a dangling pointer is never a valid reference—even if you never dereference it. + The mere existence of an invalid reference is undefined behavior. .. rust-example:: :miri: expect_ub From 54fda06c3abd160d0b932efceb998412744d2de2 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Tue, 20 Jan 2026 04:37:54 -0500 Subject: [PATCH 17/28] Update comments for clarity in Rust examples --- .../values/gui_uyp3mCj77FS8.rst.inc | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 2953c8013..97c0dd3d1 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -81,7 +81,7 @@ fn main() { let mut x = MaybeUninit::::uninit(); x.write(42); - // x is fully initialized + // SAFETY: 'x' is fully initialized let _val = unsafe { x.assume_init() }; // compliant } @@ -101,6 +101,7 @@ use std::mem::MaybeUninit; fn main() { + // Undefined behavior creating a pointer from uninitialized memory let _p: *const u32 = unsafe { MaybeUninit::uninit().assume_init() }; // noncompliant } @@ -135,7 +136,7 @@ The code writes a dangling raw pointer into memory and then calls ``assume_init()``, asserting that this memory contains a valid reference. - But a dangling pointer is never a valid reference—even if you never dereference it. + However, a dangling pointer is never a valid reference—even if you never dereference it. The mere existence of an invalid reference is undefined behavior. .. rust-example:: @@ -158,19 +159,6 @@ create_ref(); } - The ``create_ref`` function has undefined behavior when creating a reference from a dangling pointer. - It creates uninitialized memory sized for a reference (``&u8``). - ``&raw mut uninit`` retrieves a raw mutable pointer to the ``MaybeUninit``. - The ``.cast::<*const u8>()`` reinterprets it as a pointer to a raw pointer. - The call to ``.write(ptr::dangling())`` writes a dangling pointer value. - This creates a non-null, aligned pointer that does not point to a valid, initialized value. - The call to ``assume_init`` asserts the ``MaybeUninit<&u8>`` is a valid ``&u8`` reference - A reference (``&T``) has stricter requirements than a raw pointer. - Even though the bit pattern looks like a valid pointer, - the semantic requirements for a reference are violated. - The compiler is allowed to assume references always point to valid data, - so this can cause miscompilation. - .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db5 :status: draft @@ -239,7 +227,7 @@ buf[1] = 20; // writing padding is fine let p = buf.as_ptr() as *const S; - // All fields are initialized (padding doesn't matter) + // SAFETY: All fields are initialized (padding doesn't matter) let s = unsafe { p.read_unaligned() }; // compliant println!("{:?}", s); } From 05240748cf987bbb6ac920e1cc03375f6ba6a961 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 21 Jan 2026 15:36:02 -0500 Subject: [PATCH 18/28] Update function references to include std::mem:: prefix --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 97c0dd3d1..87e6e8aeb 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -23,11 +23,11 @@ Calling :std:`std::mem::MaybeUninit::assume_init` :cite:`gui_uyp3mCj77FS8:MAYBEUNINIT-DOC` or any of the following related functions is treated in the same manner as a typed read: - * ``assume_init_drop`` - * ``assume_init_mut`` - * ``assume_init_read`` - * ``assume_init_ref`` - * ``array_assume_init`` + * :std:`std::mem::MaybeUninit::assume_init_drop` + * :std:`std::mem::MaybeUninit::assume_init_mut` + * :std:`std::mem::MaybeUninit::assume_init_read` + * :std:`std::mem::MaybeUninit::assume_init_ref` + * :std:`std::mem::MaybeUninit::array_assume_init` Calling any of these function on memory that is not yet fully initialized is undefined behavior :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. The memory must be properly initialized according to the requirements of the variable's type :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. From 6e2cd30e3fb3ae3647e9fba2d6d758b03bb1a00b Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 21 Jan 2026 15:38:33 -0500 Subject: [PATCH 19/28] Update src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Fischer --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 87e6e8aeb..7d3bdb264 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -29,7 +29,7 @@ * :std:`std::mem::MaybeUninit::assume_init_ref` * :std:`std::mem::MaybeUninit::array_assume_init` - Calling any of these function on memory that is not yet fully initialized is undefined behavior :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. + Calling any of these functions on memory that is not yet fully initialized is undefined behavior :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. The memory must be properly initialized according to the requirements of the variable's type :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. For example, a variable of reference type must be aligned, non-null, and point to valid memory. Similarly, entirely uninitialized memory may have any content, while a ``bool`` must always be ``true`` or ``false``. From 3afff16d02f0e08a3c4bab406e98eeba0a59082d Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 21 Jan 2026 15:40:39 -0500 Subject: [PATCH 20/28] Simplify guidelines on uninitialized memory usage Removed redundant explanations about undefined behavior for uninitialized memory and bool types. --- .../values/gui_uyp3mCj77FS8.rst.inc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 7d3bdb264..ba6338dc1 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -29,12 +29,8 @@ * :std:`std::mem::MaybeUninit::assume_init_ref` * :std:`std::mem::MaybeUninit::array_assume_init` - Calling any of these functions on memory that is not yet fully initialized is undefined behavior :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. - The memory must be properly initialized according to the requirements of the variable's type :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. - For example, a variable of reference type must be aligned, non-null, and point to valid memory. - Similarly, entirely uninitialized memory may have any content, while a ``bool`` must always be ``true`` or ``false``. - Consequently, reading an uninitialized ``bool`` is undefined behavior. - + Calling any of these functions on memory that is not fully initialized is undefined behavior :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. + .. rationale:: :id: rat_kjFRrhpS8Wu6 :status: draft @@ -45,6 +41,11 @@ This guideline aligns with functional safety standards :cite:`gui_uyp3mCj77FS8:ISO-26262` :cite:`gui_uyp3mCj77FS8:IEC-61508` and secure coding practices. + Memory must be properly initialized according to the requirements of the variable's type :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. + For example, a variable of reference type must be aligned, non-null, and point to valid memory. + Similarly, entirely uninitialized memory may have any content, while a ``bool`` must always be ``true`` or ``false``. + Consequently, reading an uninitialized ``bool`` is undefined behavior. + .. non_compliant_example:: :id: non_compl_ex_Qb5GqYTP6db1 :status: draft From 43b8103b804b822f3020f98bb6c11dcdf58facd3 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 21 Jan 2026 15:42:26 -0500 Subject: [PATCH 21/28] Update src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Fischer --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index ba6338dc1..6422bdffd 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -91,6 +91,7 @@ :status: draft This noncompliant example creates a pointer from uninitialized memory. + Not all bit patterns are valid pointers for all operations (e.g., provenance rules) :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. You cannot create a pointer from unspecified bytes. Even a raw pointer type (e.g., ``*const T``) has validity rules :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. From 98863df8693562fd3694362bfc2dc9036bd51e21 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 21 Jan 2026 15:43:23 -0500 Subject: [PATCH 22/28] Update src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Fischer --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 6422bdffd..6cdd7150a 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -71,8 +71,10 @@ This compliant example creates an uninitialized variable ``x`` of type ``MaybeUninit``. The code calls the ``write`` function to write the value 42 to ``x``. The call to ``assume_init`` asserts that the value is initialized and extracts the value of type ``u64``. - This call is compliant with this rule because the memory has been properly initialized by the call to ``write(42)``. - This is the canonical safe pattern for using ``MaybeUninit``. + + This call to ``assume_init`` is compliant with the rule because the memory of `x` has been properly initialized by the call to ``write(42)``. + + This is the canonically safe pattern for using ``MaybeUninit``. .. rust-example:: :miri: From ee4a86a9e277933d1562e0977c9b18b843da0a9b Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 21 Jan 2026 15:45:01 -0500 Subject: [PATCH 23/28] Update src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Fischer --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 6cdd7150a..67c3a756b 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -69,6 +69,7 @@ :status: draft This compliant example creates an uninitialized variable ``x`` of type ``MaybeUninit``. + The code calls the ``write`` function to write the value 42 to ``x``. The call to ``assume_init`` asserts that the value is initialized and extracts the value of type ``u64``. From fc521a1d1e21382eb0a6144f9fedea24935ff2eb Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 21 Jan 2026 15:45:16 -0500 Subject: [PATCH 24/28] Update src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 67c3a756b..60956ce94 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -73,7 +73,7 @@ The code calls the ``write`` function to write the value 42 to ``x``. The call to ``assume_init`` asserts that the value is initialized and extracts the value of type ``u64``. - This call to ``assume_init`` is compliant with the rule because the memory of `x` has been properly initialized by the call to ``write(42)``. + This call to ``assume_init`` is compliant with this rule because the memory of `x` has been properly initialized by the call to ``write(42)``. This is the canonically safe pattern for using ``MaybeUninit``. From 347d9ca40a58570a6d5fd1e5eba56c1d22761688 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 21 Jan 2026 15:47:55 -0500 Subject: [PATCH 25/28] Update src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 60956ce94..c23dc8036 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -96,7 +96,6 @@ This noncompliant example creates a pointer from uninitialized memory. Not all bit patterns are valid pointers for all operations (e.g., provenance rules) :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. - You cannot create a pointer from unspecified bytes. Even a raw pointer type (e.g., ``*const T``) has validity rules :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. .. rust-example:: From 1ef98f223c9539b8265f437688eb9e9cfa279456 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 21 Jan 2026 15:48:19 -0500 Subject: [PATCH 26/28] Update src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Fischer --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index c23dc8036..a01c11245 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -114,6 +114,7 @@ :status: draft This noncompliant example creates a reference from uninitialized memory. + Creating a reference from arbitrary or uninitialized bytes is undefined behavior :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. References must be valid, aligned, dereferenceable, and non-null :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. Uninitialized memory cannot satisfy these requirements. From e9efabf795f93f4a7e63edb96af94e18f7b3574c Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 21 Jan 2026 15:48:40 -0500 Subject: [PATCH 27/28] Update src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Fischer --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index a01c11245..7904ba170 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -116,8 +116,8 @@ This noncompliant example creates a reference from uninitialized memory. Creating a reference from arbitrary or uninitialized bytes is undefined behavior :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. - References must be valid, aligned, dereferenceable, and non-null :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. - Uninitialized memory cannot satisfy these requirements. + + References must be valid, aligned, dereferenceable, and non-null :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. Uninitialized memory cannot satisfy these requirements. .. rust-example:: :miri: expect_ub From f84f500437e8ac3ff1dc70aefb2cc57adb04afa6 Mon Sep 17 00:00:00 2001 From: "Robert C. Seacord" Date: Wed, 21 Jan 2026 15:49:20 -0500 Subject: [PATCH 28/28] Update src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Félix Fischer --- src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc index 7904ba170..241c448f4 100644 --- a/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc +++ b/src/coding-guidelines/values/gui_uyp3mCj77FS8.rst.inc @@ -96,7 +96,8 @@ This noncompliant example creates a pointer from uninitialized memory. Not all bit patterns are valid pointers for all operations (e.g., provenance rules) :cite:`gui_uyp3mCj77FS8:UCG-VALIDITY`. - Even a raw pointer type (e.g., ``*const T``) has validity rules :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. + + As can be seen here, even the raw pointer type (``*const T``) has validity rules :cite:`gui_uyp3mCj77FS8:RUST-REF-BEHAVIOR`. .. rust-example:: :miri: expect_ub