diff options
-rw-r--r-- | recipes-ids/suricata/files/CVE-2024-37151.patch | 53 | ||||
-rw-r--r-- | recipes-ids/suricata/files/CVE-2024-38534.patch | 44 | ||||
-rw-r--r-- | recipes-ids/suricata/files/CVE-2024-38535.patch | 57 | ||||
-rw-r--r-- | recipes-ids/suricata/files/CVE-2024-38535_pre.patch | 292 | ||||
-rw-r--r-- | recipes-ids/suricata/files/CVE-2024-38536.patch | 40 | ||||
-rw-r--r-- | recipes-ids/suricata/suricata_7.0.0.bb | 5 |
6 files changed, 491 insertions, 0 deletions
diff --git a/recipes-ids/suricata/files/CVE-2024-37151.patch b/recipes-ids/suricata/files/CVE-2024-37151.patch new file mode 100644 index 0000000..7e5d8e2 --- /dev/null +++ b/recipes-ids/suricata/files/CVE-2024-37151.patch | |||
@@ -0,0 +1,53 @@ | |||
1 | From a6052dca1e27f3c8f96ec7be0fe7514c56a0d56f Mon Sep 17 00:00:00 2001 | ||
2 | From: Victor Julien <vjulien@oisf.net> | ||
3 | Date: Tue, 4 Jun 2024 14:43:22 +0200 | ||
4 | Subject: [PATCH 1/4] defrag: don't use completed tracker | ||
5 | |||
6 | When a Tracker is set up for a IPID, frags come in for it and it's | ||
7 | reassembled and complete, the `DefragTracker::remove` flag is set. This | ||
8 | is mean to tell the hash cleanup code to recyle the tracker and to let | ||
9 | the lookup code skip the tracker during lookup. | ||
10 | |||
11 | A logic error lead to the following scenario: | ||
12 | |||
13 | 1. there are sufficient frag trackers to make sure the hash table is | ||
14 | filled with trackers | ||
15 | 2. frags for a Packet with IPID X are processed correctly (X1) | ||
16 | 3. frags for a new Packet that also has IPID X come in quickly after the | ||
17 | first (X2). | ||
18 | 4. during the lookup, the frag for X2 hashes to a hash row that holds | ||
19 | more than one tracker | ||
20 | 5. as the trackers in hash row are evaluated, it finds the tracker for | ||
21 | X1, but since the `remove` bit is not checked, it is returned as the | ||
22 | tracker for X2. | ||
23 | 6. reassembly fails, as the tracker is already complete | ||
24 | |||
25 | The logic error is that only for the first tracker in a row the `remove` | ||
26 | bit was checked, leading to reuse to a closed tracker if there were more | ||
27 | trackers in the hash row. | ||
28 | |||
29 | Ticket: #7042. | ||
30 | |||
31 | Upstream-Status: Backport from [https://github.com/OISF/suricata/commit/aab7f35c76721df19403a7c0c0025feae12f3b6b] | ||
32 | CVE: CVE-2024-37151 | ||
33 | Signed-off-by: Siddharth Doshi <sdoshi@mvista.com> | ||
34 | --- | ||
35 | src/defrag-hash.c | 2 +- | ||
36 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
37 | |||
38 | diff --git a/src/defrag-hash.c b/src/defrag-hash.c | ||
39 | index 2f19ce2..87d40f9 100644 | ||
40 | --- a/src/defrag-hash.c | ||
41 | +++ b/src/defrag-hash.c | ||
42 | @@ -591,7 +591,7 @@ DefragTracker *DefragGetTrackerFromHash (Packet *p) | ||
43 | return dt; | ||
44 | } | ||
45 | |||
46 | - if (DefragTrackerCompare(dt, p) != 0) { | ||
47 | + if (!dt->remove && DefragTrackerCompare(dt, p) != 0) { | ||
48 | /* we found our tracker, lets put it on top of the | ||
49 | * hash list -- this rewards active trackers */ | ||
50 | if (dt->hnext) { | ||
51 | -- | ||
52 | 2.44.0 | ||
53 | |||
diff --git a/recipes-ids/suricata/files/CVE-2024-38534.patch b/recipes-ids/suricata/files/CVE-2024-38534.patch new file mode 100644 index 0000000..14a958c --- /dev/null +++ b/recipes-ids/suricata/files/CVE-2024-38534.patch | |||
@@ -0,0 +1,44 @@ | |||
1 | From f1645ea911d4e90b1be8ee5863e8e1a665079cce Mon Sep 17 00:00:00 2001 | ||
2 | From: Philippe Antoine <pantoine@oisf.net> | ||
3 | Date: Thu, 25 Apr 2024 21:24:33 +0200 | ||
4 | Subject: [PATCH 2/4] modbus: abort flow parsing on flood | ||
5 | |||
6 | Ticket: 6987 | ||
7 | |||
8 | Let's not spend more resources for a flow which is trying to | ||
9 | make us do it... | ||
10 | |||
11 | (cherry picked from commit 37509e8e0ed097f8e0174df754835ac60584fc72) | ||
12 | |||
13 | Upstream-Status: Backport from [https://github.com/OISF/suricata/commit/a753cdbe84caee3b66d0bf49b2712d29a50d67ae] | ||
14 | CVE: CVE-2024-38534 | ||
15 | Signed-off-by: Siddharth Doshi <sdoshi@mvista.com> | ||
16 | --- | ||
17 | rust/src/modbus/modbus.rs | 4 ++-- | ||
18 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
19 | |||
20 | diff --git a/rust/src/modbus/modbus.rs b/rust/src/modbus/modbus.rs | ||
21 | index 246e9ca..d2f7c6b 100644 | ||
22 | --- a/rust/src/modbus/modbus.rs | ||
23 | +++ b/rust/src/modbus/modbus.rs | ||
24 | @@ -189,7 +189,7 @@ impl ModbusState { | ||
25 | None => { | ||
26 | let mut tx = match self.new_tx() { | ||
27 | Some(tx) => tx, | ||
28 | - None => return AppLayerResult::ok(), | ||
29 | + None => return AppLayerResult::err(), | ||
30 | }; | ||
31 | tx.set_events_from_flags(&msg.error_flags); | ||
32 | tx.request = Some(msg); | ||
33 | @@ -215,7 +215,7 @@ impl ModbusState { | ||
34 | None => { | ||
35 | let mut tx = match self.new_tx() { | ||
36 | Some(tx) => tx, | ||
37 | - None => return AppLayerResult::ok(), | ||
38 | + None => return AppLayerResult::err(), | ||
39 | }; | ||
40 | if msg | ||
41 | .access_type | ||
42 | -- | ||
43 | 2.44.0 | ||
44 | |||
diff --git a/recipes-ids/suricata/files/CVE-2024-38535.patch b/recipes-ids/suricata/files/CVE-2024-38535.patch new file mode 100644 index 0000000..7ac72c8 --- /dev/null +++ b/recipes-ids/suricata/files/CVE-2024-38535.patch | |||
@@ -0,0 +1,57 @@ | |||
1 | From 6b00dc36d7527f051c2346f03d20f8d9e5a60138 Mon Sep 17 00:00:00 2001 | ||
2 | From: Philippe Antoine <pantoine@oisf.net> | ||
3 | Date: Mon, 17 Jun 2024 16:30:49 +0200 | ||
4 | Subject: [PATCH 3/4] http2: do not expand duplicate headers | ||
5 | |||
6 | Ticket: 7104 | ||
7 | |||
8 | As this can cause a big mamory allocation due to the quadratic | ||
9 | nature of the HPACK compression. | ||
10 | |||
11 | (cherry picked from commit 5bd17934df321b88f502d48afdd6cc8bad4787a7) | ||
12 | |||
13 | Upstream-Status: Backport from [https://github.com/OISF/suricata/commit/c82fa5ca0d1ce0bd8f936e0b860707a6571373b2] | ||
14 | CVE: CVE-2024-38535 | ||
15 | Signed-off-by: Siddharth Doshi <sdoshi@mvista.com> | ||
16 | --- | ||
17 | rust/src/http2/detect.rs | 8 ++++---- | ||
18 | 1 file changed, 4 insertions(+), 4 deletions(-) | ||
19 | |||
20 | diff --git a/rust/src/http2/detect.rs b/rust/src/http2/detect.rs | ||
21 | index 99261ad..9c2f8ab 100644 | ||
22 | --- a/rust/src/http2/detect.rs | ||
23 | +++ b/rust/src/http2/detect.rs | ||
24 | @@ -432,11 +432,11 @@ pub fn http2_frames_get_header_value_vec( | ||
25 | if found == 0 { | ||
26 | vec.extend_from_slice(&block.value); | ||
27 | found = 1; | ||
28 | - } else if found == 1 { | ||
29 | + } else if found == 1 && Rc::strong_count(&block.name) <= 2 { | ||
30 | vec.extend_from_slice(&[b',', b' ']); | ||
31 | vec.extend_from_slice(&block.value); | ||
32 | found = 2; | ||
33 | - } else { | ||
34 | + } else if Rc::strong_count(&block.name) <= 2 { | ||
35 | vec.extend_from_slice(&[b',', b' ']); | ||
36 | vec.extend_from_slice(&block.value); | ||
37 | } | ||
38 | @@ -469,14 +469,14 @@ fn http2_frames_get_header_value<'a>( | ||
39 | if found == 0 { | ||
40 | single = Ok(&block.value); | ||
41 | found = 1; | ||
42 | - } else if found == 1 { | ||
43 | + } else if found == 1 && Rc::strong_count(&block.name) <= 2 { | ||
44 | if let Ok(s) = single { | ||
45 | vec.extend_from_slice(s); | ||
46 | } | ||
47 | vec.extend_from_slice(&[b',', b' ']); | ||
48 | vec.extend_from_slice(&block.value); | ||
49 | found = 2; | ||
50 | - } else { | ||
51 | + } else if Rc::strong_count(&block.name) <= 2 { | ||
52 | vec.extend_from_slice(&[b',', b' ']); | ||
53 | vec.extend_from_slice(&block.value); | ||
54 | } | ||
55 | -- | ||
56 | 2.44.0 | ||
57 | |||
diff --git a/recipes-ids/suricata/files/CVE-2024-38535_pre.patch b/recipes-ids/suricata/files/CVE-2024-38535_pre.patch new file mode 100644 index 0000000..2aa42c4 --- /dev/null +++ b/recipes-ids/suricata/files/CVE-2024-38535_pre.patch | |||
@@ -0,0 +1,292 @@ | |||
1 | From 390f09692eb99809c679d3f350c7cc185d163e1a Mon Sep 17 00:00:00 2001 | ||
2 | From: Philippe Antoine <pantoine@oisf.net> | ||
3 | Date: Wed, 27 Mar 2024 14:33:54 +0100 | ||
4 | Subject: [PATCH] http2: use a reference counter for headers | ||
5 | |||
6 | Ticket: 6892 | ||
7 | |||
8 | As HTTP hpack header compression allows one single byte to | ||
9 | express a previously seen arbitrary-size header block (name+value) | ||
10 | we should avoid to copy the vectors data, but just point | ||
11 | to the same data, while reamining memory safe, even in the case | ||
12 | of later headers eviction from the dybnamic table. | ||
13 | |||
14 | Rust std solution is Rc, and the use of clone, so long as the | ||
15 | data is accessed by only one thread. | ||
16 | |||
17 | Note: This patch is needed to patch CVE-2024-38535 as it defines Rc. | ||
18 | Upstream-Status: Backport from [https://github.com/OISF/suricata/commit/390f09692eb99809c679d3f350c7cc185d163e1a] | ||
19 | Signed-off-by: Siddharth Doshi <sdoshi@mvista.com> | ||
20 | --- | ||
21 | rust/src/http2/detect.rs | 19 +++++++------ | ||
22 | rust/src/http2/http2.rs | 2 +- | ||
23 | rust/src/http2/parser.rs | 61 +++++++++++++++++++++------------------- | ||
24 | 3 files changed, 43 insertions(+), 39 deletions(-) | ||
25 | |||
26 | diff --git a/rust/src/http2/detect.rs b/rust/src/http2/detect.rs | ||
27 | index 9c2f8ab..e068a17 100644 | ||
28 | --- a/rust/src/http2/detect.rs | ||
29 | +++ b/rust/src/http2/detect.rs | ||
30 | @@ -23,6 +23,7 @@ use crate::core::Direction; | ||
31 | use crate::detect::uint::{detect_match_uint, DetectUintData}; | ||
32 | use std::ffi::CStr; | ||
33 | use std::str::FromStr; | ||
34 | +use std::rc::Rc; | ||
35 | |||
36 | fn http2_tx_has_frametype( | ||
37 | tx: &mut HTTP2Transaction, direction: Direction, value: u8, | ||
38 | @@ -404,7 +405,7 @@ fn http2_frames_get_header_firstvalue<'a>( | ||
39 | for frame in frames { | ||
40 | if let Some(blocks) = http2_header_blocks(frame) { | ||
41 | for block in blocks.iter() { | ||
42 | - if block.name == name.as_bytes() { | ||
43 | + if block.name.as_ref() == name.as_bytes() { | ||
44 | return Ok(&block.value); | ||
45 | } | ||
46 | } | ||
47 | @@ -428,7 +429,7 @@ pub fn http2_frames_get_header_value_vec( | ||
48 | for frame in frames { | ||
49 | if let Some(blocks) = http2_header_blocks(frame) { | ||
50 | for block in blocks.iter() { | ||
51 | - if block.name == name.as_bytes() { | ||
52 | + if block.name.as_ref() == name.as_bytes() { | ||
53 | if found == 0 { | ||
54 | vec.extend_from_slice(&block.value); | ||
55 | found = 1; | ||
56 | @@ -465,7 +466,7 @@ fn http2_frames_get_header_value<'a>( | ||
57 | for frame in frames { | ||
58 | if let Some(blocks) = http2_header_blocks(frame) { | ||
59 | for block in blocks.iter() { | ||
60 | - if block.name == name.as_bytes() { | ||
61 | + if block.name.as_ref() == name.as_bytes() { | ||
62 | if found == 0 { | ||
63 | single = Ok(&block.value); | ||
64 | found = 1; | ||
65 | @@ -905,8 +906,8 @@ fn http2_tx_set_header(state: &mut HTTP2State, name: &[u8], input: &[u8]) { | ||
66 | }; | ||
67 | let mut blocks = Vec::new(); | ||
68 | let b = parser::HTTP2FrameHeaderBlock { | ||
69 | - name: name.to_vec(), | ||
70 | - value: input.to_vec(), | ||
71 | + name: Rc::new(name.to_vec()), | ||
72 | + value: Rc::new(input.to_vec()), | ||
73 | error: parser::HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSuccess, | ||
74 | sizeupdate: 0, | ||
75 | }; | ||
76 | @@ -1061,15 +1062,15 @@ mod tests { | ||
77 | }; | ||
78 | let mut blocks = Vec::new(); | ||
79 | let b = parser::HTTP2FrameHeaderBlock { | ||
80 | - name: "Host".as_bytes().to_vec(), | ||
81 | - value: "abc.com".as_bytes().to_vec(), | ||
82 | + name: "Host".as_bytes().to_vec().into(), | ||
83 | + value: "abc.com".as_bytes().to_vec().into(), | ||
84 | error: parser::HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSuccess, | ||
85 | sizeupdate: 0, | ||
86 | }; | ||
87 | blocks.push(b); | ||
88 | let b2 = parser::HTTP2FrameHeaderBlock { | ||
89 | - name: "Host".as_bytes().to_vec(), | ||
90 | - value: "efg.net".as_bytes().to_vec(), | ||
91 | + name: "Host".as_bytes().to_vec().into(), | ||
92 | + value: "efg.net".as_bytes().to_vec().into(), | ||
93 | error: parser::HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSuccess, | ||
94 | sizeupdate: 0, | ||
95 | }; | ||
96 | diff --git a/rust/src/http2/http2.rs b/rust/src/http2/http2.rs | ||
97 | index 326030f..d14ca06 100644 | ||
98 | --- a/rust/src/http2/http2.rs | ||
99 | +++ b/rust/src/http2/http2.rs | ||
100 | @@ -204,7 +204,7 @@ impl HTTP2Transaction { | ||
101 | |||
102 | fn handle_headers(&mut self, blocks: &[parser::HTTP2FrameHeaderBlock], dir: Direction) { | ||
103 | for block in blocks { | ||
104 | - if block.name == b"content-encoding" { | ||
105 | + if block.name.as_ref() == b"content-encoding" { | ||
106 | self.decoder.http2_encoding_fromvec(&block.value, dir); | ||
107 | } | ||
108 | } | ||
109 | diff --git a/rust/src/http2/parser.rs b/rust/src/http2/parser.rs | ||
110 | index adabeb2..1a46437 100644 | ||
111 | --- a/rust/src/http2/parser.rs | ||
112 | +++ b/rust/src/http2/parser.rs | ||
113 | @@ -30,6 +30,7 @@ use nom7::sequence::tuple; | ||
114 | use nom7::{Err, IResult}; | ||
115 | use std::fmt; | ||
116 | use std::str::FromStr; | ||
117 | +use std::rc::Rc; | ||
118 | |||
119 | #[repr(u8)] | ||
120 | #[derive(Clone, Copy, PartialEq, Eq, FromPrimitive, Debug)] | ||
121 | @@ -295,8 +296,8 @@ fn http2_frame_header_static(n: u64, dyn_headers: &HTTP2DynTable) -> Option<HTTP | ||
122 | }; | ||
123 | if !name.is_empty() { | ||
124 | return Some(HTTP2FrameHeaderBlock { | ||
125 | - name: name.as_bytes().to_vec(), | ||
126 | - value: value.as_bytes().to_vec(), | ||
127 | + name: Rc::new(name.as_bytes().to_vec()), | ||
128 | + value: Rc::new(value.as_bytes().to_vec()), | ||
129 | error: HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSuccess, | ||
130 | sizeupdate: 0, | ||
131 | }); | ||
132 | @@ -304,23 +305,23 @@ fn http2_frame_header_static(n: u64, dyn_headers: &HTTP2DynTable) -> Option<HTTP | ||
133 | //use dynamic table | ||
134 | if n == 0 { | ||
135 | return Some(HTTP2FrameHeaderBlock { | ||
136 | - name: Vec::new(), | ||
137 | - value: Vec::new(), | ||
138 | + name: Rc::new(Vec::new()), | ||
139 | + value: Rc::new(Vec::new()), | ||
140 | error: HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeIndex0, | ||
141 | sizeupdate: 0, | ||
142 | }); | ||
143 | } else if dyn_headers.table.len() + HTTP2_STATIC_HEADERS_NUMBER < n as usize { | ||
144 | return Some(HTTP2FrameHeaderBlock { | ||
145 | - name: Vec::new(), | ||
146 | - value: Vec::new(), | ||
147 | + name: Rc::new(Vec::new()), | ||
148 | + value: Rc::new(Vec::new()), | ||
149 | error: HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeNotIndexed, | ||
150 | sizeupdate: 0, | ||
151 | }); | ||
152 | } else { | ||
153 | let indyn = dyn_headers.table.len() - (n as usize - HTTP2_STATIC_HEADERS_NUMBER); | ||
154 | let headcopy = HTTP2FrameHeaderBlock { | ||
155 | - name: dyn_headers.table[indyn].name.to_vec(), | ||
156 | - value: dyn_headers.table[indyn].value.to_vec(), | ||
157 | + name: dyn_headers.table[indyn].name.clone(), | ||
158 | + value: dyn_headers.table[indyn].value.clone(), | ||
159 | error: HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSuccess, | ||
160 | sizeupdate: 0, | ||
161 | }; | ||
162 | @@ -348,8 +349,10 @@ impl fmt::Display for HTTP2HeaderDecodeStatus { | ||
163 | |||
164 | #[derive(Clone, Debug)] | ||
165 | pub struct HTTP2FrameHeaderBlock { | ||
166 | - pub name: Vec<u8>, | ||
167 | - pub value: Vec<u8>, | ||
168 | + // Use Rc reference counted so that indexed headers do not get copied. | ||
169 | + // Otherwise, this leads to quadratic complexity in memory occupation. | ||
170 | + pub name: Rc<Vec<u8>>, | ||
171 | + pub value: Rc<Vec<u8>>, | ||
172 | pub error: HTTP2HeaderDecodeStatus, | ||
173 | pub sizeupdate: u64, | ||
174 | } | ||
175 | @@ -391,7 +394,7 @@ fn http2_parse_headers_block_literal_common<'a>( | ||
176 | ) -> IResult<&'a [u8], HTTP2FrameHeaderBlock> { | ||
177 | let (i3, name, error) = if index == 0 { | ||
178 | match http2_parse_headers_block_string(input) { | ||
179 | - Ok((r, n)) => Ok((r, n, HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSuccess)), | ||
180 | + Ok((r, n)) => Ok((r, Rc::new(n), HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSuccess)), | ||
181 | Err(e) => Err(e), | ||
182 | } | ||
183 | } else { | ||
184 | @@ -403,7 +406,7 @@ fn http2_parse_headers_block_literal_common<'a>( | ||
185 | )), | ||
186 | None => Ok(( | ||
187 | input, | ||
188 | - Vec::new(), | ||
189 | + Rc::new(Vec::new()), | ||
190 | HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeNotIndexed, | ||
191 | )), | ||
192 | } | ||
193 | @@ -413,7 +416,7 @@ fn http2_parse_headers_block_literal_common<'a>( | ||
194 | i4, | ||
195 | HTTP2FrameHeaderBlock { | ||
196 | name, | ||
197 | - value, | ||
198 | + value: Rc::new(value), | ||
199 | error, | ||
200 | sizeupdate: 0, | ||
201 | }, | ||
202 | @@ -435,8 +438,8 @@ fn http2_parse_headers_block_literal_incindex<'a>( | ||
203 | match r { | ||
204 | Ok((r, head)) => { | ||
205 | let headcopy = HTTP2FrameHeaderBlock { | ||
206 | - name: head.name.to_vec(), | ||
207 | - value: head.value.to_vec(), | ||
208 | + name: head.name.clone(), | ||
209 | + value: head.value.clone(), | ||
210 | error: head.error, | ||
211 | sizeupdate: 0, | ||
212 | }; | ||
213 | @@ -556,8 +559,8 @@ fn http2_parse_headers_block_dynamic_size<'a>( | ||
214 | return Ok(( | ||
215 | i3, | ||
216 | HTTP2FrameHeaderBlock { | ||
217 | - name: Vec::new(), | ||
218 | - value: Vec::new(), | ||
219 | + name: Rc::new(Vec::new()), | ||
220 | + value: Rc::new(Vec::new()), | ||
221 | error: HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeSizeUpdate, | ||
222 | sizeupdate: maxsize2, | ||
223 | }, | ||
224 | @@ -614,8 +617,8 @@ fn http2_parse_headers_blocks<'a>( | ||
225 | // if we error from http2_parse_var_uint, we keep the first parsed headers | ||
226 | if err.code == ErrorKind::LengthValue { | ||
227 | blocks.push(HTTP2FrameHeaderBlock { | ||
228 | - name: Vec::new(), | ||
229 | - value: Vec::new(), | ||
230 | + name: Rc::new(Vec::new()), | ||
231 | + value: Rc::new(Vec::new()), | ||
232 | error: HTTP2HeaderDecodeStatus::HTTP2HeaderDecodeIntegerOverflow, | ||
233 | sizeupdate: 0, | ||
234 | }); | ||
235 | @@ -765,8 +768,8 @@ mod tests { | ||
236 | match r0 { | ||
237 | Ok((remainder, hd)) => { | ||
238 | // Check the first message. | ||
239 | - assert_eq!(hd.name, ":method".as_bytes().to_vec()); | ||
240 | - assert_eq!(hd.value, "GET".as_bytes().to_vec()); | ||
241 | + assert_eq!(hd.name, ":method".as_bytes().to_vec().into()); | ||
242 | + assert_eq!(hd.value, "GET".as_bytes().to_vec().into()); | ||
243 | // And we should have no bytes left. | ||
244 | assert_eq!(remainder.len(), 0); | ||
245 | } | ||
246 | @@ -782,8 +785,8 @@ mod tests { | ||
247 | match r1 { | ||
248 | Ok((remainder, hd)) => { | ||
249 | // Check the first message. | ||
250 | - assert_eq!(hd.name, "accept".as_bytes().to_vec()); | ||
251 | - assert_eq!(hd.value, "*/*".as_bytes().to_vec()); | ||
252 | + assert_eq!(hd.name, "accept".as_bytes().to_vec().into()); | ||
253 | + assert_eq!(hd.value, "*/*".as_bytes().to_vec().into()); | ||
254 | // And we should have no bytes left. | ||
255 | assert_eq!(remainder.len(), 0); | ||
256 | assert_eq!(dynh.table.len(), 1); | ||
257 | @@ -802,8 +805,8 @@ mod tests { | ||
258 | match result { | ||
259 | Ok((remainder, hd)) => { | ||
260 | // Check the first message. | ||
261 | - assert_eq!(hd.name, ":authority".as_bytes().to_vec()); | ||
262 | - assert_eq!(hd.value, "localhost:3000".as_bytes().to_vec()); | ||
263 | + assert_eq!(hd.name, ":authority".as_bytes().to_vec().into()); | ||
264 | + assert_eq!(hd.value, "localhost:3000".as_bytes().to_vec().into()); | ||
265 | // And we should have no bytes left. | ||
266 | assert_eq!(remainder.len(), 0); | ||
267 | assert_eq!(dynh.table.len(), 2); | ||
268 | @@ -820,8 +823,8 @@ mod tests { | ||
269 | match r3 { | ||
270 | Ok((remainder, hd)) => { | ||
271 | // same as before | ||
272 | - assert_eq!(hd.name, ":authority".as_bytes().to_vec()); | ||
273 | - assert_eq!(hd.value, "localhost:3000".as_bytes().to_vec()); | ||
274 | + assert_eq!(hd.name, ":authority".as_bytes().to_vec().into()); | ||
275 | + assert_eq!(hd.value, "localhost:3000".as_bytes().to_vec().into()); | ||
276 | // And we should have no bytes left. | ||
277 | assert_eq!(remainder.len(), 0); | ||
278 | assert_eq!(dynh.table.len(), 2); | ||
279 | @@ -856,8 +859,8 @@ mod tests { | ||
280 | match r2 { | ||
281 | Ok((remainder, hd)) => { | ||
282 | // Check the first message. | ||
283 | - assert_eq!(hd.name, ":path".as_bytes().to_vec()); | ||
284 | - assert_eq!(hd.value, "/doc/manual/html/index.html".as_bytes().to_vec()); | ||
285 | + assert_eq!(hd.name, ":path".as_bytes().to_vec().into()); | ||
286 | + assert_eq!(hd.value, "/doc/manual/html/index.html".as_bytes().to_vec().into()); | ||
287 | // And we should have no bytes left. | ||
288 | assert_eq!(remainder.len(), 0); | ||
289 | assert_eq!(dynh.table.len(), 2); | ||
290 | -- | ||
291 | 2.44.0 | ||
292 | |||
diff --git a/recipes-ids/suricata/files/CVE-2024-38536.patch b/recipes-ids/suricata/files/CVE-2024-38536.patch new file mode 100644 index 0000000..2d4b3d7 --- /dev/null +++ b/recipes-ids/suricata/files/CVE-2024-38536.patch | |||
@@ -0,0 +1,40 @@ | |||
1 | From 4026bca7f04c419dd3f3ba17a1af17bbcbcf18bc Mon Sep 17 00:00:00 2001 | ||
2 | From: Philippe Antoine <pantoine@oisf.net> | ||
3 | Date: Fri, 17 May 2024 09:39:52 +0200 | ||
4 | Subject: [PATCH 4/4] http: fix nul deref on memcap reached | ||
5 | |||
6 | HttpRangeOpenFileAux may return NULL in different cases, including | ||
7 | when memcap is reached. | ||
8 | But is only caller did not check it before calling HttpRangeAppendData | ||
9 | which would dereference the NULL value. | ||
10 | |||
11 | Ticket: 7029 | ||
12 | (cherry picked from commit fd262df457f67f2174752dd6505ba2ed5911fd96) | ||
13 | |||
14 | Upstream-Status: Backport from [https://github.com/OISF/suricata/commit/2bd3bd0e318f19008e9fe068ab17277c530ffb92] | ||
15 | CVE: CVE-2024-38536 | ||
16 | Signed-off-by: Siddharth Doshi <sdoshi@mvista.com> | ||
17 | --- | ||
18 | src/app-layer-htp-range.c | 6 ++++-- | ||
19 | 1 file changed, 4 insertions(+), 2 deletions(-) | ||
20 | |||
21 | diff --git a/src/app-layer-htp-range.c b/src/app-layer-htp-range.c | ||
22 | index 3cdde35..f0d75a9 100644 | ||
23 | --- a/src/app-layer-htp-range.c | ||
24 | +++ b/src/app-layer-htp-range.c | ||
25 | @@ -351,8 +351,10 @@ static HttpRangeContainerBlock *HttpRangeOpenFile(HttpRangeContainerFile *c, uin | ||
26 | { | ||
27 | HttpRangeContainerBlock *r = | ||
28 | HttpRangeOpenFileAux(c, start, end, total, sbcfg, name, name_len, flags); | ||
29 | - if (HttpRangeAppendData(sbcfg, r, data, len) < 0) { | ||
30 | - SCLogDebug("Failed to append data while opening"); | ||
31 | + if (r) { | ||
32 | + if (HttpRangeAppendData(sbcfg, r, data, len) < 0) { | ||
33 | + SCLogDebug("Failed to append data while opening"); | ||
34 | + } | ||
35 | } | ||
36 | return r; | ||
37 | } | ||
38 | -- | ||
39 | 2.44.0 | ||
40 | |||
diff --git a/recipes-ids/suricata/suricata_7.0.0.bb b/recipes-ids/suricata/suricata_7.0.0.bb index 21d4306..1f3b694 100644 --- a/recipes-ids/suricata/suricata_7.0.0.bb +++ b/recipes-ids/suricata/suricata_7.0.0.bb | |||
@@ -16,6 +16,11 @@ SRC_URI += " \ | |||
16 | file://suricata.service \ | 16 | file://suricata.service \ |
17 | file://run-ptest \ | 17 | file://run-ptest \ |
18 | file://fixup.patch \ | 18 | file://fixup.patch \ |
19 | file://CVE-2024-37151.patch \ | ||
20 | file://CVE-2024-38534.patch \ | ||
21 | file://CVE-2024-38535_pre.patch \ | ||
22 | file://CVE-2024-38535.patch \ | ||
23 | file://CVE-2024-38536.patch \ | ||
19 | " | 24 | " |
20 | 25 | ||
21 | inherit autotools pkgconfig python3native systemd ptest cargo cargo-update-recipe-crates | 26 | inherit autotools pkgconfig python3native systemd ptest cargo cargo-update-recipe-crates |