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

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