rust-pcap / pcap

Rust language pcap library
Apache License 2.0
595 stars 138 forks source link

Double free crash with small buffer sizes #300

Closed Julian-Wollersberger closed 1 year ago

Julian-Wollersberger commented 1 year ago

When using small numbers for snaplen and buffer_size, with immediate mode, the program crashes with the following message:

free(): double free detected in tcache 2
Aborted

tcache is a part of glibc's malloc. The exact values for snaplen and buffer_size don't follow a pattern I could recognize, but values smaller than 1000 seem to always crash.

Minimized example:

use pcap::{Capture, Device};

fn main() {
    // The device doesn't seem to matter, neither do other capture options.
    let main_device = Device::lookup().unwrap().unwrap();
    let mut cap = Capture::from_device(main_device).unwrap()
        .snaplen(10)
        .buffer_size(4000)
        .immediate_mode(true)
        .open().unwrap();
}

Run with:

cargo build
sudo target/debug/pcap_double_free

This is probably a problem in libpcap, but since all the used pcap functions are marked safe, this violates Rust's safety guarantees.

I use Rust 1.69, pcap 1.1.0 and Ubuntu 22.04. The installed libpcap version is 1.10.1. (Strangely, ldd says the binary links to libpcap.so.0.8, but that file is a symlink to libpcap.so.1.10.1)

Wojtek242 commented 1 year ago

Interesting. Thanks for the report!

When I try it on my system, I get

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: PcapError("can't mmap rx ring: Invalid argument")', examples/double_free.rs:12:10

Which is safe behaviour and sort of the behaviour one would expect (supposedly the error is symptomatic of not enough memory). I use Rust 1.67, pcap 1.1.0 and libpcap 1.10.4 on Fedora 37.

I then ran it in a ubuntu:22.04 container and indeed I do get the double free.

My suspicion was then the libpcap version (we are three bugfixes apart). And indeed, the 1.10.2 changelog states that it fixes a double free: https://github.com/the-tcpdump-group/libpcap/blob/master/CHANGES#L135.

Therefore, I'm afraid the fix to this problem is to update libpcap. Would you be able to test with libpcap >= 1.10.2 keeping everything else identical? Perhaps by compiling from source?

Julian-Wollersberger commented 1 year ago

Well, then the unsoundness is a problem that will fix itself with time. Thanks for confirming it.

My original problem was that I didn't know about immediate mode, and the example from the docs didn't seem to work with live capturing. A small buffer was the first thing that worked. I'll just use bigger buffers and immediate mode.

(I've tried to install a newer libpcap for an hour, but I give up.)