diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:50 +0000 |
commit | 2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35 (patch) | |
tree | d325add32978dbdc1db975a438b3a77d571b1ab8 /vendor/semver/src/identifier.rs | |
parent | Releasing progress-linux version 1.68.2+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35.tar.xz rustc-2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35.zip |
Merging upstream version 1.69.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/semver/src/identifier.rs')
-rw-r--r-- | vendor/semver/src/identifier.rs | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/vendor/semver/src/identifier.rs b/vendor/semver/src/identifier.rs index fbe1df020..0273ae62a 100644 --- a/vendor/semver/src/identifier.rs +++ b/vendor/semver/src/identifier.rs @@ -67,11 +67,13 @@ // allows size_of::<Version>() == size_of::<Option<Version>>(). use crate::alloc::alloc::{alloc, dealloc, handle_alloc_error, Layout}; +use core::isize; use core::mem; use core::num::{NonZeroU64, NonZeroUsize}; use core::ptr::{self, NonNull}; use core::slice; use core::str; +use core::usize; const PTR_BYTES: usize = mem::size_of::<NonNull<u8>>(); @@ -103,6 +105,7 @@ impl Identifier { // SAFETY: string must be ASCII and not contain \0 bytes. pub(crate) unsafe fn new_unchecked(string: &str) -> Self { let len = string.len(); + debug_assert!(len <= isize::MAX as usize); match len as u64 { 0 => Self::empty(), 1..=8 => { @@ -118,8 +121,21 @@ impl Identifier { // SAFETY: len is in a range that does not contain 0. let size = bytes_for_varint(unsafe { NonZeroUsize::new_unchecked(len) }) + len; let align = 2; + // On 32-bit and 16-bit architecture, check for size overflowing + // isize::MAX. Making an allocation request bigger than this to + // the allocator is considered UB. All allocations (including + // static ones) are limited to isize::MAX so we're guaranteed + // len <= isize::MAX, and we know bytes_for_varint(len) <= 5 + // because 128**5 > isize::MAX, which means the only problem + // that can arise is when isize::MAX - 5 <= len <= isize::MAX. + // This is pretty much guaranteed to be malicious input so we + // don't need to care about returning a good error message. + if mem::size_of::<usize>() < 8 { + let max_alloc = usize::MAX / 2 - align; + assert!(size <= max_alloc); + } // SAFETY: align is not zero, align is a power of two, and - // rounding size up to align does not overflow usize::MAX. + // rounding size up to align does not overflow isize::MAX. let layout = unsafe { Layout::from_size_align_unchecked(size, align) }; // SAFETY: layout's size is nonzero. let ptr = unsafe { alloc(layout) }; @@ -200,7 +216,7 @@ impl Clone for Identifier { let size = bytes_for_varint(len) + len.get(); let align = 2; // SAFETY: align is not zero, align is a power of two, and rounding - // size up to align does not overflow usize::MAX. This is just + // size up to align does not overflow isize::MAX. This is just // duplicating a previous allocation where all of these guarantees // were already made. let layout = unsafe { Layout::from_size_align_unchecked(size, align) }; |