58 lines
2.0 KiB
Diff
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
|
||
|
|