From c4193371bdfb9067d31ebcf0f74b74beef5c3d55 Mon Sep 17 00:00:00 2001 From: Norbert Szetei <59439874+nszetei@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:28:27 +0100 Subject: [PATCH] fix(svc): rdpdr channel fuzzing harness and associated issues (#408) --- .github/workflows/fuzz.yml | 2 +- Cargo.lock | 1 + crates/ironrdp-fuzzing/Cargo.toml | 3 ++- crates/ironrdp-fuzzing/src/oracles/mod.rs | 10 ++++++++++ crates/ironrdp-rdpdr/src/pdu/efs.rs | 9 +++++---- ...d-from-46dc7754493e2231055dddc1c56c88b4b38e7a6e | Bin 0 -> 39 bytes fuzz/Cargo.lock | 1 + fuzz/Cargo.toml | 7 +++++++ fuzz/fuzz_targets/channel_processing.rs | 7 +++++++ xtask/src/main.rs | 8 +++++++- 10 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 crates/ironrdp-testsuite-core/test_data/fuzz_regression/channel_processing/minimized-from-46dc7754493e2231055dddc1c56c88b4b38e7a6e create mode 100644 fuzz/fuzz_targets/channel_processing.rs diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 6a4dcfaf..e319aeaa 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -41,7 +41,7 @@ jobs: strategy: fail-fast: false matrix: - target: [ pdu_decoding, rle_decompression, bitmap_stream, cliprdr_format ] + target: [ pdu_decoding, rle_decompression, bitmap_stream, cliprdr_format, channel_processing ] steps: - uses: actions/checkout@v3 diff --git a/Cargo.lock b/Cargo.lock index 4aaaa69a..f0193989 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1806,6 +1806,7 @@ dependencies = [ "ironrdp-graphics", "ironrdp-pdu", "ironrdp-rdpdr", + "ironrdp-svc", ] [[package]] diff --git a/crates/ironrdp-fuzzing/Cargo.toml b/crates/ironrdp-fuzzing/Cargo.toml index 5b0bc45e..3e15919f 100644 --- a/crates/ironrdp-fuzzing/Cargo.toml +++ b/crates/ironrdp-fuzzing/Cargo.toml @@ -16,4 +16,5 @@ ironrdp-pdu.workspace = true ironrdp-cliprdr.workspace = true ironrdp-rdpdr.workspace = true ironrdp-cliprdr-format.workspace = true -ironrdp-displaycontrol.workspace = true \ No newline at end of file +ironrdp-displaycontrol.workspace = true +ironrdp-svc.workspace = true diff --git a/crates/ironrdp-fuzzing/src/oracles/mod.rs b/crates/ironrdp-fuzzing/src/oracles/mod.rs index 74812b07..143010eb 100644 --- a/crates/ironrdp-fuzzing/src/oracles/mod.rs +++ b/crates/ironrdp-fuzzing/src/oracles/mod.rs @@ -136,3 +136,13 @@ pub fn cliprdr_format(input: &[u8]) { let _ = plain_html_to_cf_html(input); } } + +pub fn channel_process(input: &[u8]) { + use ironrdp_svc::SvcProcessor; + + let mut rdpdr = ironrdp_rdpdr::Rdpdr::new(Box::new(ironrdp_rdpdr::NoopRdpdrBackend), "Backend".to_owned()) + .with_smartcard(1) + .with_drives(None); + + let _ = rdpdr.process(input); +} diff --git a/crates/ironrdp-rdpdr/src/pdu/efs.rs b/crates/ironrdp-rdpdr/src/pdu/efs.rs index 99e291c3..25e36384 100644 --- a/crates/ironrdp-rdpdr/src/pdu/efs.rs +++ b/crates/ironrdp-rdpdr/src/pdu/efs.rs @@ -1214,12 +1214,13 @@ impl DeviceControlRequest where T::Error: ironrdp_error::Source, { - fn headerless_size() -> usize { - size_of::() * 3 // OutputBufferLength, InputBufferLength, IoControlCode - } + const HEADERLESS_SIZE: usize = 4 // OutputBufferLength + + 4 // InputBufferLength + + 4 // IoControlCode + + 20; // Additional 20 bytes for padding pub fn decode(header: DeviceIoRequest, src: &mut ReadCursor<'_>) -> PduResult { - ensure_size!(ctx: "DeviceControlRequest", in: src, size: Self::headerless_size()); + ensure_size!(ctx: "DeviceControlRequest", in: src, size: Self::HEADERLESS_SIZE); let output_buffer_length = src.read_u32(); let input_buffer_length = src.read_u32(); let io_control_code = T::try_from(src.read_u32()).map_err(|e| { diff --git a/crates/ironrdp-testsuite-core/test_data/fuzz_regression/channel_processing/minimized-from-46dc7754493e2231055dddc1c56c88b4b38e7a6e b/crates/ironrdp-testsuite-core/test_data/fuzz_regression/channel_processing/minimized-from-46dc7754493e2231055dddc1c56c88b4b38e7a6e new file mode 100644 index 0000000000000000000000000000000000000000..0db07781e2954c8550e50ce0485a1795fb3f9952 GIT binary patch literal 39 kcmXSN3G!rQU|?Wm=w$!_J`e%I91IK!3=9l144fby07dx%JOBUy literal 0 HcmV?d00001 diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 2ef9508c..c5124147 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -321,6 +321,7 @@ dependencies = [ "ironrdp-graphics", "ironrdp-pdu", "ironrdp-rdpdr", + "ironrdp-svc", ] [[package]] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 57c12e8d..faf8b38b 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -40,3 +40,10 @@ name = "cliprdr_format" path = "fuzz_targets/cliprdr_format.rs" test = false doc = false + +[[bin]] +name = "channel_processing" +path = "fuzz_targets/channel_processing.rs" +test = false +doc = false +bench = false diff --git a/fuzz/fuzz_targets/channel_processing.rs b/fuzz/fuzz_targets/channel_processing.rs new file mode 100644 index 00000000..26fc1f6e --- /dev/null +++ b/fuzz/fuzz_targets/channel_processing.rs @@ -0,0 +1,7 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| { + ironrdp_fuzzing::oracles::channel_process(data); +}); diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 26a25067..d420de90 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -33,7 +33,13 @@ pub const CARGO: &str = env!("CARGO"); pub const WASM_PACKAGES: &[&str] = &["ironrdp-web"]; -pub const FUZZ_TARGETS: &[&str] = &["pdu_decoding", "rle_decompression", "bitmap_stream", "cliprdr_format"]; +pub const FUZZ_TARGETS: &[&str] = &[ + "pdu_decoding", + "rle_decompression", + "bitmap_stream", + "cliprdr_format", + "channel_processing", +]; fn main() -> anyhow::Result<()> { let args = match cli::parse_args() {