quagga/0004-zebra-stack-overrun-in-IPv6-RA-receive-code-CVE-2016.patch
Michal Sekletar 7f173b2f4c Fix for CVE-2016-1245
Resolves: #1386110
2016-10-24 17:22:59 +02:00

58 lines
2.0 KiB
Diff

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