Blame SOURCES/dnsmasq-2.76-fix-dhcp-option-arrangements.patch

33b374
From 591ed1e90503817938ccf5f127e677a8dd48b6d8 Mon Sep 17 00:00:00 2001
33b374
From: Simon Kelley <simon@thekelleys.org.uk>
33b374
Date: Mon, 11 Jul 2016 18:18:42 +0100
33b374
Subject: [PATCH] Fix bad behaviour with some DHCP option arrangements.
33b374
33b374
The check that there's enough space to store the DHCP agent-id
33b374
at the end of the packet could succeed when it should fail
33b374
if the END option is in either of the oprion-overload areas.
33b374
That could overwrite legit options in the request and cause
33b374
bad behaviour. It's highly unlikely that any sane DHCP client
33b374
would trigger this bug, and it's never been seen, but this
33b374
fixes the problem.
33b374
33b374
Also fix off-by-one in bounds checking of option processing.
33b374
Worst case scenario on that is a read one byte beyond the
33b374
end off a buffer with a crafted packet, and maybe therefore
33b374
a SIGV crash if the memory after the buffer is not mapped.
33b374
33b374
Thanks to Timothy Becker for spotting these.
33b374
---
33b374
 src/rfc2131.c | 5 +++--
33b374
 1 file changed, 3 insertions(+), 2 deletions(-)
33b374
33b374
diff --git a/src/rfc2131.c b/src/rfc2131.c
33b374
index b7c167e..8b99d4b 100644
33b374
--- a/src/rfc2131.c
33b374
+++ b/src/rfc2131.c
33b374
@@ -186,7 +186,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
33b374
 	     be enough free space at the end of the packet to copy the option. */
33b374
 	  unsigned char *sopt;
33b374
 	  unsigned int total = option_len(opt) + 2;
33b374
-	  unsigned char *last_opt = option_find(mess, sz, OPTION_END, 0);
33b374
+	  unsigned char *last_opt = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char *)mess) + sz,
33b374
+						 OPTION_END, 0);
33b374
 	  if (last_opt && last_opt < end - total)
33b374
 	    {
33b374
 	      end -= total;
33b374
@@ -1606,7 +1607,7 @@ static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt
33b374
 {
33b374
   while (1) 
33b374
     {
33b374
-      if (p > end)
33b374
+      if (p >= end)
33b374
 	return NULL;
33b374
       else if (*p == OPTION_END)
33b374
 	return opt == OPTION_END ? p : NULL;
33b374
-- 
33b374
2.9.3
33b374