Version in base suite: 7.0.10-1+deb13u1 Base version: suricata_7.0.10-1+deb13u1 Target version: suricata_7.0.10-1+deb13u2 Base file: /srv/ftp-master.debian.org/ftp/pool/main/s/suricata/suricata_7.0.10-1+deb13u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/s/suricata/suricata_7.0.10-1+deb13u2.dsc changelog | 16 ++ patches/CVE-2025-64330.patch | 50 ++++++++ patches/CVE-2025-64331.patch | 259 +++++++++++++++++++++++++++++++++++++++++++ patches/CVE-2025-64332.patch | 44 +++++++ patches/CVE-2025-64333.patch | 45 +++++++ patches/CVE-2025-64344.patch | 50 ++++++++ patches/series | 5 7 files changed, 469 insertions(+) diff -Nru suricata-7.0.10/debian/changelog suricata-7.0.10/debian/changelog --- suricata-7.0.10/debian/changelog 2025-09-27 19:43:45.000000000 +0000 +++ suricata-7.0.10/debian/changelog 2025-12-10 19:12:20.000000000 +0000 @@ -1,3 +1,19 @@ +suricata (1:7.0.10-1+deb13u2) trixie; urgency=medium + + * Fix CVE-2025-64344 in 7.0.10. + Cherry-Picked from upstream a7ff4c9ba53009680c7cd128b16c28d0aeda9886. + * Fix CVE-2025-64333 in 7.0.10. + Cherry-Picked from upstream 4b1d284bb57219b6677a8bda5cdc14a24a6aa22d. + * Fix CVE-2025-64332 in 7.0.10. + Cherry-Picked from upstream f67d72702a2601d0a86ac1450686e70d7176f629. + * Fix CVE-2025-64331 in 7.0.10. + Cherry-Picked from upstream 5abf9b81e78476f49ab074f3a74b5840747cd069. + Added missing function declaration and refreshed patch by quilt. + * Fix CVE-2025-64330 in 7.0.10. + Cherry-Picked from upstream 5d6c24cc2ce6a390c0956b7ecb2c5efc47e72abc. + + -- Andreas Dolp Wed, 10 Dec 2025 20:12:20 +0100 + suricata (1:7.0.10-1+deb13u1) trixie; urgency=medium * Fix CVE-2025-53538 in 7.0.10. diff -Nru suricata-7.0.10/debian/patches/CVE-2025-64330.patch suricata-7.0.10/debian/patches/CVE-2025-64330.patch --- suricata-7.0.10/debian/patches/CVE-2025-64330.patch 1970-01-01 00:00:00.000000000 +0000 +++ suricata-7.0.10/debian/patches/CVE-2025-64330.patch 2025-12-10 19:12:20.000000000 +0000 @@ -0,0 +1,50 @@ +From 5d6c24cc2ce6a390c0956b7ecb2c5efc47e72abc Mon Sep 17 00:00:00 2001 +From: Juliana Fajardini +Date: Fri, 31 Oct 2025 21:38:12 -0700 +Subject: [PATCH] output/alert: fix alert index access for verdict + +The engine uses p.alerts.cnt as an index to access the packet alert that +has the `pass` action for the verdict. +For IDS/IPS mode, a `pass` will always be the last signature in the +alert queue. However, that position could be either `p.alerts.cnt` or +`p.alerts.cnt-1`, depending on whether the `pass` rule has the `alert` +keyword or not. +This patch fix corner-case scenarios of: +- accessing an index out of boundaries +- off-by-one access +Without changing how the engine increments the alerts.cnt, as this is +used in many places, and would be a more invasive change. +It checks the two different scenarios, plus the case when there is only +a single match as a silent `pass` rule. + +Bug #8021 +Bug #7630 + +Origin: upstream, https://github.com/OISF/suricata/commit/5d6c24cc2ce6a390c0956b7ecb2c5efc47e72abc.patch +Bug: https://redmine.openinfosecfoundation.org/issues/8021 +Subject: Upstream fix for CVE-2025-64330 +--- + src/output-json-alert.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/output-json-alert.c b/src/output-json-alert.c +index 495b8285f..8c000cb2a 100644 +--- a/src/output-json-alert.c ++++ b/src/output-json-alert.c +@@ -702,7 +702,12 @@ void EveAddVerdict(JsonBuilder *jb, const Packet *p) + + } else if (PacketCheckAction(p, ACTION_DROP) && EngineModeIsIPS()) { + JB_SET_STRING(jb, "action", "drop"); +- } else if (p->alerts.alerts[p->alerts.cnt].action & ACTION_PASS) { ++ } else if (p->alerts.cnt == 0 || ++ (p->alerts.cnt <= packet_alert_max && ++ (p->alerts.alerts[p->alerts.cnt - 1].action & ++ (ACTION_PASS | ACTION_ALERT)) == (ACTION_PASS | ACTION_ALERT)) || ++ (p->alerts.cnt < packet_alert_max && ++ p->alerts.alerts[p->alerts.cnt].action & ACTION_PASS)) { + JB_SET_STRING(jb, "action", "pass"); + } else { + // TODO make sure we don't have a situation where this wouldn't work +-- +2.51.2 + diff -Nru suricata-7.0.10/debian/patches/CVE-2025-64331.patch suricata-7.0.10/debian/patches/CVE-2025-64331.patch --- suricata-7.0.10/debian/patches/CVE-2025-64331.patch 1970-01-01 00:00:00.000000000 +0000 +++ suricata-7.0.10/debian/patches/CVE-2025-64331.patch 2025-12-10 19:12:20.000000000 +0000 @@ -0,0 +1,259 @@ +From 5abf9b81e78476f49ab074f3a74b5840747cd069 Mon Sep 17 00:00:00 2001 +From: Philippe Antoine +Date: Thu, 30 Oct 2025 11:18:15 +0100 +Subject: [PATCH] output/jsonbuilder: helper function SCJbSetPrintAsciiString + +To replace C PrintStringsToBuffer and avoid a stack alloc ++ copy + +Ticket: 8004 +(cherry picked from commit 7447651fa0956ff4ce55283a51b4a9494ec8cc6a) + +Origin: upstream, https://github.com/OISF/suricata/commit/5abf9b81e78476f49ab074f3a74b5840747cd069.patch +Bug: https://redmine.openinfosecfoundation.org/issues/8004 +Subject: Upstream fix for CVE-2025-64331 +--- + rust/src/jsonbuilder.rs | 60 +++++++++++++++++++++++++++++++++++++++++ + src/output-json-alert.c | 15 +++-------- + src/output-json-frame.c | 12 ++------- + src/output-json-http.c | 9 +------ + src/output-json.c | 36 +++++-------------------- + 5 files changed, 72 insertions(+), 60 deletions(-) + +--- a/rust/src/jsonbuilder.rs ++++ b/rust/src/jsonbuilder.rs +@@ -527,6 +527,52 @@ + } + } + ++ /// Set a key with a string value taking only ascii-printable bytes. ++ /// Non-printable characters are replaced by a dot `.`, except ++ /// CR and LF which are escaped the regular json way \r and \n ++ pub fn set_print_ascii(&mut self, key: &str, val: &[u8]) -> Result<&mut Self, JsonError> { ++ match self.current_state() { ++ State::ObjectNth => { ++ self.push(',')?; ++ } ++ State::ObjectFirst => { ++ self.set_state(State::ObjectNth); ++ } ++ _ => { ++ debug_validate_fail!("invalid state"); ++ return Err(JsonError::InvalidState); ++ } ++ } ++ self.push('"')?; ++ self.push_str(key)?; ++ self.push_str("\":\"")?; ++ for &x in val.iter() { ++ match x { ++ b'\r' => { ++ self.push_str("\\r")?; ++ } ++ b'\n'=> { ++ self.push_str("\\n")?; ++ } ++ b'"'=> { ++ self.push_str("\\\"")?; ++ } ++ b'\\'=> { ++ self.push_str("\\\\")?; ++ } ++ _ => { ++ if !x.is_ascii() || x.is_ascii_control() { ++ self.push('.')?; ++ } else { ++ self.push(x as char)?; ++ } ++ } ++ } ++ } ++ self.push('"')?; ++ Ok(self) ++ } ++ + /// Set a key and a string value (from bytes) on an object, with a limited size + pub fn set_string_from_bytes_limited(&mut self, key: &str, val: &[u8], limit: usize) -> Result<&mut Self, JsonError> { + let mut valtrunc = Vec::new(); +@@ -883,6 +929,20 @@ + } + return false; + } ++ ++#[no_mangle] ++pub unsafe extern "C" fn SCJbSetPrintAsciiString( ++ js: &mut JsonBuilder, key: *const c_char, bytes: *const u8, len: u32, ++) -> bool { ++ if bytes.is_null() || len == 0 { ++ return false; ++ } ++ if let Ok(key) = CStr::from_ptr(key).to_str() { ++ let val = std::slice::from_raw_parts(bytes, len as usize); ++ return js.set_print_ascii(key, val).is_ok(); ++ } ++ return false; ++} + + #[no_mangle] + pub unsafe extern "C" fn jb_set_base64( +--- a/src/output-json-alert.c ++++ b/src/output-json-alert.c +@@ -452,13 +452,7 @@ + } + + if (json_output_ctx->flags & LOG_JSON_PAYLOAD) { +- uint8_t printable_buf[p->payload_len + 1]; +- uint32_t offset = 0; +- PrintStringsToBuffer(printable_buf, &offset, +- p->payload_len + 1, +- p->payload, p->payload_len); +- printable_buf[p->payload_len] = '\0'; +- jb_set_string(js, "payload_printable", (char *)printable_buf); ++ SCJbSetPrintAsciiString(js, "payload_printable", p->payload, p->payload_len); + } + } + +@@ -764,11 +758,8 @@ + } + + if (json_output_ctx->flags & LOG_JSON_PAYLOAD) { +- uint8_t printable_buf[cbd.payload->offset + 1]; +- uint32_t offset = 0; +- PrintStringsToBuffer(printable_buf, &offset, sizeof(printable_buf), cbd.payload->buffer, +- cbd.payload->offset); +- jb_set_string(jb, "payload_printable", (char *)printable_buf); ++ SCJbSetPrintAsciiString( ++ jb, "payload_printable", cbd.payload->buffer, cbd.payload->offset); + } + return true; + } +--- a/src/output-json-frame.c ++++ b/src/output-json-frame.c +@@ -202,11 +202,7 @@ + + if (cbd.payload->offset) { + jb_set_base64(jb, "payload", cbd.payload->buffer, cbd.payload->offset); +- uint8_t printable_buf[cbd.payload->offset + 1]; +- uint32_t offset = 0; +- PrintStringsToBuffer(printable_buf, &offset, sizeof(printable_buf), cbd.payload->buffer, +- cbd.payload->offset); +- jb_set_string(jb, "payload_printable", (char *)printable_buf); ++ SCJbSetPrintAsciiString(jb, "payload_printable", cbd.payload->buffer, cbd.payload->offset); + jb_set_bool(jb, "complete", complete); + } + } +@@ -235,11 +231,7 @@ + const uint32_t log_data_len = MIN(data_len, 256); + jb_set_base64(js, "payload", data, log_data_len); + +- uint8_t printable_buf[log_data_len + 1]; +- uint32_t o = 0; +- PrintStringsToBuffer(printable_buf, &o, log_data_len + 1, data, log_data_len); +- printable_buf[log_data_len] = '\0'; +- jb_set_string(js, "payload_printable", (char *)printable_buf); ++ SCJbSetPrintAsciiString(js, "payload_printable", data, log_data_len); + #if 0 + char pretty_buf[data_len * 4 + 1]; + pretty_buf[0] = '\0'; +--- a/src/output-json-http.c ++++ b/src/output-json-http.c +@@ -366,7 +366,6 @@ + static void BodyPrintableBuffer(JsonBuilder *js, HtpBody *body, const char *key) + { + if (body->sb != NULL && body->sb->region.buf != NULL) { +- uint32_t offset = 0; + const uint8_t *body_data; + uint32_t body_data_len; + uint64_t body_offset; +@@ -376,13 +375,7 @@ + return; + } + +- uint8_t printable_buf[body_data_len + 1]; +- PrintStringsToBuffer(printable_buf, &offset, +- sizeof(printable_buf), +- body_data, body_data_len); +- if (offset > 0) { +- jb_set_string(js, key, (char *)printable_buf); +- } ++ SCJbSetPrintAsciiString(js, key, body_data, body_data_len); + } + } + +--- a/src/output-json.c ++++ b/src/output-json.c +@@ -210,22 +210,10 @@ + PrintStringsToBuffer(keybuf, &offset, + sizeof(keybuf), + pv->key, pv->key_len); +- uint32_t len = pv->value_len; +- uint8_t printable_buf[len + 1]; +- offset = 0; +- PrintStringsToBuffer(printable_buf, &offset, +- sizeof(printable_buf), +- pv->value, pv->value_len); +- jb_set_string(js_vars, (char *)keybuf, (char *)printable_buf); ++ SCJbSetPrintAsciiString(js_vars, (char *)keybuf, pv->value, pv->value_len); + } else { + const char *varname = VarNameStoreLookupById(pv->id, VAR_TYPE_PKT_VAR); +- uint32_t len = pv->value_len; +- uint8_t printable_buf[len + 1]; +- uint32_t offset = 0; +- PrintStringsToBuffer(printable_buf, &offset, +- sizeof(printable_buf), +- pv->value, pv->value_len); +- jb_set_string(js_vars, varname, (char *)printable_buf); ++ SCJbSetPrintAsciiString(js_vars, varname, pv->value, pv->value_len); + } + jb_close(js_vars); + } +@@ -276,15 +264,9 @@ + break; + } + +- uint32_t len = fv->data.fv_str.value_len; +- uint8_t printable_buf[len + 1]; +- uint32_t offset = 0; +- PrintStringsToBuffer(printable_buf, &offset, +- sizeof(printable_buf), +- fv->data.fv_str.value, fv->data.fv_str.value_len); +- + jb_start_object(js_flowvars); +- jb_set_string(js_flowvars, varname, (char *)printable_buf); ++ SCJbSetPrintAsciiString( ++ js_flowvars, varname, fv->data.fv_str.value, fv->data.fv_str.value_len); + jb_close(js_flowvars); + } + } else if (fv->datatype == FLOWVAR_TYPE_STR && fv->key != NULL) { +@@ -300,15 +282,9 @@ + sizeof(keybuf), + fv->key, fv->keylen); + +- uint32_t len = fv->data.fv_str.value_len; +- uint8_t printable_buf[len + 1]; +- offset = 0; +- PrintStringsToBuffer(printable_buf, &offset, +- sizeof(printable_buf), +- fv->data.fv_str.value, fv->data.fv_str.value_len); +- + jb_start_object(js_flowvars); +- jb_set_string(js_flowvars, (const char *)keybuf, (char *)printable_buf); ++ SCJbSetPrintAsciiString(js_flowvars, (const char *)keybuf, fv->data.fv_str.value, ++ fv->data.fv_str.value_len); + jb_close(js_flowvars); + } else if (fv->datatype == FLOWVAR_TYPE_INT) { + const char *varname = VarNameStoreLookupById(fv->idx, +--- a/rust/dist/rust-bindings.h ++++ b/rust/dist/rust-bindings.h +@@ -4898,6 +4898,11 @@ + const uint8_t *bytes, + uint32_t len); + ++bool SCJbSetPrintAsciiString(struct JsonBuilder *js, ++ const char *key, ++ const uint8_t *bytes, ++ uint32_t len); ++ + bool jb_set_base64(struct JsonBuilder *js, + const char *key, + const uint8_t *bytes, diff -Nru suricata-7.0.10/debian/patches/CVE-2025-64332.patch suricata-7.0.10/debian/patches/CVE-2025-64332.patch --- suricata-7.0.10/debian/patches/CVE-2025-64332.patch 1970-01-01 00:00:00.000000000 +0000 +++ suricata-7.0.10/debian/patches/CVE-2025-64332.patch 2025-12-10 19:12:20.000000000 +0000 @@ -0,0 +1,44 @@ +From f67d72702a2601d0a86ac1450686e70d7176f629 Mon Sep 17 00:00:00 2001 +From: Philippe Antoine +Date: Thu, 30 Oct 2025 11:27:22 +0100 +Subject: [PATCH] util/swf: move allocation from stack to heap + +As it can overflow the stack + +Ticket: 8055 +(cherry picked from commit a84addb771846f6d4d55ec535a4591f58369e49c) + +Origin: upstream, https://github.com/OISF/suricata/commit/f67d72702a2601d0a86ac1450686e70d7176f629.patch +Bug: https://redmine.openinfosecfoundation.org/issues/8055 +Subject: Upstream fix for CVE-2025-64332 +--- + src/util-file-decompression.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/util-file-decompression.c b/src/util-file-decompression.c +index dfafdc87f..bf65b0b7c 100644 +--- a/src/util-file-decompression.c ++++ b/src/util-file-decompression.c +@@ -169,7 +169,10 @@ int FileSwfDecompression(const uint8_t *buffer, uint32_t buffer_len, + * | LZMA properties | Uncompressed length | Compressed data | + */ + compressed_data_len += 13; +- uint8_t compressed_data[compressed_data_len]; ++ uint8_t *compressed_data = SCCalloc(1, compressed_data_len); ++ if (compressed_data == NULL) { ++ goto error; ++ } + /* put lzma properties */ + memcpy(compressed_data, buffer + 12, 5); + /* put lzma end marker */ +@@ -183,6 +186,7 @@ int FileSwfDecompression(const uint8_t *buffer, uint32_t buffer_len, + r = FileSwfLzmaDecompression(det_ctx, + compressed_data, compressed_data_len, + out_buffer->buf + 8, out_buffer->len - 8); ++ SCFree(compressed_data); + if (r == 0) + goto error; + } else { +-- +2.51.2 + diff -Nru suricata-7.0.10/debian/patches/CVE-2025-64333.patch suricata-7.0.10/debian/patches/CVE-2025-64333.patch --- suricata-7.0.10/debian/patches/CVE-2025-64333.patch 1970-01-01 00:00:00.000000000 +0000 +++ suricata-7.0.10/debian/patches/CVE-2025-64333.patch 2025-12-10 19:12:20.000000000 +0000 @@ -0,0 +1,45 @@ +From 4b1d284bb57219b6677a8bda5cdc14a24a6aa22d Mon Sep 17 00:00:00 2001 +From: Philippe Antoine +Date: Thu, 30 Oct 2025 11:43:27 +0100 +Subject: [PATCH] output/http: log content-type like other headers + +Ticket: 8056 + +Avoid stack allocation. +Do not handle null and ; especially + +(cherry picked from commit b8411fcc8dfc16910c3080d4d8c03a9a64c3a1f7) + +Origin: upstream, https://github.com/OISF/suricata/commit/4b1d284bb57219b6677a8bda5cdc14a24a6aa22d.patch +Bug: https://redmine.openinfosecfoundation.org/issues/8056 +Subject: Upstream fix for CVE-2025-64333 +--- + src/output-json-http.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/src/output-json-http.c b/src/output-json-http.c +index bd3f6a116..87191caa9 100644 +--- a/src/output-json-http.c ++++ b/src/output-json-http.c +@@ -237,13 +237,12 @@ static void EveHttpLogJSONBasic(JsonBuilder *js, htp_tx_t *tx) + if (tx->response_headers != NULL) { + htp_header_t *h_content_type = htp_table_get_c(tx->response_headers, "content-type"); + if (h_content_type != NULL) { +- const size_t size = bstr_len(h_content_type->value) * 2 + 1; +- char string[size]; +- BytesToStringBuffer(bstr_ptr(h_content_type->value), bstr_len(h_content_type->value), string, size); +- char *p = strchr(string, ';'); ++ uint32_t len = (uint32_t)bstr_len(h_content_type->value); ++ const uint8_t *p = memchr(bstr_ptr(h_content_type->value), ';', len); + if (p != NULL) +- *p = '\0'; +- jb_set_string(js, "http_content_type", string); ++ len = (uint32_t)(p - bstr_ptr(h_content_type->value)); ++ jb_set_string_from_bytes( ++ js, "http_content_type", bstr_ptr(h_content_type->value), len); + } + htp_header_t *h_content_range = htp_table_get_c(tx->response_headers, "content-range"); + if (h_content_range != NULL) { +-- +2.51.2 + diff -Nru suricata-7.0.10/debian/patches/CVE-2025-64344.patch suricata-7.0.10/debian/patches/CVE-2025-64344.patch --- suricata-7.0.10/debian/patches/CVE-2025-64344.patch 1970-01-01 00:00:00.000000000 +0000 +++ suricata-7.0.10/debian/patches/CVE-2025-64344.patch 2025-12-10 19:12:20.000000000 +0000 @@ -0,0 +1,50 @@ +From a7ff4c9ba53009680c7cd128b16c28d0aeda9886 Mon Sep 17 00:00:00 2001 +From: Victor Julien +Date: Fri, 31 Oct 2025 09:38:55 +0100 +Subject: [PATCH] lua: remove luajit pushlstring workaround + +81ee6f5aadeb ("lua: push correct length back through ScFlowvarGet, work around valgrind warning") +added a workaround for valgrind warnings in pushing a string buffer +into the lua state. This is no longer needed as tested with both +address sanitizer and valgrind. + +(cherry picked from commit 52fd61dffdfa50c9a2d4ec24865a54da0b8f0a2a) + +Origin: upstream, https://github.com/OISF/suricata/commit/a7ff4c9ba53009680c7cd128b16c28d0aeda9886.patch +Bug: https://redmine.openinfosecfoundation.org/issues/8065 +Subject: Upstream fix for CVE-2025-64344 +--- + src/util-lua.c | 17 +---------------- + 1 file changed, 1 insertion(+), 16 deletions(-) + +diff --git a/src/util-lua.c b/src/util-lua.c +index 9e65c3017..3dd1d3150 100644 +--- a/src/util-lua.c ++++ b/src/util-lua.c +@@ -328,22 +328,7 @@ void LuaPrintStack(lua_State *state) { + + int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len) + { +- if (input_len % 4 != 0) { +- /* we're using a buffer sized at a multiple of 4 as lua_pushlstring generates +- * invalid read errors in valgrind otherwise. Adding in a nul to be sure. +- * +- * Buffer size = len + 1 (for nul) + whatever makes it a multiple of 4 */ +- size_t buflen = input_len + 1 + ((input_len + 1) % 4); +- uint8_t buf[buflen]; +- memset(buf, 0x00, buflen); +- memcpy(buf, input, input_len); +- buf[input_len] = '\0'; +- +- /* return value through luastate, as a luastring */ +- lua_pushlstring(luastate, (char *)buf, input_len); +- } else { +- lua_pushlstring(luastate, (char *)input, input_len); +- } ++ lua_pushlstring(luastate, (char *)input, input_len); + return 1; + } + +-- +2.51.2 + diff -Nru suricata-7.0.10/debian/patches/series suricata-7.0.10/debian/patches/series --- suricata-7.0.10/debian/patches/series 2025-09-27 19:43:45.000000000 +0000 +++ suricata-7.0.10/debian/patches/series 2025-12-10 19:12:20.000000000 +0000 @@ -10,3 +10,8 @@ llc.patch CVE-2025-53538.patch CVE-2025-59147.patch +CVE-2025-64344.patch +CVE-2025-64333.patch +CVE-2025-64332.patch +CVE-2025-64331.patch +CVE-2025-64330.patch