From f1cb79db8276427e7c2b0a282f36b8f0b4eec016 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 13 Jan 2026 12:08:24 +0100 Subject: [PATCH] Fix CVE-2025-68973 (gpg.fail/memcpy) Resolves: RHEL-137866 --- gnupg-2.3.3-memcpy.patch | 85 ++++++++++++++++++++++++++++++++++++++++ gnupg2.spec | 4 +- 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 gnupg-2.3.3-memcpy.patch diff --git a/gnupg-2.3.3-memcpy.patch b/gnupg-2.3.3-memcpy.patch new file mode 100644 index 0000000..f2544b6 --- /dev/null +++ b/gnupg-2.3.3-memcpy.patch @@ -0,0 +1,85 @@ +From 115d138ba599328005c5321c0ef9f00355838ca9 Mon Sep 17 00:00:00 2001 +From: Werner Koch +Date: Thu, 23 Oct 2025 11:36:04 +0200 +Subject: [PATCH] gpg: Fix possible memory corruption in the armor parser. + +* g10/armor.c (armor_filter): Fix faulty double increment. + +* common/iobuf.c (underflow_target): Assert that the filter +implementations behave well. +-- + +This fixes a bug in a code path which can only be reached with special +crafted input data and would then error out at an upper layer due to +corrupt input (every second byte in the buffer is unitialized +garbage). No fuzzing has yet hit this case and we don't have a test +case for this code path. However memory corruption can never be +tolerated as it always has the protential for remode code execution. + +Reported-by: 8b79fe4dd0581c1cd000e1fbecba9f39e16a396a +Fixes-commit: c27c7416d5148865a513e007fb6f0a34993a6073 +which fixed +Fixes-commit: 7d0efec7cf5ae110c99511abc32587ff0c45b14f + +The bug was introduced on 1999-01-07 by me: +* armor.c: Rewrote large parts. +which I fixed on 1999-03-02 but missed to fix the other case: +* armor.c (armor_filter): Fixed armor bypassing. + +Below is base64+gzipped test data which can be used with valgrind to +show access to uninitalized memory in write(2) in the unpatched code. + +--8<---------------cut here---------------start------------->8--- +H4sICIDd+WgCA3h4AO3QMQ6CQBCG0djOKbY3G05gscYFSRAJt/AExp6Di0cQG0ze +a//MV0zOq3Pt+jFN3ZTKfLvP9ZLafqifJUe8juOjeZbVtSkbRPmRgICAgICAgICA +gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA +gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA +gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA +gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA +gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA +gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA +gICAgICAgICAgICAgICAgICAgICAgICAgMCXF6dYDgAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7E14AAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwZ94aieId3+8EAA== +--8<---------------cut here---------------end--------------->8--- +--- + common/iobuf.c | 6 ++++++ + g10/armor.c | 4 ++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/common/iobuf.c b/common/iobuf.c +index 8a128b3f6..769df958d 100644 +--- a/common/iobuf.c ++++ b/common/iobuf.c +@@ -1939,8 +1939,12 @@ underflow_target (iobuf_t a, int clear_pending_eof, size_t target) + A->FILTER. */ + rc = 0; + else ++ { ++ size_t tmplen = len; /* Used to check for bugs in the filter. */ + rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain, + &a->d.buf[a->d.len], &len); ++ log_assert (len <= tmplen); ++ } + a->d.len += len; + + if (DBG_IOBUF) +diff --git a/g10/armor.c b/g10/armor.c +index 036b72772..59a6202aa 100644 +--- a/g10/armor.c ++++ b/g10/armor.c +@@ -1312,8 +1312,8 @@ armor_filter( void *opaque, int control, + n = 0; + if( afx->buffer_len ) { + /* Copy the data from AFX->BUFFER to BUF. */ +- for(; n < size && afx->buffer_pos < afx->buffer_len; n++ ) +- buf[n++] = afx->buffer[afx->buffer_pos++]; ++ for(; n < size && afx->buffer_pos < afx->buffer_len;) ++ buf[n++] = afx->buffer[afx->buffer_pos++]; + if( afx->buffer_pos >= afx->buffer_len ) + afx->buffer_len = 0; + } + diff --git a/gnupg2.spec b/gnupg2.spec index e5616e2..be97be2 100644 --- a/gnupg2.spec +++ b/gnupg2.spec @@ -26,7 +26,8 @@ Patch22: gnupg-2.2.18-gpg-accept-subkeys-with-a-good-revocation-but-no-self-sig. Patch23: gnupg-2.2.20-CVE-2022-34903.patch # Fixes for issues found in Coverity scan - reported upstream Patch30: gnupg-2.2.20-coverity.patch - +# https://github.com/gpg/gnupg/commit/115d138ba599328005c5321c0ef9f00355838ca9 +Patch36: gnupg-2.3.3-memcpy.patch URL: http://www.gnupg.org/ @@ -110,6 +111,7 @@ to the base GnuPG package %patch23 -p1 -b .CVE-2022-34903 %patch30 -p1 -b .coverity +%patch36 -p1 -b .memcpy # pcsc-lite library major: 0 in 1.2.0, 1 in 1.2.9+ (dlopen()'d in pcsc-wrapper) # Note: this is just the name of the default shared lib to load in scdaemon,