On 2026-08-15 Andreas Metzler <[email protected]> wrote:
> On 2026-07-13 Jonathan Wiltshire <[email protected]> wrote:
> > Control: tag -1 confirmed

> > Hi,

> > d-i ack needed for the udeb but as far as I'm concerned please go ahead.

> I would like to amend this and add the fix for CVE-2026-24882, too.
[...]

Another revision, adding the fix for CVE-2026-105712.

cu Andreas
diff --git a/debian/changelog b/debian/changelog
index 786180728..54a21509a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,23 @@
+gnupg2 (2.4.7-21+deb13u2) trixie; urgency=medium
+
+  * Fix CVE-2026-57062.
+    CMS (Cryptographic Message Syntax) parsing in gpgsm in GnuPG through
+    2.5.20 mishandles the CMS format for AES-GCM because aes-ICVlen is
+    supposed to be 12 bytes but 4 bytes is accepted.
+  * Fix CVE-2026-24882: Stack-based buffer overflow in tpm2daemon during
+    handling of the PKDECRYPT command for TPM-backed RSA and ECC keys.
+  * Add upstream patchset for CVE-2026-105712.
+    gpgtar in GnuPG before 2.5.19 can allow file overwrite via crafted data
+    in an archive. When extracting an untrusted archive with --directory
+    (aka -C) into an existing directory containing a pre-existing symlink,
+    gpgtar can follow that symlink and create or overwrite a file outside
+    the selected extraction directory. The write is limited by the
+    extraction user's filesystem permissions. An archive extracted into a
+    fresh empty directory does not have this risk.
+    https://static.dev.gnupg.org/T8159.html (Closes: #1150168)
+
+ -- Andreas Metzler <[email protected]>  Sat, 17 Oct 2026 18:06:15 +0200
+
 gnupg2 (2.4.7-21+deb13u1) trixie; urgency=high
 
   * Avoid potential downgrade to SHA1 in 3rd party key signatures.
