Auto merge of #43217 - pnkfelix:alloc-requires-align-it-in-u32, r=alexcrichton
Add precondition to `Layout` that the `align` fit in a u32. Add precondition to `Layout` that the `align` not exceed 2^31. This precondition takes the form of a behavorial change in `Layout::from_size_align` (so it returns `None` if the input `align` is too large) and a new requirement for safe usage of `Layout::from_size_align_unchecked`. Fix #30170.
This commit is contained in:
@@ -65,11 +65,13 @@ pub struct Layout {
|
|||||||
|
|
||||||
impl Layout {
|
impl Layout {
|
||||||
/// Constructs a `Layout` from a given `size` and `align`,
|
/// Constructs a `Layout` from a given `size` and `align`,
|
||||||
/// or returns `None` if either of the following conditions
|
/// or returns `None` if any of the following conditions
|
||||||
/// are not met:
|
/// are not met:
|
||||||
///
|
///
|
||||||
/// * `align` must be a power of two,
|
/// * `align` must be a power of two,
|
||||||
///
|
///
|
||||||
|
/// * `align` must not exceed 2^31 (i.e. `1 << 31`),
|
||||||
|
///
|
||||||
/// * `size`, when rounded up to the nearest multiple of `align`,
|
/// * `size`, when rounded up to the nearest multiple of `align`,
|
||||||
/// must not overflow (i.e. the rounded value must be less than
|
/// must not overflow (i.e. the rounded value must be less than
|
||||||
/// `usize::MAX`).
|
/// `usize::MAX`).
|
||||||
@@ -79,6 +81,10 @@ impl Layout {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if align > (1 << 31) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
// (power-of-two implies align != 0.)
|
// (power-of-two implies align != 0.)
|
||||||
|
|
||||||
// Rounded up size is:
|
// Rounded up size is:
|
||||||
@@ -106,8 +112,10 @@ impl Layout {
|
|||||||
///
|
///
|
||||||
/// # Unsafety
|
/// # Unsafety
|
||||||
///
|
///
|
||||||
/// This function is unsafe as it does not verify that `align` is a power of
|
/// This function is unsafe as it does not verify that `align` is
|
||||||
/// two nor that `size` aligned to `align` fits within the address space.
|
/// a power-of-two that is also less than or equal to 2^31, nor
|
||||||
|
/// that `size` aligned to `align` fits within the address space
|
||||||
|
/// (i.e. the `Layout::from_size_align` preconditions).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Layout {
|
pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Layout {
|
||||||
Layout { size: size, align: align }
|
Layout { size: size, align: align }
|
||||||
@@ -217,10 +225,10 @@ impl Layout {
|
|||||||
Some(alloc_size) => alloc_size,
|
Some(alloc_size) => alloc_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
// We can assume that `self.align` is a power-of-two.
|
// We can assume that `self.align` is a power-of-two that does
|
||||||
// Furthermore, `alloc_size` has alreayd been rounded up
|
// not exceed 2^31. Furthermore, `alloc_size` has already been
|
||||||
// to a multiple of `self.align`; therefore, the call
|
// rounded up to a multiple of `self.align`; therefore, the
|
||||||
// to `Layout::from_size_align` below should never panic.
|
// call to `Layout::from_size_align` below should never panic.
|
||||||
Some((Layout::from_size_align(alloc_size, self.align).unwrap(), padded_size))
|
Some((Layout::from_size_align(alloc_size, self.align).unwrap(), padded_size))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user