Skip to content

patina_internal_collections: Fix UB memory read in Node fields#1152

Merged
makubacki merged 7 commits intoOpenDevicePartnership:mainfrom
garybeihl:fix-node-uninit
Apr 2, 2026
Merged

patina_internal_collections: Fix UB memory read in Node fields#1152
makubacki merged 7 commits intoOpenDevicePartnership:mainfrom
garybeihl:fix-node-uninit

Conversation

@garybeihl
Copy link
Copy Markdown
Contributor

@garybeihl garybeihl commented Dec 3, 2025

Description

Fixes an undefined behavior issue where Cell::set() reads uninitialized memory during linked list creation in Storage::resize().

Root Cause

  • Cell::set() internally uses mem::replace(), which reads the old value before writing the new one.
  • When Storage::resize() allocates new nodes and calls build_linked_list(), the Cell fields contain uninitialized memory.
  • Reading uninitialized memory is undefined behavior, even if immediately overwritten. Unwanted compiler "optimizations" could follow.

Impact

Fix

  • Initialize all Cell fields using ptr::write() before build_linked_list()
  • Use addr_of_mut!() to read field pointers without creating references to uninitialized data

Introduced by

Related to #560

  • Impacts functionality?
  • Impacts security?
  • Breaking change?
  • Includes tests?
  • Includes documentation?

How This Was Tested

  • Tested with: cargo +nightly-2025-09-19 miri test -p patina_dxe_core.
  • 7 tests now pass (previously 0/469 due to this UB issue).

Integration Instructions

N/A

@github-actions github-actions Bot added the impact:security Has a security impact label Dec 3, 2025
@garybeihl garybeihl added the type:bug Something isn't working label Dec 3, 2025
@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 3, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@garybeihl garybeihl force-pushed the fix-node-uninit branch 2 times, most recently from 492ef76 to 7a57e63 Compare December 3, 2025 16:57
Comment thread core/patina_internal_collections/src/node.rs Outdated
Comment thread core/patina_internal_collections/src/node.rs Outdated
Comment thread core/patina_internal_collections/src/node.rs Outdated
Comment thread core/patina_internal_collections/src/node.rs Outdated
Comment thread core/patina_internal_collections/src/node.rs Outdated
@garybeihl garybeihl force-pushed the fix-node-uninit branch 4 times, most recently from f0178c1 to b1385f8 Compare December 9, 2025 00:26
@garybeihl garybeihl force-pushed the fix-node-uninit branch 2 times, most recently from ae5dcec to 7fcea9b Compare December 16, 2025 00:41
@Javagedes
Copy link
Copy Markdown
Contributor

Hi @garybeihl , I noticed you've been keeping this PR up to date, but not working on it (which is completely fine).

I just wanted to make sure you were not waiting on additional information from any of us that have commented on this PR (i.e. make sure we are not blocking you in any way)!

@garybeihl
Copy link
Copy Markdown
Contributor Author

No - not blocked - I uploaded a version of the changes that uses MaybeUninit and D: Default - just waiting for further comments or change requests. If you could have a look when you get a chance, that would be great - thanks!

@garybeihl garybeihl force-pushed the fix-node-uninit branch 3 times, most recently from a3c3321 to 490f0cf Compare December 23, 2025 21:23
Comment thread core/patina_internal_collections/src/node.rs
Comment thread core/patina_internal_collections/src/node.rs
Comment thread core/patina_internal_collections/src/node.rs Outdated
@garybeihl garybeihl force-pushed the fix-node-uninit branch 4 times, most recently from f6e8da6 to 84636f4 Compare January 15, 2026 15:04
…ment

Replace Default trait requirement with MaybeUninit wrapper for Node data field.
Only initialize data when nodes move from available to in-use list.
Fixes UB where Cell::set() was reading uninitialized memory.
Add safety documentation to all unsafe blocks in production code.
Add allow(clippy::undocumented_unsafe_blocks) to test modules
to avoid redundant safety comments for test assertions.
@garybeihl
Copy link
Copy Markdown
Contributor Author

Is there anything more for me to do here? If not, can I get another approval?

Copy link
Copy Markdown
Collaborator

@makubacki makubacki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Javagedes & @joschock should have a final review as well.

@patina-automation
Copy link
Copy Markdown
Contributor

patina-automation Bot commented Mar 5, 2026

✅ QEMU Validation Passed

All QEMU validation jobs completed successfully.

Note: Q35 is only built on Windows hosts (QEMU boot is disabled due to a QEMU vfat issue).

Workflow run: https://github.com/OpenDevicePartnership/patina/actions/runs/23915461797

Boot Time to EFI Shell

Platform Elapsed
Q35 (Linux Host) 28.3s
SBSA (Linux Host) 1m 3s

Dependencies

Repository Ref
patina 8ca306d
patina-dxe-core-qemu 3eb6066
patina-fw-patcher 29264b2
patina-qemu firmware v3.0.0
patina-qemu build script db5eef0

This comment was automatically generated by the Patina QEMU PR Validation Post workflow.

@garybeihl
Copy link
Copy Markdown
Contributor Author

Ping - please review so I can close this and move on to other Miri-found issues. Thanks!

Copy link
Copy Markdown
Collaborator

@makubacki makubacki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving latest

Comment thread core/patina_internal_collections/src/node.rs Outdated
Comment thread core/patina_internal_collections/src/node.rs Outdated
Comment thread core/patina_internal_collections/src/node.rs Outdated
Comment thread core/patina_internal_collections/src/node.rs Outdated
- Use MaybeUninit<Node<D>> in expand() to avoid UB from creating
  references to uninitialized memory
- Change Node data field visibility from pub to pub(crate)
- Fix expand() copy loop to iterate 0..self.len() instead of
  0..self.capacity() to avoid reading uninitialized data
- Remove module-level #[allow(clippy::undocumented_unsafe_blocks)]
  in favor of per-block safety comments

Signed-off-by: Gary Beihl <garybeihl@microsoft.com>
@makubacki makubacki merged commit 322b051 into OpenDevicePartnership:main Apr 2, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

impact:security Has a security impact type:bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants