[git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.27-8-g0aac920
by Werner Koch
cvs at cvs.gnupg.org
Sun Apr 5 19:35:19 CEST 2015
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".
The branch, STABLE-BRANCH-2-0 has been updated
via 0aac920f23fd07e152fdb7385299c92bb9a4ade3 (commit)
from 2a2da1b165f0a3050bca51dea67db9c04b9cb734 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 0aac920f23fd07e152fdb7385299c92bb9a4ade3
Author: Werner Koch <wk at gnupg.org>
Date: Sun Apr 5 19:33:36 2015 +0200
gpg: Fix DoS while parsing mangled secret key packets.
* g10/parse-packet.c (parse_key): Check PKTLEN before calling mpi_read
et al.
--
Due to the missing length checks PKTLEN may turn negative. Because
PKTLEN is an unsigned int the malloc in read_rest would try to malloc
a too large number and terminate the process with "error reading rest
of packet: Cannot allocate memory".
Reported-by: Hanno Böck.
Signed-off-by: Werner Koch <wk at gnupg.org>
(backported from 2.1 commit d901efcebaefaf6eae4a9b9aa8f0c2c055d3518a)
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 5a98961..a8f9d99 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -1828,6 +1828,12 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
byte temp[16];
size_t snlen = 0;
+ if (pktlen < 1)
+ {
+ rc = GPG_ERR_INV_PACKET;
+ goto leave;
+ }
+
if( !npkey ) {
sk->skey[0] = gcry_mpi_set_opaque (NULL, read_rest(inp, pktlen, 0),
pktlen*8 );
@@ -1836,7 +1842,9 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
}
for(i=0; i < npkey; i++ ) {
- n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
+ n = pktlen;
+ sk->skey[i] = mpi_read(inp, &n, 0 );
+ pktlen -=n;
if( list_mode ) {
fprintf (listfp, "\tskey[%d]: ", i);
mpi_print(listfp, sk->skey[i], mpi_print_mode );
@@ -1847,7 +1855,8 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
}
if (rc) /* one of the MPIs were bad */
goto leave;
- sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
+ sk->protect.algo = iobuf_get_noeof(inp);
+ pktlen--;
sk->protect.sha1chk = 0;
if( sk->protect.algo ) {
sk->is_protected = 1;
@@ -1858,12 +1867,15 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
goto leave;
}
sk->protect.sha1chk = (sk->protect.algo == 254);
- sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
+ sk->protect.algo = iobuf_get_noeof(inp);
+ pktlen--;
/* Note that a sk->protect.algo > 110 is illegal, but
I'm not erroring on it here as otherwise there
would be no way to delete such a key. */
- sk->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--;
- sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
+ sk->protect.s2k.mode = iobuf_get_noeof(inp);
+ pktlen--;
+ sk->protect.s2k.hash_algo = iobuf_get_noeof(inp);
+ pktlen--;
/* check for the special GNU extension */
if( is_v4 && sk->protect.s2k.mode == 101 ) {
for(i=0; i < 4 && pktlen; i++, pktlen-- )
@@ -2013,6 +2025,11 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
/* ugly; the length is encrypted too, so we read all
* stuff up to the end of the packet into the first
* skey element */
+ if (pktlen < 2) /* At least two bytes for the length. */
+ {
+ rc = GPG_ERR_INV_PACKET;
+ goto leave;
+ }
sk->skey[npkey] = gcry_mpi_set_opaque (NULL,
read_rest(inp, pktlen, 0),
pktlen*8);
@@ -2029,6 +2046,11 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
fprintf (listfp, "\tskey[%d]: [encrypted]\n", i);
}
else {
+ if (pktlen < 2) /* At least two bytes for the length. */
+ {
+ rc = GPG_ERR_INV_PACKET;
+ goto leave;
+ }
n = pktlen;
sk->skey[i] = mpi_read(inp, &n, 0 );
pktlen -=n;
@@ -2045,7 +2067,13 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
if (rc)
goto leave;
- sk->csum = read_16(inp); pktlen -= 2;
+ if (pktlen < 2)
+ {
+ rc = GPG_ERR_INV_PACKET;
+ goto leave;
+ }
+ sk->csum = read_16(inp);
+ pktlen -= 2;
if( list_mode ) {
fprintf (listfp, "\tchecksum: %04hx\n", sk->csum);
}
@@ -2057,6 +2085,12 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
else {
PKT_public_key *pk = pkt->pkt.public_key;
+ if (pktlen < 1)
+ {
+ rc = GPG_ERR_INV_PACKET;
+ goto leave;
+ }
+
if( !npkey ) {
pk->pkey[0] = gcry_mpi_set_opaque ( NULL,
read_rest(inp, pktlen, 0),
@@ -2066,7 +2100,9 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
}
for(i=0; i < npkey; i++ ) {
- n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
+ n = pktlen;
+ pk->pkey[i] = mpi_read(inp, &n, 0 );
+ pktlen -=n;
if( list_mode ) {
fprintf (listfp, "\tpkey[%d]: ", i);
mpi_print(listfp, pk->pkey[i], mpi_print_mode );
-----------------------------------------------------------------------
Summary of changes:
g10/parse-packet.c | 50 +++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 43 insertions(+), 7 deletions(-)
hooks/post-receive
--
The GNU Privacy Guard
http://git.gnupg.org
More information about the Gnupg-commits
mailing list