From 6a6cfa25148a39d024f4e868029db420a36a2b61 Mon Sep 17 00:00:00 2001
From: Martin Schwenke <mschwenke@ddn.com>
Date: Tue, 9 Jun 2026 10:41:25 +1000
Subject: [PATCH 10/23] CVE-2026-58224: ctdb-daemon: Avoid out of bounds data access

Instead of checking only that there is enough data for the length
field, check there is enough data for the entire header part of the
struct.  After cross-checking overall lengths, ensure there is enough
data for the key/data in the data element.

While here, modernise the DEBUG.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=16085

Reported-by: Andrew Tridgell (issue 13)
Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 ctdb/server/ctdb_traverse.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/ctdb/server/ctdb_traverse.c b/ctdb/server/ctdb_traverse.c
index 4865dcc94f0..094f824bf9d 100644
--- a/ctdb/server/ctdb_traverse.c
+++ b/ctdb/server/ctdb_traverse.c
@@ -561,13 +561,17 @@ int32_t ctdb_control_traverse_all(struct ctdb_context *ctdb, TDB_DATA data, TDB_
 int32_t ctdb_control_traverse_data(struct ctdb_context *ctdb, TDB_DATA data, TDB_DATA *outdata)
 {
 	struct ctdb_rec_data_old *d = (struct ctdb_rec_data_old *)data.dptr;
+	size_t rec_data_header_len = offsetof(struct ctdb_rec_data_old, data);
 	struct ctdb_traverse_all_handle *state;
 	TDB_DATA key;
 	ctdb_traverse_fn_t callback;
 	void *private_data;
 
-	if (data.dsize < sizeof(uint32_t) || data.dsize != d->length) {
-		DEBUG(DEBUG_ERR,("Bad record size in ctdb_control_traverse_data\n"));
+	if (data.dsize < rec_data_header_len ||
+	    data.dsize != d->length ||
+	    d->keylen > d->length - rec_data_header_len ||
+	    d->datalen > d->length - rec_data_header_len - d->keylen) {
+		DBG_ERR("Invalid packet\n");
 		return -1;
 	}
 
-- 
2.43.0


