From 274255fdb0e56c379aa5455c7da772936dd0c1fc Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl@samba.org>
Date: Tue, 24 Feb 2026 16:11:15 +0100
Subject: [PATCH 04/38] CVE-2026-3238 winsserver4: Dissolve direct variable
 initialization

Checks are required before the packet is dereferenced

Bug: https://bugzilla.samba.org/show_bug.cgi?id=16012
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
---
 source4/nbt_server/wins/winsserver.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/source4/nbt_server/wins/winsserver.c b/source4/nbt_server/wins/winsserver.c
index a9f3ecd7d29..438677ab269 100644
--- a/source4/nbt_server/wins/winsserver.c
+++ b/source4/nbt_server/wins/winsserver.c
@@ -459,16 +459,27 @@ static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock,
 	struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
 						       struct nbtd_interface);
 	struct wins_server *winssrv = iface->nbtsrv->winssrv;
-	struct nbt_name *name = &packet->questions[0].name;
+	struct nbt_name *name = NULL;
 	struct winsdb_record *rec;
 	uint8_t rcode = NBT_RCODE_OK;
-	uint16_t nb_flags = packet->additional[0].rdata.netbios.addresses[0].nb_flags;
-	const char *address = packet->additional[0].rdata.netbios.addresses[0].ipaddr;
+	struct nbt_res_rec *additional = NULL;
+	uint16_t nb_flags;
+	const char *address = NULL;
+	struct nbt_rdata_address *addresses = NULL;
 	bool mhomed = ((packet->operation & NBT_OPCODE) == NBT_OPCODE_MULTI_HOME_REG);
-	enum wrepl_name_type new_type = wrepl_type(nb_flags, name, mhomed);
+	enum wrepl_name_type new_type;
 	struct winsdb_addr *winsdb_addr = NULL;
 	bool duplicate_packet;
 
+	name = &packet->questions[0].name;
+	additional = packet->additional;
+
+	addresses = additional[0].rdata.netbios.addresses;
+
+	nb_flags = addresses[0].nb_flags;
+	address = addresses[0].ipaddr;
+	new_type = wrepl_type(nb_flags, name, mhomed);
+
 	/*
 	 * as a special case, the local master browser name is always accepted
 	 * for registration, but never stored, but w2k3 stores it if it's registered
@@ -728,13 +739,15 @@ static void nbtd_winsserver_query(struct loadparm_context *lp_ctx,
 	struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
 						       struct nbtd_interface);
 	struct wins_server *winssrv = iface->nbtsrv->winssrv;
-	struct nbt_name *name = &packet->questions[0].name;
+	struct nbt_name *name = NULL;
 	struct winsdb_record *rec;
 	struct winsdb_record *rec_1b = NULL;
 	const char **addresses;
 	const char **addresses_1b = NULL;
 	uint16_t nb_flags = 0;
 
+	name = &packet->questions[0].name;
+
 	if (name->type == NBT_NAME_MASTER) {
 		goto notfound;
 	}
@@ -870,11 +883,13 @@ static void nbtd_winsserver_release(struct nbt_name_socket *nbtsock,
 	struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
 						       struct nbtd_interface);
 	struct wins_server *winssrv = iface->nbtsrv->winssrv;
-	struct nbt_name *name = &packet->questions[0].name;
+	struct nbt_name *name = NULL;
 	struct winsdb_record *rec;
 	uint32_t modify_flags = 0;
 	uint8_t ret;
 
+	name = &packet->questions[0].name;
+
 	if (name->type == NBT_NAME_MASTER) {
 		goto done;
 	}
-- 
2.43.0


