Skip to content

Add user seed to -Z randomize-layout #91932

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,10 +347,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {

let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();

// `ReprOptions.layout_seed` is a deterministic seed that we can use to
// randomize field ordering with
let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed);

let optimize = !repr.inhibit_struct_field_reordering_opt();
if optimize {
let end =
Expand All @@ -364,6 +360,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
// the field ordering to try and catch some code making assumptions about layouts
// we don't guarantee
if repr.can_randomize_type_layout() {
// `ReprOptions.layout_seed` is a deterministic seed that we can use to
// randomize field ordering with
let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed);

// Shuffle the ordering of the fields
optimizing.shuffle(&mut rng);

Expand Down
15 changes: 11 additions & 4 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1608,9 +1608,9 @@ bitflags! {
// the seed stored in `ReprOptions.layout_seed`
const RANDOMIZE_LAYOUT = 1 << 5;
// Any of these flags being set prevent field reordering optimisation.
const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits |
ReprFlags::IS_SIMD.bits |
ReprFlags::IS_LINEAR.bits;
const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits
| ReprFlags::IS_SIMD.bits
| ReprFlags::IS_LINEAR.bits;
}
}

Expand Down Expand Up @@ -1640,7 +1640,14 @@ impl ReprOptions {

// Generate a deterministically-derived seed from the item's path hash
// to allow for cross-crate compilation to actually work
let field_shuffle_seed = tcx.def_path_hash(did).0.to_smaller_hash();
let mut field_shuffle_seed = tcx.def_path_hash(did).0.to_smaller_hash();

// If the user defined a custom seed for layout randomization, xor the item's
// path hash with the user defined seed, this will allowing determinism while
// still allowing users to further randomize layout generation for e.g. fuzzing
if let Some(user_seed) = tcx.sess.opts.debugging_opts.layout_seed {
field_shuffle_seed ^= user_seed;
}

for attr in tcx.get_attrs(did).iter() {
for r in attr::find_repr_attrs(&tcx.sess, attr) {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1321,6 +1321,8 @@ options! {
"print some statistics about the query system (default: no)"),
randomize_layout: bool = (false, parse_bool, [TRACKED],
"randomize the layout of types (default: no)"),
layout_seed: Option<u64> = (None, parse_opt_number, [TRACKED],
"seed layout randomization"),
relax_elf_relocations: Option<bool> = (None, parse_opt_bool, [TRACKED],
"whether ELF relocations can be relaxed"),
relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
Expand Down