jobcore/pacman/pacman-fix-gnupg-binary-data.patch
2024-03-01 22:02:29 +02:00

106 lines
3.9 KiB
Diff

From 86ec26b2d33372a4b3bda48f22c4a9f226c3ccce Mon Sep 17 00:00:00 2001
From: David Runge <dvzrv@archlinux.org>
Date: Sun, 21 Jan 2024 12:33:04 +0100
Subject: [PATCH] makepkg: Improve robustness of signature verification by
limiting terms
The output of
`gpg --quiet --batch --status-fd /dev/stdout --verify <signature_file> <file> 2> /dev/null`
or
`git verify-commit --raw <commit> 2>&1`
may contain binary data, if the signature has been created with an
OpenPGP implementation, that e.g. makes use of notations.
If the notation string (see `NOTATION_DATA` in /usr/share/doc/gnupg/
DETAILS) contains a trailing binary char, this will break signature
verification, as any following entry (e.g. `VALIDSIG`) will be offset.
As we are only making use of a narrow set of terms from the statusfile
(namely `NEWSIG`, `GOODSIG`, `EXPSIG`, `EXPKEYSIG`, `REVKEYSIG`,
`BADSIG`, `ERRSIG`, `VALIDSIG`, `TRUST_UNDEFINED`, `TRUST_NEVER`,
`TRUST_MARGINAL`, `TRUST_FULLY`, `TRUST_ULTIMATE`), we are applying a
filter, so that only understood terms are written to the file.
Signed-off-by: David Runge <dvzrv@archlinux.org>
---
.../integrity/verify_signature.sh.in | 27 ++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/scripts/libmakepkg/integrity/verify_signature.sh.in b/scripts/libmakepkg/integrity/verify_signature.sh.in
index ca1d5a868..d786a2c39 100644
--- a/scripts/libmakepkg/integrity/verify_signature.sh.in
+++ b/scripts/libmakepkg/integrity/verify_signature.sh.in
@@ -26,6 +26,12 @@ MAKEPKG_LIBRARY=${MAKEPKG_LIBRARY:-'@libmakepkgdir@'}
source "$MAKEPKG_LIBRARY/util/message.sh"
source "$MAKEPKG_LIBRARY/util/pkgbuild.sh"
+# Filter the contents of a GnuPG statusfile to only contain understood terms to narrow the file's scope and circumvent
+# the use of terms (e.g. NOTATION_DATA) that may contain unescaped binary data
+filter_gnupg_statusfile() {
+ grep -E "(.*SIG| TRUST_.*)"
+}
+
check_pgpsigs() {
(( SKIPPGPCHECK )) && return 0
! source_has_signatures && return 0
@@ -35,6 +41,7 @@ check_pgpsigs() {
local netfile proto pubkey success status fingerprint trusted
local warnings=0
local errors=0
+ local statusfile_raw="$(mktemp)"
local statusfile=$(mktemp)
local all_sources
@@ -103,7 +110,7 @@ check_pgpsigs() {
printf '\n' >&2
done
- rm -f "$statusfile"
+ rm -f "$statusfile" "$statusfile_raw"
if (( errors )); then
error "$(gettext "One or more PGP signatures could not be verified!")"
@@ -158,12 +165,19 @@ verify_file_signature() {
esac
# verify the signature and write metadata to a status file
- if ! $decompress < "$sourcefile" | gpg --quiet --batch --status-file "$statusfile" --verify "$file" - 2> /dev/null; then
+ if ! $decompress < "$sourcefile" | gpg --quiet --batch --status-file "$statusfile_raw" --verify "$file" - 2> /dev/null; then
printf '%s\n' "$(gettext "%s is unable to verify the signature.")" "gpg" >&2
errors=1
return 1
fi
+ # create a statusfile that contains only understood terms
+ if ! filter_gnupg_statusfile > "$statusfile" < "$statusfile_raw"; then
+ printf '%s\n' "$(gettext "unable to extract signature metadata.")" >&2
+ errors=1
+ return 1
+ fi
+
return 0
}
@@ -196,12 +210,19 @@ verify_git_signature() {
printf " %s git repo ... " "${dir##*/}" >&2
# verify the signature and write metadata to a status file
- if ! git -C "$dir" verify-$fragtype --raw "$fragval" > "$statusfile" 2>&1; then
+ if ! git -C "$dir" verify-$fragtype --raw "$fragval" > "$statusfile_raw" 2>&1; then
printf '%s\n' "$(gettext "%s is unable to verify the signature.")" "git" >&2
errors=1
return 1
fi
+ # create a statusfile that contains only understood terms
+ if ! filter_gnupg_statusfile > "$statusfile" < "$statusfile_raw"; then
+ printf '%s\n' "$(gettext "unable to extract signature metadata.")" >&2
+ errors=1
+ return 1
+ fi
+
if ! grep -qs NEWSIG "$statusfile"; then
printf '%s\n' "$(gettext "SIGNATURE NOT FOUND")" >&2
errors=1
--
GitLab