Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Index out of range panic when displaying ParseError::InvalidByteCount #36

Open
ohazi opened this issue Feb 19, 2024 · 2 comments
Open

Comments

@ohazi
Copy link

ohazi commented Feb 19, 2024

The following code panics:

fn main() {
    println!("{}", eui48::MacAddress::parse_str("123456ABCDEF1").unwrap_err());
}
ohazi@avocado:~/source/eui48_index_out_of_range$ RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/eui48_index_out_of_range`
thread 'main' panicked at /home/ohazi/.cargo/registry/src/index.crates.io-6f17d22bba15001f/eui48-1.1.0/src/lib.rs:300:21:
range end index 7 out of range for slice of length 6
stack backtrace:
   0: rust_begin_unwind
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:645:5
   1: core::panicking::panic_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panicking.rs:72:14
   2: core::slice::index::slice_end_index_len_fail_rt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/slice/index.rs:76:5
   3: core::slice::index::slice_end_index_len_fail
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/slice/index.rs:68:9
   4: <core::ops::range::Range<usize> as core::slice::index::SliceIndex<[T]>>::index
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/slice/index.rs:408:13
   5: <core::ops::range::RangeTo<usize> as core::slice::index::SliceIndex<[T]>>::index
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/slice/index.rs:455:9
   6: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/slice/index.rs:18:9
   7: core::array::<impl core::ops::index::Index<I> for [T; N]>::index
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/array/mod.rs:348:9
   8: <eui48::ParseError as core::fmt::Display>::fmt
             at /home/ohazi/.cargo/registry/src/index.crates.io-6f17d22bba15001f/eui48-1.1.0/src/lib.rs:300:21
   9: core::fmt::rt::Argument::fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/fmt/rt.rs:142:9
  10: core::fmt::write
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/fmt/mod.rs:1120:17
  11: std::io::Write::write_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/io/mod.rs:1762:15
  12: <&std::io::stdio::Stdout as std::io::Write>::write_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/io/stdio.rs:727:9
  13: <std::io::stdio::Stdout as std::io::Write>::write_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/io/stdio.rs:701:9
  14: std::io::stdio::print_to
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/io/stdio.rs:1020:21
  15: std::io::stdio::_print
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/io/stdio.rs:1097:5
  16: eui48_index_out_of_range::main
             at ./src/main.rs:2:5
  17: core::ops::function::FnOnce::call_once
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
ohazi@avocado:~/source/eui48_index_out_of_range$ 

The culprit is this line: https://github.com/abaumhauer/eui48/blob/master/src/lib.rs#L300

In ParseError::InvalidByteCount(found, eui), found is the number of bytes encountered (in this case seven bytes, more than the expected six bytes), and eui is the eui48 that was created out of the first six bytes. You cannot index into eui beyond six, which is what &eui[..found] on line 300 appears to be trying to do.

@sjoqvist
Copy link

sjoqvist commented Feb 18, 2025

I recreated the bug before discovering this issue. 01:23:45:01:23:45:01:23 returns an error but 0123450123450123 causes a panic.

# Cargo.toml

[package]
name = "test-eui48"
version = "0.1.0"
edition = "2021"

[dependencies]
eui48 = { version = "1.1.0", features = ["serde"] }
serde_json = "1.0.138"
// src/main.rs

use serde_json::from_str;
type Res = Result<eui48::MacAddress, serde_json::Error>;

fn main() {
    // Ok(MacAddress("01:23:45:01:23:45"))
    let addr: Res = from_str("\"01:23:45:01:23:45\"");
    println!("{addr:?}");

    // Ok(MacAddress("01:23:45:01:23:45"))
    let addr: Res = from_str("\"012345012345\"");
    println!("{addr:?}");

    // Err(Error("Invalid length; expecting 11 to 17 chars, found 23", line: 1, column: 25))
    let addr: Res = from_str("\"01:23:45:01:23:45:01:23\"");
    println!("{addr:?}");

    // thread 'main' panicked at /home/foo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/eui48-1.1.0/src/lib.rs:300:21:
    // range end index 8 out of range for slice of length 6
    // note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    let _addr: Res = from_str("\"0123450123450123\"");
}

I was planning to parse JSON provided by the user. It's good that I tested bad strings before deploying the code, but this needs to be fixed as it's too easy for a malicious user to crash the software.

@ohazi
Copy link
Author

ohazi commented Feb 18, 2025

FWIW, my proposed one line fix from a year ago would work here:

ohazi@avocado:~/source/test-eui48$ cargo run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s
     Running `target/debug/test-eui48`
Ok(MacAddress("01:23:45:01:23:45"))
Ok(MacAddress("01:23:45:01:23:45"))
Err(Error("Invalid length; expecting 11 to 17 chars, found 23", line: 1, column: 25))
ohazi@avocado:~/source/test-eui48$ 

(and if you add one last println):

ohazi@avocado:~/source/test-eui48$ cargo run
   Compiling test-eui48 v0.1.0 (/home/ohazi/source/test-eui48)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.28s
     Running `target/debug/test-eui48`
Ok(MacAddress("01:23:45:01:23:45"))
Ok(MacAddress("01:23:45:01:23:45"))
Err(Error("Invalid length; expecting 11 to 17 chars, found 23", line: 1, column: 25))
Err(Error("Invalid byte count; Matched `8` bytes ([1, 35, 69, 1, 35, 69])", line: 1, column: 18))
ohazi@avocado:~/source/test-eui48$ 

but alas, it hasn't been merged, nor has this crate seen any released updates since 2020.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants