Blame SOURCES/dnsmasq-2.87-CVE-2022-0934.patch

25f1e8
From b0cb924292daecc1cc89fbd3911373eb468fc8f1 Mon Sep 17 00:00:00 2001
25f1e8
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
25f1e8
Date: Tue, 22 Feb 2022 00:45:01 +0100
25f1e8
Subject: [PATCH] Change message type by dedicated function
25f1e8
25f1e8
Long-term pointer to beginning of message does not work well. I case
25f1e8
outpacket is reallocated in any new_opt6() section, original outmsgtypep
25f1e8
pointer becomes invalid. Instead of using that pointer use dedicated
25f1e8
function, which will change just the first byte of the message.
25f1e8
25f1e8
This makes sure correct beginning of packet is always used.
25f1e8
---
25f1e8
 src/dnsmasq.h   |  1 +
25f1e8
 src/outpacket.c | 11 +++++++++++
25f1e8
 src/rfc3315.c   | 29 ++++++++++++++---------------
25f1e8
 3 files changed, 26 insertions(+), 15 deletions(-)
25f1e8
25f1e8
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
25f1e8
index 27ff86a..0749260 100644
25f1e8
--- a/src/dnsmasq.h
25f1e8
+++ b/src/dnsmasq.h
25f1e8
@@ -1563,6 +1563,7 @@ void put_opt6_long(unsigned int val);
25f1e8
 void put_opt6_short(unsigned int val);
25f1e8
 void put_opt6_char(unsigned int val);
25f1e8
 void put_opt6_string(char *s);
25f1e8
+void put_msgtype6(unsigned int val);
25f1e8
 #endif
25f1e8
 
25f1e8
 /* radv.c */
25f1e8
diff --git a/src/outpacket.c b/src/outpacket.c
25f1e8
index d20bd33..1c8f1bc 100644
25f1e8
--- a/src/outpacket.c
25f1e8
+++ b/src/outpacket.c
25f1e8
@@ -115,4 +115,15 @@ void put_opt6_string(char *s)
25f1e8
   put_opt6(s, strlen(s));
25f1e8
 }
25f1e8
 
25f1e8
+void put_msgtype6(unsigned int val)
25f1e8
+{
25f1e8
+  if (outpacket_counter == 0)
25f1e8
+    put_opt6_char(val);
25f1e8
+  else
25f1e8
+    {
25f1e8
+      unsigned char *p = daemon->outpacket.iov_base;
25f1e8
+      *p = val;
25f1e8
+    }
25f1e8
+}
25f1e8
+
25f1e8
 #endif
25f1e8
diff --git a/src/rfc3315.c b/src/rfc3315.c
25f1e8
index 554b1fe..1f1aad8 100644
25f1e8
--- a/src/rfc3315.c
25f1e8
+++ b/src/rfc3315.c
25f1e8
@@ -116,7 +116,6 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
25f1e8
   void *end = inbuff + sz;
25f1e8
   void *opts = inbuff + 34;
25f1e8
   int msg_type = *((unsigned char *)inbuff);
25f1e8
-  unsigned char *outmsgtypep;
25f1e8
   void *opt;
25f1e8
   struct dhcp_vendor *vendor;
25f1e8
 
25f1e8
@@ -178,9 +177,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
25f1e8
     return 0;
25f1e8
   
25f1e8
   /* copy header stuff into reply message and set type to reply */
25f1e8
-  if (!(outmsgtypep = put_opt6(inbuff, 34)))
25f1e8
+  if (!put_opt6(inbuff, 34))
25f1e8
     return 0;
25f1e8
-  *outmsgtypep = DHCP6RELAYREPL;
25f1e8
+  put_msgtype6(DHCP6RELAYREPL);
25f1e8
 
25f1e8
   /* look for relay options and set tags if found. */
25f1e8
   for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
25f1e8
@@ -249,7 +248,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
25f1e8
   struct dhcp_netid *tagif;
25f1e8
   struct dhcp_config *config = NULL;
25f1e8
   struct dhcp_netid known_id, iface_id, v6_id;
25f1e8
-  unsigned char *outmsgtypep;
25f1e8
+  unsigned char *xid;
25f1e8
   struct dhcp_vendor *vendor;
25f1e8
   struct dhcp_context *context_tmp;
25f1e8
   struct dhcp_mac *mac_opt;
25f1e8
@@ -286,10 +285,10 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
25f1e8
   state->tags = &v6_id;
25f1e8
 
25f1e8
   /* copy over transaction-id, and save pointer to message type */
