From e0764e1e12235585772f0781333e7e0dac577bdd Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Mon, 31 May 2021 17:14:48 +0200 Subject: [PATCH] http2: make decompression a configure-time option --- .github/workflows/builds.yml | 2 +- configure.ac | 9 +++++++++ rust/Cargo.toml.in | 5 +++-- rust/Makefile.am | 4 ++++ rust/src/http2/http2.rs | 12 ++++++++++++ rust/src/http2/mod.rs | 1 + src/suricata.c | 3 ++- 7 files changed, 32 insertions(+), 4 deletions(-) diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index fd845dfcaff0..736020e9f5e0 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -641,7 +641,7 @@ jobs: chmod 755 $HOME/.cargo/bin/cbindgen echo "$HOME/.cargo/bin" >> $GITHUB_PATH - run: ./autogen.sh - - run: CFLAGS="$DEFAULT_CFLAGS -DNDEBUG" ./configure --enable-unittests + - run: CFLAGS="$DEFAULT_CFLAGS -DNDEBUG" ./configure --enable-unittests --enable-http2-decompression - run: make -j2 - run: make check - run: make dist diff --git a/configure.ac b/configure.ac index a9f9746ba39b..85f769bebabf 100644 --- a/configure.ac +++ b/configure.ac @@ -521,6 +521,14 @@ ]) AM_CONDITIONAL([DEBUG_VALIDATION], [test "x$enable_debug_validation" = "xyes"]) + # enable http2 decompression + AC_ARG_ENABLE(http2-decompression, + AS_HELP_STRING([--enable-http2-decompression], [Enable http2 decompression]),[enable_http2_decompression=$enableval],[enable_http2_decompression=no]) + AS_IF([test "x$enable_http2_decompression" = "xyes"], [ + AC_DEFINE([HTTP2_DECOMPRESSION],[1],[Enable http2 decompression]) + ]) + AM_CONDITIONAL([HTTP2_DECOMPRESSION], [test "x$enable_http2_decompression" = "xyes"]) + # profiling support AC_ARG_ENABLE(profiling, AS_HELP_STRING([--enable-profiling], [Enable performance profiling]),[enable_profiling=$enableval],[enable_profiling=no]) @@ -2824,6 +2832,7 @@ SURICATA_BUILD_CONF="Suricata Configuration: Hyperscan support: ${enable_hyperscan} Libnet support: ${enable_libnet} liblz4 support: ${enable_liblz4} + HTTP2 decompression: ${enable_http2_decompression} Rust support: ${enable_rust} Rust strict mode: ${enable_rust_strict} diff --git a/rust/Cargo.toml.in b/rust/Cargo.toml.in index 2dff06ee3acf..7ba259bdcc80 100644 --- a/rust/Cargo.toml.in +++ b/rust/Cargo.toml.in @@ -17,6 +17,7 @@ strict = [] debug = [] debug-validate = [] function-macro = [] +decompression = ["flate2", "brotli"] [dependencies] nom = "= 5.1.1" @@ -30,8 +31,8 @@ num-derive = "0.2" num-traits = "0.2" widestring = "0.4" md5 = "0.7.0" -flate2 = "1.0" -brotli = "3.3.0" +flate2 = { version = "1.0", optional = true } +brotli = { version = "3.3.0", optional = true } der-parser = "4.0" kerberos-parser = "0.5" diff --git a/rust/Makefile.am b/rust/Makefile.am index 9247012656bf..afe9836e82de 100644 --- a/rust/Makefile.am +++ b/rust/Makefile.am @@ -27,6 +27,10 @@ if DEBUG_VALIDATION RUST_FEATURES += debug-validate endif +if HTTP2_DECOMPRESSION +RUST_FEATURES += decompression +endif + if RUST_CROSS_COMPILE RUST_TARGET = --target $(host_triplet) endif diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs index a3277d10b9ef..c69e91bae9bd 100644 --- a/rust/src/http2/http2.rs +++ b/rust/src/http2/http2.rs @@ -16,6 +16,7 @@ */ use super::files::*; +#[cfg(feature = "decompression")] use super::decompression; use super::parser; use crate::applayer::{self, *}; @@ -127,6 +128,7 @@ pub struct HTTP2Transaction { pub frames_tc: Vec, pub frames_ts: Vec, + #[cfg(feature = "decompression")] decoder: decompression::HTTP2Decoder, de_state: Option<*mut core::DetectEngineState>, @@ -149,6 +151,7 @@ impl HTTP2Transaction { state: HTTP2TransactionState::HTTP2StateIdle, frames_tc: Vec::new(), frames_ts: Vec::new(), + #[cfg(feature = "decompression")] decoder: decompression::HTTP2Decoder::new(), de_state: None, events: std::ptr::null_mut(), @@ -168,6 +171,10 @@ impl HTTP2Transaction { } } + #[cfg(not(feature = "decompression"))] + fn handle_headers(&mut self, _blocks: &Vec, _dir: u8) {} + + #[cfg(feature = "decompression")] fn handle_headers(&mut self, blocks: &Vec, dir: u8) { for i in 0..blocks.len() { if blocks[i].name == "content-encoding".as_bytes().to_vec() { @@ -180,8 +187,13 @@ impl HTTP2Transaction { &'a mut self, input: &'a [u8], dir: u8, sfcm: &'static SuricataFileContext, over: bool, files: &mut FileContainer, flags: u16, ) -> io::Result<()> { + #[cfg(feature = "decompression")] let mut output = Vec::with_capacity(decompression::HTTP2_DECOMPRESSION_CHUNK_SIZE); + #[cfg(feature = "decompression")] let decompressed = self.decoder.decompress(input, &mut output, dir)?; + #[cfg(not(feature = "decompression"))] + let decompressed = input; + let xid: u32 = self.tx_id as u32; if dir == STREAM_TOCLIENT { self.ft_tc.new_chunk( diff --git a/rust/src/http2/mod.rs b/rust/src/http2/mod.rs index d6dcb55eca47..105b115e8c5e 100644 --- a/rust/src/http2/mod.rs +++ b/rust/src/http2/mod.rs @@ -15,6 +15,7 @@ * 02110-1301, USA. */ +#[cfg(feature = "decompression")] mod decompression; pub mod detect; pub mod files; diff --git a/src/suricata.c b/src/suricata.c index 3187e0a9dd03..712a2b387e2b 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -704,8 +704,9 @@ static void PrintBuildInfo(void) #ifdef HAVE_NSS strlcat(features, "HAVE_NSS ", sizeof(features)); #endif - /* HTTP2_DECOMPRESSION is not an optional feature in this major version */ +#ifdef HTTP2_DECOMPRESSION strlcat(features, "HTTP2_DECOMPRESSION ", sizeof(features)); +#endif #ifdef HAVE_LUA strlcat(features, "HAVE_LUA ", sizeof(features)); #endif