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

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