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

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