Fix CVE-2012-1820

Signed-off-by: Adam Tkac <atkac@redhat.com>
This commit is contained in:
Adam Tkac 2012-06-07 12:04:24 +02:00
parent 3e4599a767
commit dd793e2bff
2 changed files with 82 additions and 1 deletions

View File

@ -0,0 +1,74 @@
@@ -, +, @@
bgpd: CVE-2012-1820, DoS in bgp_capability_orf()
An ORF (code 3) capability TLV is defined to contain exactly one
AFI/SAFI block. Function bgp_capability_orf(), which parses ORF
capability TLV, uses do-while cycle to call its helper function
bgp_capability_orf_entry(), which actually processes the AFI/SAFI data
block. The call is made at least once and repeated as long as the input
buffer has enough data for the next call.
The helper function, bgp_capability_orf_entry(), uses "Number of ORFs"
field of the provided AFI/SAFI block to verify, if it fits the input
buffer. However, the check is made based on the total length of the ORF
TLV regardless of the data already consumed by the previous helper
function call(s). This way, the check condition is only valid for the
first AFI/SAFI block inside an ORF capability TLV.
For the subsequent calls of the helper function, if any are made, the
check condition may erroneously tell, that the current "Number of ORFs"
field fits the buffer boundary, where in fact it does not. This makes it
possible to trigger an assertion by feeding an OPEN message with a
specially-crafted malformed ORF capability TLV.
This commit fixes the vulnerability by making the implementation follow
the spec.
--- a/bgpd/bgp_open.c
+++ a/bgpd/bgp_open.c
@@ -231,7 +231,7 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
}
/* validate number field */
- if (sizeof (struct capability_orf_entry) + (entry.num * 2) > hdr->length)
+ if (sizeof (struct capability_orf_entry) + (entry.num * 2) != hdr->length)
{
zlog_info ("%s ORF Capability entry length error,"
" Cap length %u, num %u",
@@ -335,28 +335,6 @@ bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
}
static int
-bgp_capability_orf (struct peer *peer, struct capability_header *hdr)
-{
- struct stream *s = BGP_INPUT (peer);
- size_t end = stream_get_getp (s) + hdr->length;
-
- assert (stream_get_getp(s) + sizeof(struct capability_orf_entry) <= end);
-
- /* We must have at least one ORF entry, as the caller has already done
- * minimum length validation for the capability code - for ORF there must
- * at least one ORF entry (header and unknown number of pairs of bytes).
- */
- do
- {
- if (bgp_capability_orf_entry (peer, hdr) == -1)
- return -1;
- }
- while (stream_get_getp(s) + sizeof(struct capability_orf_entry) < end);
-
- return 0;
-}
-
-static int
bgp_capability_restart (struct peer *peer, struct capability_header *caphdr)
{
struct stream *s = BGP_INPUT (peer);
@@ -573,7 +551,7 @@ bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability,
break;
case CAPABILITY_CODE_ORF:
case CAPABILITY_CODE_ORF_OLD:
- if (bgp_capability_orf (peer, &caphdr))
+ if (bgp_capability_orf_entry (peer, &caphdr))
return -1;
break;
case CAPABILITY_CODE_RESTART:

View File

@ -32,7 +32,7 @@
Summary: Routing daemon
Name: quagga
Version: 0.99.21
Release: 1%{?dist}
Release: 2%{?dist}
License: GPLv2+
Group: System Environment/Daemons
Source0: http://www.quagga.net/download/%{name}-%{version}.tar.xz
@ -70,6 +70,8 @@ Requires(postun): systemd-units
Provides: routingdaemon = %{version}-%{release}
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Patch0: quagga-CVE-2012-1820.patch
%description
Quagga is free software that operates TCP/IP-based routing protocols. It takes
a multi-server and multi-threaded approach to resolving the current complexity
@ -113,6 +115,8 @@ developing OSPF-API and quagga applications.
%prep
%setup -q
%patch0 -p1 -b .CVE-2012-1820
%build
# FC5+ automatic -fstack-protector-all switch
export RPM_OPT_FLAGS=${RPM_OPT_FLAGS//-fstack-protector/-fstack-protector-all}
@ -432,6 +436,9 @@ rm -rf $RPM_BUILD_ROOT
%endif
%changelog
* Thu Jun 07 2012 Adam Tkac <atkac redhat com> 0.99.21-2
- fix CVE-2012-1820
* Thu May 03 2012 Adam Tkac <atkac redhat com> 0.99.21
- update to 0.99.21
- various packaging fixes