diff --git a/debian/patches/freepg/0050-tpm-Fix-possible-buffer-overflow-in-PKDECRYPT.patch b/debian/patches/freepg/0050-tpm-Fix-possible-buffer-overflow-in-PKDECRYPT.patch
new file mode 100644
index 000000000..dc952def2
--- /dev/null
+++ b/debian/patches/freepg/0050-tpm-Fix-possible-buffer-overflow-in-PKDECRYPT.patch
@@ -0,0 +1,65 @@
+From 01c130031806010f4c563694501e8739f1580228 Mon Sep 17 00:00:00 2001
+From: Werner Koch <[email protected]>
+Date: Mon, 26 Jan 2026 11:13:44 +0100
+Subject: tpm: Fix possible buffer overflow in PKDECRYPT
+
+* tpm2d/tpm2.c (tpm2_ecc_decrypt): Bail out on too long CIPHERTEXT.
+(tpm2_rsa_decrypt): Ditto.
+--
+
+Cherry pick master commit of:
+	93fa34d9a346020355cd51d54102d30d4f177323
+
+GnuPG-bug-id: 8045
+Co-authored-by: NIIBE Yutaka <[email protected]>
+Reported-by: OpenAI Security Research
+---
+ tpm2d/tpm2.c | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+diff --git a/tpm2d/tpm2.c b/tpm2d/tpm2.c
+index 3e908ddb1..cd0347c6e 100644
+--- a/tpm2d/tpm2.c
++++ b/tpm2d/tpm2.c
+@@ -917,10 +917,20 @@ tpm2_ecc_decrypt (ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key,
+   size_t len;
+   int ret;
+ 
++#if defined(TPM2_MAX_ECC_KEY_BYTES) /* Intel stack */
++  if (ciphertext_len > 2*TPM2_MAX_ECC_KEY_BYTES + 1)
++    return GPG_ERR_TOO_LARGE;
++#elif defined(MAX_ECC_KEY_BYTES)    /* IBM stack */
++  if (ciphertext_len > 2*MAX_ECC_KEY_BYTES + 1)
++    return GPG_ERR_TOO_LARGE;
++#else
++# error TMP2 header are not correctly installed
++#endif
++
+   /* This isn't really a decryption per se.  The ciphertext actually
+    * contains an EC Point which we must multiply by the private key number.
+    *
+-   * The reason is to generate a diffe helman agreement on a shared
++   * The reason is to generate a diffie-hellman agreement on a shared
+    * point.  This shared point is then used to generate the per
+    * session encryption key.
+    */
+@@ -976,6 +986,16 @@ tpm2_rsa_decrypt (ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key,
+   TPM_HANDLE ah;
+   char *auth;
+ 
++#if defined(TPM2_MAX_RSA_KEY_BYTES)  /* Intel stack */
++  if (ciphertext_len > TPM2_MAX_RSA_KEY_BYTES)
++    return GPG_ERR_TOO_LARGE;
++#elif defined(MAX_RSA_KEY_BYTES)     /* IBM stack */
++  if (ciphertext_len > MAX_RSA_KEY_BYTES)
++    return GPG_ERR_TOO_LARGE;
++#else
++# error TMP2 header are not correctly installed
++#endif
++
+   inScheme.scheme = TPM_ALG_RSAES;
+   /*
+    * apparent gcrypt error: occasionally rsa ciphertext will
+-- 
+2.39.5
+
diff --git a/debian/patches/freepg/0051-agent-Fix-the-regression-in-pkdecrypt-with-TPM-RSA.patch b/debian/patches/freepg/0051-agent-Fix-the-regression-in-pkdecrypt-with-TPM-RSA.patch
new file mode 100644
index 000000000..2277dcee3
--- /dev/null
+++ b/debian/patches/freepg/0051-agent-Fix-the-regression-in-pkdecrypt-with-TPM-RSA.patch
@@ -0,0 +1,42 @@
+From 555a9f5b3a0ca69e663373d47902e0bec0bd49d0 Mon Sep 17 00:00:00 2001
+From: NIIBE Yutaka <[email protected]>
+Date: Thu, 12 Feb 2026 11:51:17 +0900
+Subject: agent: Fix the regression in pkdecrypt with TPM RSA.
+
+* agent/divert-tpm2.c (divert_tpm2_pkdecrypt): Care about additional
+0x00.
+
+--
+
+Cherry pick master commit of:
+	6eed3959303c81c9699fe9273030e480732f72be
+
+GnuPG-bug-id: 8045
+Signed-off-by: NIIBE Yutaka <[email protected]>
+---
+ agent/divert-tpm2.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c
+index 2496d091a..5b5bd14bb 100644
+--- a/agent/divert-tpm2.c
++++ b/agent/divert-tpm2.c
+@@ -135,6 +135,15 @@ divert_tpm2_pkdecrypt (ctrl_t ctrl,
+       if (!smatch (&s, n, "a"))
+         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
+       n = snext (&s);
++      /* NOTE: gpg-agent protocol uses signed integer for RSA (%m in
++       * MPI), where 0x00 is added when the MSB is 1.  TPM2 uses
++       * unsigned integer.  We need to remove this 0x00, or else
++       * it may result GPG_ERR_TOO_LARGE in tpm2daemon.  */
++      if (!*s && (n&1))
++        {
++          s++;
++          n--;
++        }
+     }
+   else if (smatch (&s, n, "ecdh"))
+     {
+-- 
+2.39.5
+
diff --git a/debian/patches/from-master/0004-gpgsm-Require-a-minimum-tag-length-for-GCM-decryptio.patch b/debian/patches/from-master/0004-gpgsm-Require-a-minimum-tag-length-for-GCM-decryptio.patch
new file mode 100644
index 000000000..be629b0ee
--- /dev/null
+++ b/debian/patches/from-master/0004-gpgsm-Require-a-minimum-tag-length-for-GCM-decryptio.patch
@@ -0,0 +1,45 @@
+From 4c7e68cf3d335328821bdbb70db309a60d0e4fd4 Mon Sep 17 00:00:00 2001
+From: Werner Koch <[email protected]>
+Date: Thu, 18 Jun 2026 10:51:34 +0200
+Subject: [PATCH] gpgsm: Require a minimum tag length for GCM decryption.
+
+* sm/decrypt.c (gpgsm_decrypt): Require a minimum authtaglen.
+--
+
+Reported-by: Thai Duong <[email protected]>
+CVE-id: CVE-2026-57062
+---
+ sm/decrypt.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/sm/decrypt.c b/sm/decrypt.c
+index 20fb96060..92a33c6e6 100644
+--- a/sm/decrypt.c
++++ b/sm/decrypt.c
+@@ -1443,15 +1443,22 @@ gpgsm_decrypt (ctrl_t ctrl, estream_t in_fp, estream_t out_fp)
+               if (rc)
+                 {
+                   log_error ("error getting authtag: %s\n", gpg_strerror (rc));
+                   goto leave;
+                 }
+               if (DBG_CRYPTO)
+                 log_printhex (authtag, authtaglen, "Authtag ...:");
+-              rc = gcry_cipher_checktag (dfparm.hd, authtag, authtaglen);
++              if (authtaglen < 12)
++                {
++                  log_info ("authentication tag is too short (%zu octets)\n",
++                            authtaglen);
++                  rc = gpg_error (GPG_ERR_CHECKSUM);
++                }
++              else
++                rc = gcry_cipher_checktag (dfparm.hd, authtag, authtaglen);
+               xfree (authtag);
+               if (rc)
+                 log_error ("data is not authentic: %s\n", gpg_strerror (rc));
+               goto leave;
+             }
+         }
+     }
+-- 
+2.53.0
+
diff --git a/debian/patches/from-master/0009-tests-openpgp-With-gpgtar-extract-tarball-into-an-em.patch b/debian/patches/from-master/0009-tests-openpgp-With-gpgtar-extract-tarball-into-an-em.patch
new file mode 100644
index 000000000..037324da8
--- /dev/null
+++ b/debian/patches/from-master/0009-tests-openpgp-With-gpgtar-extract-tarball-into-an-em.patch
@@ -0,0 +1,49 @@
+From 268e435f921a834909429063ea656186266a0f85 Mon Sep 17 00:00:00 2001
+From: NIIBE Yutaka <[email protected]>
+Date: Wed, 18 Mar 2026 16:07:44 +0900
+Subject: [PATCH] tests:openpgp: With gpgtar, extract tarball into an empty
+ directory.
+
+* tests/openpgp/defs.scm (setup-legacy-environment): Only
+call create-gpghome in case of no --unpack-tarball.
+
+--
+
+At the tarball creation by setup.scm, it calls create-gpghome.  So,
+it's not needed in case of --unpack-tarball.
+
+GnuPG-bug-id: 8159
+Signed-off-by: NIIBE Yutaka <[email protected]>
+---
+ tests/openpgp/defs.scm | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tests/openpgp/defs.scm b/tests/openpgp/defs.scm
+index 686439a36..c3b05ddb7 100644
+--- a/tests/openpgp/defs.scm
++++ b/tests/openpgp/defs.scm
+@@ -460,20 +460,20 @@
+   (call-check `(,(tool 'gpg-preset-passphrase)
+ 		--preset --passphrase abc
+ 		"A0747D5F9425E6664F4FFBEED20FBCA79FDED2BD")))
+ 
+ ;; Initialize the test environment, install appropriate configuration
+ ;; and start the agent, with the keys from the legacy test suite.
+ (define (setup-legacy-environment)
+-  (create-gpghome)
+   (if (member "--unpack-tarball" *args*)
+       (begin
+ 	(call-check `(,(tool 'gpgtar) --extract --directory=. ,(cadr *args*)))
+ 	(start-agent))
+       (begin
++        (create-gpghome)
+ 	(start-agent)
+ 	(create-legacy-gpghome)))
+   (preset-passphrases))
+ 
+ ;; Create the socket dir and start the agent.
+ (define (start-agent . args)
+   (log "Starting gpg-agent...")
+-- 
+2.53.0
+
diff --git a/debian/patches/from-master/0010-tool-gpgtar-Check-the-output-directory-with-director.patch b/debian/patches/from-master/0010-tool-gpgtar-Check-the-output-directory-with-director.patch
new file mode 100644
index 000000000..24e7c2889
--- /dev/null
+++ b/debian/patches/from-master/0010-tool-gpgtar-Check-the-output-directory-with-director.patch
@@ -0,0 +1,200 @@
+From 7a2692fe5e580ae3bbb2a47abc4baaf1af65aa88 Mon Sep 17 00:00:00 2001
+From: NIIBE Yutaka <[email protected]>
+Date: Fri, 20 Mar 2026 13:33:00 +0900
+Subject: [PATCH] tool:gpgtar: Check the output directory with --directory.
+
+* doc/tools.texi (gpgtar): Clarify about the --directory option.
+* tools/gpgtar-extract.c (check_output_directory): New.
+(gpgtar_extract): Call check_output_directory.
+
+--
+
+GnuPG-bug-id: 8159
+Signed-off-by: NIIBE Yutaka <[email protected]>
+---
+ doc/tools.texi         |  11 ++--
+ tools/gpgtar-extract.c | 123 ++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 128 insertions(+), 6 deletions(-)
+
+--- a/doc/tools.texi
++++ b/doc/tools.texi
+@@ -2014,15 +2014,16 @@ archives.
+ Do not actually output the extracted files.
+ 
+ @item --directory @var{dir}
+ @itemx -C @var{dir}
+ @opindex directory
+-Extract the files into the directory @var{dir}.  The default is to
+-take the directory name from the input filename.  If no input filename
+-is known a directory named @file{GPGARCH} is used.  For tarball
+-creation, switch to directory @var{dir} before performing any
+-operations.
++Extract the files into the directory @var{dir}.  It raises an error
++when @var{dir} is not empty, or @var{dir} is a symlink to other
++directory.  When this option is not given, the default is to take the
++directory name from the input filename.  If no input filename is known
++a directory, named @file{GPGARCH} is used.  For tarball creation,
++switch to directory @var{dir} before performing any operations.
+ 
+ @item --files-from @var{file}
+ @itemx -T @var{file}
+ Take the file names to work from the file @var{file}; one file per
+ line.
+--- a/tools/gpgtar-extract.c
++++ b/tools/gpgtar-extract.c
+@@ -22,10 +22,12 @@
+ 
+ #include <config.h>
+ #include <errno.h>
+ #include <stdio.h>
+ #include <stdlib.h>
++#include <dirent.h>
++#include <fcntl.h>
+ #include <string.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ 
+@@ -368,10 +370,116 @@ create_directory (const char *dirprefix)
+   xfree (prefix_buffer);
+   return dirname;
+ }
+ 
+ 
++/* Check the output directory DIRNAME if it's not symlink and empty.
++   Return 1 if good, 0 otherwise.  */
++static int
++check_output_directory (const char *dirname)
++{
++#ifdef HAVE_W32_SYSTEM
++#define dirent _wdirent
++#define DIR _WDIR
++#define readdir _wreaddir
++#define closedir _wclosedir
++#endif
++  DIR *d;
++  struct dirent *dent;
++  int count = 0;
++
++#ifdef HAVE_W32_SYSTEM
++  wchar_t *wdirname;
++  DWORD attr;
++
++  wdirname = utf8_to_wchar (dirname);
++  if (!wdirname)
++    return 0;
++
++  attr = GetFileAttributesW (wdirname);
++
++  if (attr == INVALID_FILE_ATTRIBUTES)
++    {
++      log_error ("error getting attributes '%s': %s\n", dirname, w32_strerror (-1));
++      xfree (wdirname);
++      return 0;
++    }
++  else if ((attr & FILE_ATTRIBUTE_REPARSE_POINT))
++    {
++      /* It's reparse point (possibly symlink), not good.  */
++      log_error ("Not a regular directory (may be symlink): %s\n", dirname);
++      xfree (wdirname);
++      return 0;
++    }
++
++  d = _wopendir (wdirname);
++  xfree (wdirname);
++#else
++# if O_NOFOLLOW == 0
++  struct stat sbuf;
++
++  if (lstat (dirname, &sbuf))
++    return 0;
++
++  if (S_ISLNK (sbuf.st_mode))
++    {
++      /* It's symlink, not good.  */
++      log_error ("It's symbolic link: %s\n", dirname);
++      return 0;
++    }
++
++  d = opendir (dirname);
++# else
++  int fd;
++
++  /* With O_NOFOLLOW, make sure it's not symlink.  */
++  fd = open (dirname, (O_RDONLY | O_NOFOLLOW));
++  if (fd < 0)
++    {
++      log_error ("Can't open (symlink?): %s\n", dirname);
++      return 0;
++    }
++
++  d = fdopendir (fd);
++# endif
++#endif
++
++  if (d == NULL)
++    return 0;
++
++  while ((dent = readdir (d)) != NULL)
++    {
++      if (dent->d_name[0] == '.' && dent->d_name[1] == 0)
++        continue;
++
++      if (dent->d_name[0] == '.' && dent->d_name[1] == '.'
++          && dent->d_name[2] == 0)
++        continue;
++
++      count++;
++    }
++
++  /* In case of fdopendir, FD is released by closedir. */
++  closedir (d);
++
++  if (count)
++    {
++      /* It's not empty, not good.  */
++      log_error ("Directory not empty: %s\n", dirname);
++      return 0;
++    }
++
++  /* Good.  */
++  return 1;
++}
++
++#ifdef HAVE_W32_SYSTEM
++#undef dirent
++#undef DIR
++#undef readdir
++#undef closedir
++#endif
+ 
+ gpg_error_t
+ gpgtar_extract (const char *filename, int decrypt)
+ {
+   gpg_error_t err;
+@@ -387,11 +495,24 @@ gpgtar_extract (const char *filename, in
+   unsigned long long notextracted;
+ 
+   memset (&tarinfo_buffer, 0, sizeof tarinfo_buffer);
+ 
+   if (opt.directory)
+-    dirname = xtrystrdup (opt.directory);
++    {
++      dirname = xtrystrdup (opt.directory);
++      if (!dirname)
++        {
++          err = gpg_error_from_syserror ();
++          goto leave;
++        }
++
++      if (!check_output_directory (dirname))
++        {
++          err = gpg_error (GPG_ERR_INV_ARG);
++          goto leave;
++        }
++    }
+   else
+     {
+       if (opt.filename)
+         {
+           dirprefix = strrchr (opt.filename, '/');
diff --git a/debian/patches/from-master/0011-gpgtar-Add-compatibility-flag-no-dir-check.patch b/debian/patches/from-master/0011-gpgtar-Add-compatibility-flag-no-dir-check.patch
new file mode 100644
index 000000000..b9b753d8c
--- /dev/null
+++ b/debian/patches/from-master/0011-gpgtar-Add-compatibility-flag-no-dir-check.patch
@@ -0,0 +1,182 @@
+From 86020945ce1564a7f6cfa6a18ea8dcdca5e19baf Mon Sep 17 00:00:00 2001
+From: Werner Koch <[email protected]>
+Date: Thu, 9 Apr 2026 09:17:52 +0200
+Subject: [PATCH] gpgtar: Add --compatibility-flag  no-dir-check
+
+* tools/gpgtar.c (oCompatibilityFlags): New.
+(opts): Add "compatibility-flags".
+(compatibility_flags): New.
+(parse_arguments): Parse it.
+* tools/gpgtar.h (opt): Add field compat_flags.
+(COMPAT_NO_DIR_CHECK): New.
+* tools/gpgtar-extract.c (gpgtar_extract): No directory check if
+  COMPAT_NO_DIR_CHECK is set.
+--
+
+GnuPG-bug-id: 8159
+---
+ tools/gpgtar-extract.c |  3 ++-
+ tools/gpgtar.c         | 23 ++++++++++++++++++++++-
+ tools/gpgtar.h         |  8 ++++++++
+ 3 files changed, 32 insertions(+), 2 deletions(-)
+
+--- a/tools/gpgtar-extract.c
++++ b/tools/gpgtar-extract.c
+@@ -501,15 +501,16 @@ gpgtar_extract (const char *filename, in
+       dirname = xtrystrdup (opt.directory);
+       if (!dirname)
+         {
+           err = gpg_error_from_syserror ();
+           goto leave;
+         }
+ 
+-      if (!check_output_directory (dirname))
++      if (!(opt.compat_flags & COMPAT_NO_DIR_CHECK)
++          && !check_output_directory (dirname))
+         {
+           err = gpg_error (GPG_ERR_INV_ARG);
+           goto leave;
+         }
+     }
+   else
+     {
+--- a/tools/gpgtar.c
++++ b/tools/gpgtar.c
+@@ -80,14 +80,15 @@ enum cmd_and_opt_values
+ 
+     oBatch,
+     oAnswerYes,
+     oAnswerNo,
+     oStatusFD,
+     oRequireCompliance,
+     oWithLog,
++    oCompatibilityFlags,
+ 
+     /* Compatibility with gpg-zip.  */
+     oGpgArgs,
+     oTarArgs,
+     oTarProgram,
+ 
+     /* Debugging.  */
+@@ -126,14 +127,15 @@ static gpgrt_opt_t opts[] = {
+ 
+   ARGPARSE_s_n (oBatch, "batch", "@"),
+   ARGPARSE_s_n (oAnswerYes, "yes", "@"),
+   ARGPARSE_s_n (oAnswerNo, "no", "@"),
+   ARGPARSE_s_i (oStatusFD, "status-fd", "@"),
+   ARGPARSE_s_n (oRequireCompliance, "require-compliance", "@"),
+   ARGPARSE_s_n (oWithLog, "with-log", "@"),
++  ARGPARSE_s_s (oCompatibilityFlags, "compatibility-flags", "@"),
+ 
+   ARGPARSE_group (302, N_("@\nTar options:\n ")),
+ 
+   ARGPARSE_s_s (oDirectory, "directory",
+                 N_("|DIRECTORY|change to DIRECTORY first")),
+   ARGPARSE_s_s (oFilesFrom, "files-from",
+                 N_("|FILE|get names to create from FILE")),
+@@ -163,14 +165,24 @@ static gpgrt_opt_t tar_opts[] = {
+                 N_("|FILE|get names to create from FILE")),
+   ARGPARSE_s_n (oNull, "null", N_("-T reads null-terminated names")),
+ 
+   ARGPARSE_end ()
+ };
+ 
+ 
++/* The list of compatibility flags.  */
++static struct compatibility_flags_s compatibility_flags [] =
++  {
++    { COMPAT_NO_DIR_CHECK, "no-dir-check" },
++    { 0, NULL }
++  };
++
++
++
++
+ /* Global flags.  */
+ static enum cmd_and_opt_values cmd = 0;
+ static int skip_crypto = 0;
+ static const char *files_from = NULL;
+ static int null_names = 0;
+ static int any_debug;
+ 
+@@ -398,14 +410,23 @@ parse_arguments (gpgrt_argparse_t *pargs
+         case oBatch: opt.batch = 1; break;
+         case oAnswerYes: opt.answer_yes = 1; break;
+         case oAnswerNo: opt.answer_no = 1; break;
+         case oStatusFD: opt.status_fd = pargs->r.ret_int; break;
+         case oRequireCompliance: opt.require_compliance = 1; break;
+         case oWithLog: opt.with_log = 1; break;
+ 
++        case oCompatibilityFlags:
++          if (parse_compatibility_flags (pargs->r.ret_str, &opt.compat_flags,
++                                         compatibility_flags))
++            {
++              pargs->r_opt = ARGPARSE_INVALID_ARG;
++              pargs->err = ARGPARSE_PRINT_ERROR;
++            }
++          break;
++
+         case oGpgArgs:;
+           {
+             strlist_t list;
+             if (shell_parse_stringlist (pargs->r.ret_str, &list))
+               log_error ("failed to parse gpg arguments '%s'\n",
+                          pargs->r.ret_str);
+             else
+@@ -449,15 +470,15 @@ parse_arguments (gpgrt_argparse_t *pargs
+           any_debug = 1;
+           break;
+ 
+         case oDryRun:
+           opt.dry_run = 1;
+           break;
+ 
+-        default: pargs->err = 2; break;
++        default: pargs->err = ARGPARSE_PRINT_ERROR; break;
+ 	}
+     }
+ }
+ 
+ 
+ 
+ /* gpgtar main. */
+--- a/tools/gpgtar.h
++++ b/tools/gpgtar.h
+@@ -45,14 +45,16 @@ struct
+   int batch;
+   int answer_yes;
+   int answer_no;
+   int status_fd;
+   estream_t status_stream;
+   int require_compliance;
+   int with_log;
++  /* Compatibility flags (COMPAT_FLAG_xxxx).  */
++  unsigned int compat_flags;
+ } opt;
+ 
+ 
+ /* An info structure to avoid global variables.  */
+ struct tarinfo_s
+ {
+   unsigned long long nblocks;     /* Count of processed blocks.      */
+@@ -138,14 +140,20 @@ struct tar_header_s
+ 
+   unsigned long long nrecords; /* Number of data records.  */
+ 
+   char name[1];             /* Filename (UTF-8, dynamically extended).  */
+ };
+ 
+ 
++/* Compatibility flags */
++/* When using -C on extract the specified directory is checked to be
++ * empty and not be a symlink.  This flag disables the check.  */
++#define COMPAT_NO_DIR_CHECK  1
++
++
+ /*-- gpgtar.c --*/
+ gpg_error_t read_record (estream_t stream, void *record);
+ gpg_error_t write_record (estream_t stream, const void *record);
+ 
+ /*-- gpgtar-create.c --*/
+ gpg_error_t gpgtar_create (char **inpattern, const char *files_from,
+                            int null_names, int encrypt, int sign);
diff --git a/debian/patches/from-master/0012-tools-gpgtar-Fix-for-a-case-of-non-existing-dir-with.patch b/debian/patches/from-master/0012-tools-gpgtar-Fix-for-a-case-of-non-existing-dir-with.patch
new file mode 100644
index 000000000..78b1c6070
--- /dev/null
+++ b/debian/patches/from-master/0012-tools-gpgtar-Fix-for-a-case-of-non-existing-dir-with.patch
@@ -0,0 +1,39 @@
+From 1bdd1f5bb4d192d9700dd6ab2540b0a940c23dd5 Mon Sep 17 00:00:00 2001
+From: NIIBE Yutaka <[email protected]>
+Date: Tue, 14 Apr 2026 13:32:00 +0900
+Subject: [PATCH] tools:gpgtar: Fix for a case of non existing dir with -C.
+
+* tools/gpgtar-extract.c (gpgtar_extract): Call the
+check_output_directory function only when DIRNAME exists.
+
+--
+
+GnuPG-bug-id: 8159
+Signed-off-by: NIIBE Yutaka <[email protected]>
+---
+ tools/gpgtar-extract.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c
+index d6be9df5e..72c79ce1b 100644
+--- a/tools/gpgtar-extract.c
++++ b/tools/gpgtar-extract.c
+@@ -501,14 +501,15 @@ gpgtar_extract (const char *filename, int decrypt)
+       if (!dirname)
+         {
+           err = gpg_error_from_syserror ();
+           goto leave;
+         }
+ 
+       if (!(opt.compat_flags & COMPAT_NO_DIR_CHECK)
++          && gnupg_access (dirname, F_OK) == 0
+           && !check_output_directory (dirname))
+         {
+           err = gpg_error (GPG_ERR_INV_ARG);
+           goto leave;
+         }
+     }
+   else
+-- 
+2.53.0
+
diff --git a/debian/patches/series b/debian/patches/series
index 3b42e1375..c493962d3 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -20,6 +20,8 @@ freepg/0026-gpg-Default-to-compliance-openpgp.patch
 freepg/0029-Add-keyboxd-systemd-support.patch
 freepg/0033-Support-large-RSA-keygen-in-non-batch-mode.patch
 freepg/0034-gpg-Verify-Text-mode-Signatures-over-binary-Literal-.patch
+freepg/0050-tpm-Fix-possible-buffer-overflow-in-PKDECRYPT.patch
+freepg/0051-agent-Fix-the-regression-in-pkdecrypt-with-TPM-RSA.patch
 debian-packaging/avoid-beta-warning.patch
 debian-packaging/avoid-regenerating-defsincdate-use-shipped-file.patch
 dirmngr-idling/dirmngr-hkp-Avoid-potential-race-condition-when-some.patch
@@ -36,6 +38,7 @@ from-master/gpg-agent-idling/0007-agent-Fix-the-previous-commit.patch
 from-master/gpg-agent-idling/0008-agent-Fix-timer-list-management.patch
 from-master/gpg-agent-idling/0009-agent-Fix-sock_inotify_fd-handling.patch
 from-master/gpg-agent-idling/0010-agent-Fix-timer-round-up-check-when-inserting-an-ent.patch
+from-master/0004-gpgsm-Require-a-minimum-tag-length-for-GCM-decryptio.patch
 Use-hkps-keys.openpgp.org-as-the-default-keyserver.patch
 debian-packaging/Build-regexp-against-debian-s-unicode-data-package.patch
 debian-packaging/Always-build-common-status-codes.h-and-common-audit-event.patch
@@ -59,3 +62,7 @@ gpg-Avoid-potential-downgrade-to-SHA1-in-3rd-party-k.patch
 gpg-Error-out-on-unverified-output-for-non-detached-.patch
 gpg-Fix-possible-memory-corruption-in-the-armor-pars.patch
 from-master/gpg-Do-not-use-a-default-when-asking-for-another-out.patch
+from-master/0009-tests-openpgp-With-gpgtar-extract-tarball-into-an-em.patch
+from-master/0010-tool-gpgtar-Check-the-output-directory-with-director.patch
+from-master/0011-gpgtar-Add-compatibility-flag-no-dir-check.patch
+from-master/0012-tools-gpgtar-Fix-for-a-case-of-non-existing-dir-with.patch

Reply via email to