25f1e8
-  if (!(outmsgtypep = put_opt6(inbuff, 4)))
25f1e8
+  if (!(xid = put_opt6(inbuff, 4)))
25f1e8
     return 0;
25f1e8
   start_opts = save_counter(-1);
25f1e8
-  state->xid = outmsgtypep[3] | outmsgtypep[2] << 8 | outmsgtypep[1] << 16;
25f1e8
+  state->xid = xid[3] | xid[2] << 8 | xid[1] << 16;
25f1e8
    
25f1e8
   /* We're going to be linking tags from all context we use. 
25f1e8
      mark them as unused so we don't link one twice and break the list */
25f1e8
@@ -336,7 +335,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
25f1e8
       (msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))
25f1e8
     
25f1e8
     {  
25f1e8
-      *outmsgtypep = DHCP6REPLY;
25f1e8
+      put_msgtype6(DHCP6REPLY);
25f1e8
       o1 = new_opt6(OPTION6_STATUS_CODE);
25f1e8
       put_opt6_short(DHCP6USEMULTI);
25f1e8
       put_opt6_string("Use multicast");
25f1e8
@@ -600,11 +599,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
25f1e8
 	struct dhcp_netid *solicit_tags;
25f1e8
 	struct dhcp_context *c;
25f1e8
 	
25f1e8
-	*outmsgtypep = DHCP6ADVERTISE;
25f1e8
+	put_msgtype6(DHCP6ADVERTISE);
25f1e8
 	
25f1e8
 	if (opt6_find(state->packet_options, state->end, OPTION6_RAPID_COMMIT, 0))
25f1e8
 	  {
25f1e8
-	    *outmsgtypep = DHCP6REPLY;
25f1e8
+	    put_msgtype6(DHCP6REPLY);
25f1e8
 	    state->lease_allocate = 1;
25f1e8
 	    o = new_opt6(OPTION6_RAPID_COMMIT);
25f1e8
 	    end_opt6(o);
25f1e8
@@ -876,7 +875,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
25f1e8
 	int start = save_counter(-1);
25f1e8
 
25f1e8
 	/* set reply message type */
25f1e8
-	*outmsgtypep = DHCP6REPLY;
25f1e8
+	put_msgtype6(DHCP6REPLY);
25f1e8
 	state->lease_allocate = 1;
25f1e8
 
25f1e8
 	log6_quiet(state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
25f1e8
@@ -992,7 +991,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
25f1e8
     case DHCP6RENEW:
25f1e8
       {
25f1e8
 	/* set reply message type */
25f1e8
-	*outmsgtypep = DHCP6REPLY;
25f1e8
+	put_msgtype6(DHCP6REPLY);
25f1e8
 	
25f1e8
 	log6_quiet(state, "DHCPRENEW", NULL, NULL);
25f1e8
 
25f1e8
@@ -1104,7 +1103,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
25f1e8
 	int good_addr = 0;
25f1e8
 
25f1e8
 	/* set reply message type */
25f1e8
-	*outmsgtypep = DHCP6REPLY;
25f1e8
+	put_msgtype6(DHCP6REPLY);
25f1e8
 	
25f1e8
 	log6_quiet(state, "DHCPCONFIRM", NULL, NULL);
25f1e8
 	
25f1e8
@@ -1168,7 +1167,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
25f1e8
 	log6_quiet(state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state->hostname);
25f1e8
 	if (ignore)
25f1e8
 	  return 0;
25f1e8
-	*outmsgtypep = DHCP6REPLY;
25f1e8
+	put_msgtype6(DHCP6REPLY);
25f1e8
 	tagif = add_options(state, 1);
25f1e8
 	break;
25f1e8
       }
25f1e8
@@ -1177,7 +1176,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
25f1e8
     case DHCP6RELEASE:
25f1e8
       {
25f1e8
 	/* set reply message type */
25f1e8
-	*outmsgtypep = DHCP6REPLY;
25f1e8
+	put_msgtype6(DHCP6REPLY);
25f1e8
 
25f1e8
 	log6_quiet(state, "DHCPRELEASE", NULL, NULL);
25f1e8
 
25f1e8
@@ -1242,7 +1241,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
25f1e8
     case DHCP6DECLINE:
25f1e8
       {
25f1e8
 	/* set reply message type */
25f1e8
-	*outmsgtypep = DHCP6REPLY;
25f1e8
+	put_msgtype6(DHCP6REPLY);
25f1e8
 	
25f1e8
 	log6_quiet(state, "DHCPDECLINE", NULL, NULL);
25f1e8
 
25f1e8
-- 
25f1e8
2.34.1
25f1e8