File 0005-Fix-possible-read-access-beyond-the-buffer.patch of Package libksba
From a7eed17a0b2a1c09ef986f3b4b323cd31cea2b64 Mon Sep 17 00:00:00 2001
From: Werner Koch <wk@gnupg.org>
Date: Tue, 3 May 2016 14:10:04 +0200
Subject: [PATCH 3/9] Fix possible read access beyond the buffer.
* src/ber-help.c (_ksba_ber_parse_tl): Add extra sanity check.
* src/cert.c (ksba_cert_get_cert_policies): Check TLV given length
against buffer length.
(ksba_cert_get_ext_key_usages): Ditto.
* src/ocsp.c (parse_asntime_into_isotime): Ditto.
--
The returned length of the object from _ksba_ber_parse_tl (ti.length)
was not always checked against the actual buffer length, thus leading
to a read access after the end of the buffer and thus a segv.
GnuPG-bug-id: 2344
Reported-by: Pascal Cuoq
Signed-off-by: Werner Koch <wk@gnupg.org>
---
src/ber-help.c | 6 ++++++
src/cert.c | 23 ++++++++++++++++++++++-
src/name.c | 2 +-
src/ocsp.c | 2 ++
4 files changed, 31 insertions(+), 2 deletions(-)
Index: libksba-1.3.0/src/ber-help.c
===================================================================
--- libksba-1.3.0.orig/src/ber-help.c
+++ libksba-1.3.0/src/ber-help.c
@@ -285,9 +285,15 @@ _ksba_ber_parse_tl (unsigned char const
ti->buf[ti->nhdr++] = c;
len |= c & 0xff;
}
+ /* Sanity check for the length: This is done so that we can take
+ * the value for malloc plus some additional bytes without
+ * risking an overflow. */
+ if (len > (1 << 30))
+ return gpg_error (GPG_ERR_BAD_BER);
ti->length = len;
}
+
/* Without this kludge some example certs can't be parsed */
if (ti->class == CLASS_UNIVERSAL && !ti->tag)
ti->length = 0;
Index: libksba-1.3.0/src/cert.c
===================================================================
--- libksba-1.3.0.orig/src/cert.c
+++ libksba-1.3.0/src/cert.c
@@ -1337,9 +1337,15 @@ ksba_cert_get_cert_policies (ksba_cert_t
err = gpg_error (GPG_ERR_NOT_DER_ENCODED);
goto leave;
}
+ if (ti.length > derlen)
+ {
+ err = gpg_error (GPG_ERR_BAD_BER);
+ goto leave;
+ }
if (!ti.length)
{
- err = gpg_error (GPG_ERR_INV_CERT_OBJ); /* no empty inner SEQ */
+ /* We do not accept an empty inner SEQ */
+ err = gpg_error (GPG_ERR_INV_CERT_OBJ);
goto leave;
}
if (ti.nhdr+ti.length > seqlen)
@@ -1358,6 +1364,11 @@ ksba_cert_get_cert_policies (ksba_cert_t
err = gpg_error (GPG_ERR_INV_CERT_OBJ);
goto leave;
}
+ if (ti.length > derlen)
+ {
+ err = gpg_error (GPG_ERR_BAD_BER);
+ goto leave;
+ }
if (ti.nhdr+ti.length > seqseqlen)
{
err = gpg_error (GPG_ERR_BAD_BER);
@@ -1460,6 +1471,16 @@ ksba_cert_get_ext_key_usages (ksba_cert_
err = gpg_error (GPG_ERR_INV_CERT_OBJ);
goto leave;
}
+ if (ti.ndef)
+ {
+ err = gpg_error (GPG_ERR_NOT_DER_ENCODED);
+ goto leave;
+ }
+ if (ti.length > derlen)
+ {
+ err = gpg_error (GPG_ERR_BAD_BER);
+ goto leave;
+ }
suboid = ksba_oid_to_str (der, ti.length);
if (!suboid)
Index: libksba-1.3.0/src/name.c
===================================================================
--- libksba-1.3.0.orig/src/name.c
+++ libksba-1.3.0/src/name.c
@@ -113,7 +113,7 @@ _ksba_name_new_from_der (ksba_name_t *r_
*r_name = NULL;
- /* count and check for encoding errors - we won;t do this again
+ /* Count and check for encoding errors - we won't do this again
during the second pass */
der = image;
derlen = imagelen;
Index: libksba-1.3.0/src/ocsp.c
===================================================================
--- libksba-1.3.0.orig/src/ocsp.c
+++ libksba-1.3.0/src/ocsp.c
@@ -231,6 +231,8 @@ parse_asntime_into_isotime (unsigned cha
&& (ti.tag == TYPE_UTC_TIME || ti.tag == TYPE_GENERALIZED_TIME)
&& !ti.is_constructed) )
err = gpg_error (GPG_ERR_INV_OBJ);
+ else if (ti.length > *len)
+ err = gpg_error (GPG_ERR_INV_BER);
else if (!(err = _ksba_asntime_to_iso (*buf, ti.length,
ti.tag == TYPE_UTC_TIME, isotime)))
parse_skip (buf, len, &ti);