From 2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:50 +0200 Subject: Merging upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/semver/src/identifier.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'vendor/semver/src/identifier.rs') 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::() == size_of::>(). 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::>(); @@ -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::() < 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) }; -- cgit v1.2.3