From 09f2a7bca624d0492e1d7ab29ce19542249c13ff Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Fri, 21 Aug 2015 11:55:15 +0200 Subject: [PATCH] common: Don't incorrectly reject 4 GB - 1 sized packets. * g10/parse-packet.c (parse): Don't reject 4 GB - 1 sized packets. Add the constraint that the type must be 63. * kbx/keybox-openpgp.c (next_packet): Likewise. * tests/openpgp/4gb-packet.asc: New file. * tests/openpgp/4gb-packet.test: New file. * tests/openpgp/Makefile.am (TESTS): Add 4gb-packet.test. (TEST_FILES): Add 4gb-packet.asc. -- Signed-off-by: Neal H. Walfield . --- g10/parse-packet.c | 9 ++++++++- kbx/keybox-openpgp.c | 9 ++++++++- tests/openpgp/4gb-packet.asc | Bin 0 -> 4983 bytes tests/openpgp/4gb-packet.test | 16 ++++++++++++++++ tests/openpgp/Makefile.am | 4 ++-- 5 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 tests/openpgp/4gb-packet.asc create mode 100755 tests/openpgp/4gb-packet.test diff --git a/g10/parse-packet.c b/g10/parse-packet.c index bc9965331..edebbe782 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -643,7 +643,14 @@ parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos, } } - if (pktlen == (unsigned long) (-1)) + /* Sometimes the decompressing layer enters an error state in which + it simply outputs 0xff for every byte read. If we have a stream + of 0xff bytes, then it will be detected as a new format packet + with type 63 and a 4-byte encoded length that is 4G-1. Since + packets with type 63 are private and we use them as a control + packet, which won't be 4 GB, we reject such packets as + invalid. */ + if (pkttype == 63 && pktlen == 0xFFFFFFFF) { /* With some probability this is caused by a problem in the * the uncompressing layer - in some error cases it just loops diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c index 2cac242e9..a5f602b7b 100644 --- a/kbx/keybox-openpgp.c +++ b/kbx/keybox-openpgp.c @@ -139,7 +139,14 @@ next_packet (unsigned char const **bufptr, size_t *buflen, return gpg_error (GPG_ERR_UNEXPECTED); } - if (pktlen == (unsigned long)(-1)) + if (pkttype == 63 && pktlen == 0xFFFFFFFF) + /* Sometimes the decompressing layer enters an error state in + which it simply outputs 0xff for every byte read. If we have a + stream of 0xff bytes, then it will be detected as a new format + packet with type 63 and a 4-byte encoded length that is 4G-1. + Since packets with type 63 are private and we use them as a + control packet, which won't be 4 GB, we reject such packets as + invalid. */ return gpg_error (GPG_ERR_INV_PACKET); if (pktlen > len) diff --git a/tests/openpgp/4gb-packet.asc b/tests/openpgp/4gb-packet.asc new file mode 100644 index 0000000000000000000000000000000000000000..7e5d6f349a83c50c2ed6935f4d78b5beaeef5774 GIT binary patch literal 4983 zcmZ3?>=cz@X6P8H792UJb?;H;m1W<5zj9(>aA06iVqy?tm?6O6;=t&@$icwSpuoVu zv4EjOI+TH};j6(Vj#ZfpGA=N1+qwj@xHf1k;^>xNps|Qcz^tmU{yf(?i&KGDo?m}#oq0uu%{2VP!=s%B?32L^r*2F3-K zl^qz^S592O%jVYJvV*7DLCR2qSE_O0 zRyJk9g-vXszPv!=X0bIeE=V$xVqmzyV8Y8_V#L4$9I45WV&Gro$RfnZlCpq7h(m>m z!|A2voF-E#Ax@BBoPLGtd!MNvMfJ3+uHP(w_e0(6>J+;Tmw9VUE9>V?x*mRhhwi8B zUpMO(8SZa6;H>;m%UCln`beJd{jV__T5ca|yB+bv^FyVm9@_!QJIZx^JJ~`c=N@u1 zUEcqo>A@}zV+oJ@{J{lW>Wzy8)0h;FfAo42RpytyUipo*v%LDn_3pYe911*pJI%9i z82qtR`7>uzU!73O-*Z7S{+r+SX>!eel8E74uoo z?snCjYx`w|lW^qW%{9qW>$xk<{muop&9`)k&3zL7rlWsfRMNIrzw4o oUS!0wwn|Ask-RPwYvNhfWTYXW6F!0Q38DU;qFB literal 0 HcmV?d00001 diff --git a/tests/openpgp/4gb-packet.test b/tests/openpgp/4gb-packet.test new file mode 100755 index 000000000..f8e43c80b --- /dev/null +++ b/tests/openpgp/4gb-packet.test @@ -0,0 +1,16 @@ +#!/bin/sh + +. $srcdir/defs.inc || exit 3 + +# GnuPG through 2.1.7 would incorrect mark packets whose size is +# 2^32-1 as invalid and exit with status code 2. +i=$srcdir/4gb-packet.asc + +if ! $GPG --list-packets $i +then + echo Failed to parse 4GB packet. + exit 1 +else + echo Can parse 4GB packets. + exit 0 +fi diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am index dae8c1141..4fdb0a607 100644 --- a/tests/openpgp/Makefile.am +++ b/tests/openpgp/Makefile.am @@ -38,7 +38,7 @@ TESTS = version.test mds.test \ armdetachm.test detachm.test genkey1024.test \ conventional.test conventional-mdc.test \ multisig.test verify.test armor.test \ - import.test ecc.test finish.test + import.test ecc.test 4gb-packet.test finish.test TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \ @@ -46,7 +46,7 @@ TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \ pubring.pkr.asc secring.skr.asc secdemo.asc pubdemo.asc \ gpg.conf.tmpl gpg-agent.conf.tmpl \ bug537-test.data.asc bug894-test.asc \ - bug1223-good.asc bug1223-bogus.asc + bug1223-good.asc bug1223-bogus.asc 4gb-packet.asc data_files = data-500 data-9000 data-32000 data-80000 plain-large