dcf5a52
From c4ea553123a5ab1bf5fab38f12a540020c08293d Mon Sep 17 00:00:00 2001
dcf5a52
From: David Lamparter <equinox@opensourcerouting.org>
dcf5a52
Date: Wed, 31 Aug 2016 13:31:16 +0200
dcf5a52
Subject: [PATCH 4/4] zebra: stack overrun in IPv6 RA receive code
dcf5a52
 (CVE-2016-1245)
dcf5a52
dcf5a52
The IPv6 RA code also receives ICMPv6 RS and RA messages.
dcf5a52
Unfortunately, by bad coding practice, the buffer size specified on
dcf5a52
receiving such messages mixed up 2 constants that in fact have
dcf5a52
different values.
dcf5a52
dcf5a52
The code itself has:
dcf5a52
 #define RTADV_MSG_SIZE 4096
dcf5a52
While BUFSIZ is system-dependent, in my case (x86_64 glibc):
dcf5a52
 /usr/include/_G_config.h:#define _G_BUFSIZ 8192
dcf5a52
 /usr/include/libio.h:#define _IO_BUFSIZ _G_BUFSIZ
dcf5a52
 /usr/include/stdio.h:# define BUFSIZ _IO_BUFSIZ
dcf5a52
dcf5a52
FreeBSD, OpenBSD, NetBSD and Illumos are not affected, since all of them
dcf5a52
have BUFSIZ == 1024.
dcf5a52
dcf5a52
As the latter is passed to the kernel on recvmsg(), it's possible to
dcf5a52
overwrite 4kB of stack -- with ICMPv6 packets that can be globally sent
dcf5a52
to any of the system's addresses (using fragmentation to get to 8k).
dcf5a52
dcf5a52
(The socket has filters installed limiting this to RS and RA packets,
dcf5a52
but does not have a filter for source address or TTL.)
dcf5a52
dcf5a52
Issue discovered by trying to test other stuff, which randomly caused
dcf5a52
the stack to be smaller than 8kB in that code location, which then
dcf5a52
causes the kernel to report EFAULT (Bad address).
dcf5a52
dcf5a52
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
dcf5a52
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
dcf5a52
dcf5a52
Cherry-picked from: cfb1fae25f8c092e0d17073eaf7bd428ce1cd546
dcf5a52
Resolves: #1386110
dcf5a52
---
dcf5a52
 zebra/rtadv.c | 2 +-
dcf5a52
 1 file changed, 1 insertion(+), 1 deletion(-)
dcf5a52
dcf5a52
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
dcf5a52
index 21ca6da..973ae08 100644
dcf5a52
--- a/zebra/rtadv.c
dcf5a52
+++ b/zebra/rtadv.c
dcf5a52
@@ -515,7 +515,7 @@ rtadv_read (struct thread *thread)
dcf5a52
   /* Register myself. */
dcf5a52
   rtadv_event (RTADV_READ, sock);
dcf5a52
 
dcf5a52
-  len = rtadv_recv_packet (sock, buf, BUFSIZ, &from, &ifindex, &hoplimit);
dcf5a52
+  len = rtadv_recv_packet (sock, buf, sizeof (buf), &from, &ifindex, &hoplimit);
dcf5a52
 
dcf5a52
   if (len < 0) 
dcf5a52
     {
dcf5a52
-- 
dcf5a52
2.7.4
dcf5a52