Skip to content

[layout] Restrict CastFrom's CastExact impl - #3549

Open
enthropy7 wants to merge 1 commit into
google:mainfrom
enthropy7:main
Open

[layout] Restrict CastFrom's CastExact impl#3549
enthropy7 wants to merge 1 commit into
google:mainfrom
enthropy7:main

Conversation

@enthropy7

Copy link
Copy Markdown

CastExact promises that a cast preserves the complete referent byte range. However, CastFrom only preserves the address and the size before trailing padding. This is incorrect for dynamically sized types with explicit alignment:

#[repr(C, align(8))]
struct Aligned<T: ?Sized> {
    trailing: T,
}

An Aligned<[u8]> containing one byte has a total size of eight bytes because of trailing padding. Projecting it to [u8] produces a one-byte referent. This is a valid shrinking Cast, but not a CastExact.тThis case came up while checking complete byte ranges in aligned zero-copy video buffers, instead of checking only addresses and logical payload lengths.

This PR restricts the CastExact implementation to Src: IntoBytes. Such sources cannot contain padding, so the complete byte range is preserved. The general Cast implementation remains available for projections that may shrink.

No current safe public path to UB was found because the existing transmute paths already require Src: IntoBytes. The change is still needed because the unsafe CastExact implementation must be correct for every type for which it is implemented. Otherwise, future internal code could rely on a false size-preservation guarantee.

The regression test demonstrates the eight-to-one-byte projection and verifies that it implements Cast, but not CastExact.

Tested with the repository's MSRV, stable, and nightly configurations, including Clippy, formatting, and all 136 library tests.

Related to #2910 and #3199.

CastFrom preserves unpadded size, but lowering the alignment of a dynamically padded DST can shrink its referent. Require IntoBytes on the source so CastExact is only implemented for padding-free source layouts.

Add a regression test using an aligned slice DST whose one-byte payload projects from an eight-byte referent to a one-byte slice.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.86%. Comparing base (82eed02) to head (efc46c3).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3549   +/-   ##
=======================================
  Coverage   91.85%   91.86%           
=======================================
  Files          20       20           
  Lines        6093     6100    +7     
=======================================
+ Hits         5597     5604    +7     
  Misses        496      496           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants