librasn / rasn

A Safe #[no_std] ASN.1 Codec Framework
Other
183 stars 43 forks source link

OER/COER decode_sequence_of passes invalid data to bitvec load_be resulting in panic from assertion #261

Closed pcwizz closed 1 week ago

pcwizz commented 3 weeks ago

A panic originating from a documented assertion within Bitvec can be reached via the OER decoder. Given that the assertion is documented as part of Bitvec's interface I'm filing the issue here as I think RASN should validate the input length before trying to load an integer from it.

#[test]
fn bitvec_load_panic_oer() {
    let data: [u8; 2] = [
        61,
        11,
    ];

    let r = rasn::oer::decode::<rasn_ocsp::OcspRequest>(&data);
    println!("{:?}", r)
}
thread 'bitvec_load_panic_oer' panicked at /Users/pcwizz/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitvec-1.0.1/src/field.rs:526:5:
cannot load 64 bits from a 0-bit region
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a26981974230110fa8fb15e1cf04d05b9a2103f9/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_fmt
             at /rustc/a26981974230110fa8fb15e1cf04d05b9a2103f9/library/core/src/panicking.rs:72:14
   2: bitvec::field::check
             at /Users/pcwizz/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitvec-1.0.1/src/field.rs:526:2
   3: <bitvec::slice::BitSlice<T,bitvec::order::Msb0> as bitvec::field::BitField>::load_be
             at /Users/pcwizz/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitvec-1.0.1/src/field.rs:296:3
   4: <rasn::oer::de::Decoder as rasn::de::Decoder>::decode_sequence_of
             at ./src/oer/de.rs:608:22
   5: <alloc::vec::Vec<T> as rasn::de::Decode>::decode_with_tag_and_constraints
             at ./src/de.rs:523:9
   6: rasn::de::Decode::decode_with_tag
             at ./src/de.rs:31:9
   7: rasn::de::Decode::decode
             at ./src/de.rs:22:9
   8: <rasn_ocsp::TbsRequest as rasn::de::Decode>::decode_with_tag_and_constraints::{{closure}}
             at ./standards/ocsp/src/lib.rs:29:33
   9: <rasn::oer::de::Decoder as rasn::de::Decoder>::decode_sequence
             at ./src/oer/de.rs:582:25
  10: <rasn_ocsp::TbsRequest as rasn::de::Decode>::decode_with_tag_and_constraints
             at ./standards/ocsp/src/lib.rs:29:33
  11: rasn::de::Decode::decode_with_tag
             at ./src/de.rs:31:9
  12: rasn::de::Decode::decode
             at ./src/de.rs:22:9
  13: <rasn_ocsp::OcspRequest as rasn::de::Decode>::decode_with_tag_and_constraints::{{closure}}
             at ./standards/ocsp/src/lib.rs:19:33
  14: <rasn::oer::de::Decoder as rasn::de::Decoder>::decode_sequence
             at ./src/oer/de.rs:582:25
  15: <rasn_ocsp::OcspRequest as rasn::de::Decode>::decode_with_tag_and_constraints
             at ./standards/ocsp/src/lib.rs:19:33
  16: rasn::de::Decode::decode_with_tag
             at ./src/de.rs:31:9
  17: rasn::de::Decode::decode
             at ./src/de.rs:22:9
  18: rasn::oer::decode
             at ./src/oer.rs:15:5
  19: bitvecloadpanicoer::bitvec_load_panic_oer
             at ./tests/bitvecloadpanicoer.rs:8:13
  20: bitvecloadpanicoer::bitvec_load_panic_oer::{{closure}}
             at ./tests/bitvecloadpanicoer.rs:2:27
  21: core::ops::function::FnOnce::call_once
             at /rustc/a26981974230110fa8fb15e1cf04d05b9a2103f9/library/core/src/ops/function.rs:250:5
  22: core::ops::function::FnOnce::call_once
             at /rustc/a26981974230110fa8fb15e1cf04d05b9a2103f9/library/core/src/ops/function.rs:250:5
pcwizz commented 3 weeks ago

The assertion can also be hit from COER and with to long an input rather than to short.

