VYPR
Moderate severityNVD Advisory· Published Feb 4, 2026· Updated Feb 5, 2026

Bytes is vulnerable to integer overflow in BytesMut::reserve

CVE-2026-25541

Description

Bytes is a utility library for working with bytes. From version 1.2.1 to before 1.11.1, Bytes is vulnerable to integer overflow in BytesMut::reserve. In the unique reclaim path of BytesMut::reserve, if the condition "v_capacity >= new_cap + offset" uses an unchecked addition. When new_cap + offset overflows usize in release builds, this condition may incorrectly pass, causing self.cap to be set to a value that exceeds the actual allocated capacity. Subsequent APIs such as spare_capacity_mut() then trust this corrupted cap value and may create out-of-bounds slices, leading to UB. This behavior is observable in release builds (integer overflow wraps), whereas debug builds panic due to overflow checks. This issue has been patched in version 1.11.1.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Integer overflow in BytesMut::reserve in the bytes crate (versions 1.2.1 to 1.11.0) can lead to out-of-bounds memory access and undefined behavior in release builds.

The vulnerability resides in the BytesMut::reserve method of the bytes crate, specifically in the unique reclaim path. The condition v_capacity >= new_cap + offset uses an unchecked addition; when new_cap + offset overflows usize in release builds, the condition may incorrectly pass, causing self.cap to be set to a value that exceeds the actual allocated capacity [1][3]. This integer overflow is not caught because release builds wrap on overflow, whereas debug builds panic due to overflow checks [1].

Exploitation requires no authentication and is triggered by any code path that calls BytesMut::reserve with sizes large enough to cause the overflow. The bug is in the library's internal logic, so any application using the affected versions of bytes and processing untrusted data that influences buffer sizes could be at risk [1][3].

Once self.cap is corrupted, subsequent APIs such as spare_capacity_mut() trust the inflated capacity and may create out-of-bounds slices, leading to undefined behavior (memory corruption) [1][3]. This can potentially be leveraged for more severe security impacts depending on the application context.

The issue has been patched in version 1.11.1 of the bytes crate [2][4]. Users are advised to update immediately. The fix introduces a checked addition (checked_add) to prevent the overflow, ensuring the condition is evaluated correctly [2]. No workaround is available for affected versions.

AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
bytescrates.io
>= 1.2.1, < 1.11.11.11.1

Affected products

1
  • tokio-rs/bytesv5
    Range: >= 1.2.1, < 1.11.1

Patches

1
d0293b0e3583

Merge commit from fork

https://github.com/tokio-rs/bytesAlice RyhlFeb 3, 2026via ghsa
3 files changed · +28 8
  • ci/miri.sh+3 0 modified
    @@ -8,3 +8,6 @@ export MIRIFLAGS="-Zmiri-strict-provenance"
     
     cargo miri test
     cargo miri test --target mips64-unknown-linux-gnuabi64
    +
    +# run with wrapping integer overflow instead of panic
    +cargo miri test --release
    
  • src/bytes_mut.rs+12 8 modified
    @@ -695,9 +695,15 @@ impl BytesMut {
     
                     let offset = self.ptr.as_ptr().offset_from(ptr) as usize;
     
    +                let new_cap_plus_offset = match new_cap.checked_add(offset) {
    +                    Some(new_cap_plus_offset) => new_cap_plus_offset,
    +                    None if !allocate => return false,
    +                    None => panic!("overflow"),
    +                };
    +
                     // Compare the condition in the `kind == KIND_VEC` case above
                     // for more details.
    -                if v_capacity >= new_cap + offset {
    +                if v_capacity >= new_cap_plus_offset {
                         self.cap = new_cap;
                         // no copy is necessary
                     } else if v_capacity >= new_cap && offset >= len {
    @@ -713,14 +719,12 @@ impl BytesMut {
                         if !allocate {
                             return false;
                         }
    -                    // calculate offset
    -                    let off = (self.ptr.as_ptr() as usize) - (v.as_ptr() as usize);
     
                         // new_cap is calculated in terms of `BytesMut`, not the underlying
                         // `Vec`, so it does not take the offset into account.
                         //
                         // Thus we have to manually add it here.
    -                    new_cap = new_cap.checked_add(off).expect("overflow");
    +                    new_cap = new_cap_plus_offset;
     
                         // The vector capacity is not sufficient. The reserve request is
                         // asking for more than the initial buffer capacity. Allocate more
    @@ -742,13 +746,13 @@ impl BytesMut {
                         // the unused capacity of the vector is copied over to the new
                         // allocation, so we need to ensure that we don't have any data we
                         // care about in the unused capacity before calling `reserve`.
    -                    debug_assert!(off + len <= v.capacity());
    -                    v.set_len(off + len);
    +                    debug_assert!(offset + len <= v.capacity());
    +                    v.set_len(offset + len);
                         v.reserve(new_cap - v.len());
     
                         // Update the info
    -                    self.ptr = vptr(v.as_mut_ptr().add(off));
    -                    self.cap = v.capacity() - off;
    +                    self.ptr = vptr(v.as_mut_ptr().add(offset));
    +                    self.cap = v.capacity() - offset;
                     }
     
                     return true;
    
  • tests/test_bytes.rs+13 0 modified
    @@ -1707,3 +1707,16 @@ fn bytes_mut_put_bytes_specialization() {
         // If allocation is reused, capacity should be equal to original vec capacity.
         assert_eq!(bytes_mut.capacity(), capacity);
     }
    +
    +#[test]
    +#[should_panic]
    +fn bytes_mut_reserve_overflow() {
    +    let mut a = BytesMut::from(&b"hello world"[..]);
    +    let mut b = a.split_off(5);
    +    // Ensure b becomes the unique owner of the backing storage
    +    drop(a);
    +    // Trigger overflow in new_cap + offset inside reserve
    +    b.reserve(usize::MAX - 6);
    +    // This call relies on the corrupted cap and may cause UB & HBO
    +    b.put_u8(b'h');
    +}
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.