Skip to content

WIP PROOF-OF-CONCEPT: experiment with very strict pointer provenance #95199

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

Closed
wants to merge 10 commits into from
Prev Previous commit
Next Next commit
WIP PROOF-OF-CONCEPT handle all the fallout in rustc
Why does rustc do oh so many crimes? Oh so many...
  • Loading branch information
Gankra committed Mar 22, 2022
commit 09be0276b39c39f2cdda1e5f8e2b4b441a6eadf2
20 changes: 11 additions & 9 deletions compiler/rustc_arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#![feature(decl_macro)]
#![feature(rustc_attrs)]
#![cfg_attr(test, feature(test))]
#![feature(strict_provenance)]

use smallvec::SmallVec;

Expand Down Expand Up @@ -87,7 +88,7 @@ impl<T> ArenaChunk<T> {
unsafe {
if mem::size_of::<T>() == 0 {
// A pointer as large as possible for zero-sized elements.
!0 as *mut T
ptr::invalid_mut(!0)
} else {
self.start().add(self.storage.len())
}
Expand Down Expand Up @@ -199,7 +200,7 @@ impl<T> TypedArena<T> {
unsafe {
if mem::size_of::<T>() == 0 {
self.ptr.set((self.ptr.get() as *mut u8).wrapping_offset(1) as *mut T);
let ptr = mem::align_of::<T>() as *mut T;
let ptr = ptr::NonNull::<T>::dangling().as_ptr();
// Don't drop the object. This `write` is equivalent to `forget`.
ptr::write(ptr, object);
&mut *ptr
Expand All @@ -216,7 +217,7 @@ impl<T> TypedArena<T> {

#[inline]
fn can_allocate(&self, additional: usize) -> bool {
let available_bytes = self.end.get() as usize - self.ptr.get() as usize;
let available_bytes = self.end.get().addr() - self.ptr.get().addr();
let additional_bytes = additional.checked_mul(mem::size_of::<T>()).unwrap();
available_bytes >= additional_bytes
}
Expand Down Expand Up @@ -262,7 +263,7 @@ impl<T> TypedArena<T> {
// If a type is `!needs_drop`, we don't need to keep track of how many elements
// the chunk stores - the field will be ignored anyway.
if mem::needs_drop::<T>() {
let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize;
let used_bytes = self.ptr.get().addr() - last_chunk.start().addr();
last_chunk.entries = used_bytes / mem::size_of::<T>();
}

Expand All @@ -288,9 +289,9 @@ impl<T> TypedArena<T> {
// chunks.
fn clear_last_chunk(&self, last_chunk: &mut ArenaChunk<T>) {
// Determine how much was filled.
let start = last_chunk.start() as usize;
let start = last_chunk.start().addr();
// We obtain the value of the pointer to the first uninitialized element.
let end = self.ptr.get() as usize;
let end = self.ptr.get().addr();
// We then calculate the number of elements to be dropped in the last chunk,
// which is the filled area's length.
let diff = if mem::size_of::<T>() == 0 {
Expand Down Expand Up @@ -395,15 +396,16 @@ impl DroplessArena {
/// request.
#[inline]
fn alloc_raw_without_grow(&self, layout: Layout) -> Option<*mut u8> {
let start = self.start.get() as usize;
let end = self.end.get() as usize;
let start = self.start.get().addr();
let old_end = self.end.get();
let end = old_end.addr();

let align = layout.align();
let bytes = layout.size();

let new_end = end.checked_sub(bytes)? & !(align - 1);
if start <= new_end {
let new_end = new_end as *mut u8;
let new_end = old_end.with_addr(new_end);
self.end.set(new_end);
Some(new_end)
} else {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#![feature(once_cell)]
#![feature(nll)]
#![feature(associated_type_bounds)]
#![feature(strict_provenance)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mono_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
fn to_raw_string(&self) -> String {
match *self {
MonoItem::Fn(instance) => {
format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr() as usize)
format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr().addr())
}
MonoItem::Static(id) => format!("Static({:?})", id),
MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id),
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_data_structures/src/tagged_ptr.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// FIXME(strict_provenance_magic): rustc is grounded for pointer crimes.
#![cfg_attr(not(bootstrap), allow(fuzzy_provenance_casts))]

//! This module implements tagged pointers.
//!
//! In order to utilize the pointer packing, you must have two types: a pointer,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// FIXME(strict_provenance_magic): rustc is grounded for pointer crimes.
#![cfg_attr(not(bootstrap), allow(fuzzy_provenance_casts))]

use libloading::Library;
use rustc_ast as ast;
use rustc_codegen_ssa::traits::CodegenBackend;
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/ty/adt.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// FIXME(strict_provenance_magic): rustc is grounded for pointer crimes.
#![cfg_attr(not(bootstrap), allow(fuzzy_provenance_casts))]

use crate::mir::interpret::ErrorHandled;
use crate::ty;
use crate::ty::util::{Discr, IntTypeExt};
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//! Type context book-keeping.

// FIXME(strict_provenance_magic): rustc is grounded for pointer crimes.
#![cfg_attr(not(bootstrap), allow(fuzzy_provenance_casts))]

use crate::arena::Arena;
use crate::dep_graph::{DepGraph, DepKind, DepKindStruct};
use crate::hir::place::Place as HirPlace;
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/ty/impls_ty.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! This module contains `HashStable` implementations for various data types
//! from `rustc_middle::ty` in no particular order.

// FIXME(strict_provenance_magic): rustc is grounded for pointer crimes.
#![cfg_attr(not(bootstrap), allow(fuzzy_provenance_casts))]

use crate::middle::region;
use crate::mir;
use crate::ty;
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/ty/list.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// FIXME(strict_provenance_magic): rustc is grounded for pointer crimes.
#![cfg_attr(not(bootstrap), allow(fuzzy_provenance_casts))]

use crate::arena::Arena;
use rustc_serialize::{Encodable, Encoder};
use std::alloc::Layout;
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/ty/subst.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// Type substitutions.

// FIXME(strict_provenance_magic): rustc is grounded for pointer crimes.
#![cfg_attr(not(bootstrap), allow(fuzzy_provenance_casts))]

use crate::mir;
use crate::ty::codec::{TyDecoder, TyEncoder};
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor};
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// FIXME(strict_provenance_magic): rustc is grounded for pointer crimes.
#![cfg_attr(not(bootstrap), allow(fuzzy_provenance_casts))]

use super::diagnostics::SnapshotParser;
use super::pat::{CommaRecoveryMode, RecoverColon, RecoverComma, PARAM_EXPECTED};
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
Expand Down