#[test]
fn bitvec_load_panic_coer() {
    let data: [u8; 108] = [
        3,
        0,
        0,
        0,
        1,
        0,
        1,
        128,
        1,
        1,
        16,
        16,
        16,
        16,
        1,
        0,
        16,
        16,
        16,
        16,
        96,
        16,
        16,
        16,
        16,
        16,
        16,
        9,
        0,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        20,
        16,
        30,
        0,
        16,
        16,
        16,
        16,
        16,
        16,
        18,
        16,
        16,
        16,
        16,
        16,
        58,
        16,
        16,
        128,
        1,
        128,
        39,
        128,
        1,
        128,
        39,
        128,
        16,
        1,
        128,
        4,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        16,
        18,
        16,
        4,
        85,
        14,
        59,
        4,
        1,
        4,
        4,
        4,
        90,
        4,
        4,
        47,
    ];

    let r = rasn::coer::decode::<rasn_snmp::v3::Message>(&data);
    println!("{:?}", r)
}
thread 'bitvec_load_panic_coer' panicked at /Users/pcwizz/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitvec-1.0.1/src/field.rs:526:5:
cannot load 64 bits from a 128-bit region
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a26981974230110fa8fb15e1cf04d05b9a2103f9/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_fmt
             at /rustc/a26981974230110fa8fb15e1cf04d05b9a2103f9/library/core/src/panicking.rs:72:14
   2: bitvec::field::check
             at /Users/pcwizz/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitvec-1.0.1/src/field.rs:526:2
   3: <bitvec::slice::BitSlice<T,bitvec::order::Msb0> as bitvec::field::BitField>::load_be
             at /Users/pcwizz/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitvec-1.0.1/src/field.rs:296:3
   4: <rasn::oer::de::Decoder as rasn::de::Decoder>::decode_sequence_of
             at ./src/oer/de.rs:608:22
   5: <alloc::vec::Vec<T> as rasn::de::Decode>::decode_with_tag_and_constraints
             at ./src/de.rs:523:9
   6: rasn::de::Decode::decode_with_tag
             at ./src/de.rs:31:9
   7: rasn::de::Decode::decode
             at ./src/de.rs:22:9
   8: <rasn_snmp::v2::Pdu as rasn::de::Decode>::decode_with_tag_and_constraints::{{closure}}
             at ./standards/snmp/src/v2.rs:59:33
   9: <rasn::oer::de::Decoder as rasn::de::Decoder>::decode_sequence
             at ./src/oer/de.rs:582:25
  10: <rasn_snmp::v2::Pdu as rasn::de::Decode>::decode_with_tag_and_constraints
             at ./standards/snmp/src/v2.rs:59:33
  11: <rasn_snmp::v2::GetRequest as rasn::de::Decode>::decode_with_tag_and_constraints
             at ./standards/snmp/src/v2.rs:19:33
  12: rasn::de::Decode::decode_with_tag
             at ./src/de.rs:31:9
  13: rasn::de::Decode::decode
             at ./src/de.rs:22:9
  14: <rasn_snmp::v2::Pdus as rasn::types::DecodeChoice>::from_tag
             at ./standards/snmp/src/v2.rs:6:33
  15: <rasn::oer::de::Decoder as rasn::de::Decoder>::decode_choice
             at ./src/oer/de.rs:833:13
  16: <rasn_snmp::v2::Pdus as rasn::de::Decode>::decode
             at ./standards/snmp/src/v2.rs:6:33
  17: <rasn_snmp::v3::ScopedPdu as rasn::de::Decode>::decode_with_tag_and_constraints::{{closure}}
             at ./standards/snmp/src/v3.rs:156:33
  18: <rasn::oer::de::Decoder as rasn::de::Decoder>::decode_sequence
             at ./src/oer/de.rs:582:25
  19: <rasn_snmp::v3::ScopedPdu as rasn::de::Decode>::decode_with_tag_and_constraints
             at ./standards/snmp/src/v3.rs:156:33
  20: rasn::de::Decode::decode_with_tag
             at ./src/de.rs:31:9
  21: rasn::de::Decode::decode
             at ./src/de.rs:22:9
  22: <rasn_snmp::v3::ScopedPduData as rasn::types::DecodeChoice>::from_tag
             at ./standards/snmp/src/v3.rs:143:33
  23: <rasn::oer::de::Decoder as rasn::de::Decoder>::decode_choice
             at ./src/oer/de.rs:833:13
  24: <rasn_snmp::v3::ScopedPduData as rasn::de::Decode>::decode
             at ./standards/snmp/src/v3.rs:143:33
  25: <rasn_snmp::v3::Message as rasn::de::Decode>::decode_with_tag_and_constraints::{{closure}}
             at ./standards/snmp/src/v3.rs:25:26
  26: <rasn::oer::de::Decoder as rasn::de::Decoder>::decode_sequence
             at ./src/oer/de.rs:582:25
  27: <rasn_snmp::v3::Message as rasn::de::Decode>::decode_with_tag_and_constraints
             at ./standards/snmp/src/v3.rs:25:26
  28: rasn::de::Decode::decode_with_tag
             at ./src/de.rs:31:9
  29: rasn::de::Decode::decode
             at ./src/de.rs:22:9
  30: rasn::coer::decode
             at ./src/coer.rs:12:5
  31: bitvecloadpaniccoer::bitvec_load_panic_coer
             at ./tests/bitvecloadpaniccoer.rs:114:13
  32: bitvecloadpaniccoer::bitvec_load_panic_coer::{{closure}}
             at ./tests/bitvecloadpaniccoer.rs:2:28
  33: core::ops::function::FnOnce::call_once
             at /rustc/a26981974230110fa8fb15e1cf04d05b9a2103f9/library/core/src/ops/function.rs:250:5
  34: core::ops::function::FnOnce::call_once
             at /rustc/a26981974230110fa8fb15e1cf04d05b9a2103f9/library/core/src/ops/function.rs:250:5
XAMPPRocky commented 3 weeks ago

Cc @Nicceboy

Nicceboy commented 3 weeks ago

Thanks for the issue! Do you mind maybe waiting for weekend before fuzzing further? I created fuzzing setup for all the codecs which covers most of the ASN.1 spec and I have bunch of bugs I haven't had time to fix yet. I can try to finish that now over the weekend. Just to reduce duplicate work.

Nicceboy commented 1 week ago

Fixed on #275