[PATCH] agent: Fix not using cache for pinentry loopback

Waqar Hameed whame at whame.dev
Fri May 8 17:07:09 CEST 2026


* agent/command.c (cmd_get_passphrase): Use a local copy of cacheid.
--

Using the passphrase cache with pinentry loopback mode doesn't work.
This is due to `cacheid` being wiped by
`assuan_begin/end_confidential()` in `pinentry_loopback()`. This results
in calling `agent_put_cache()` with `cacheid` pointing to a buffer with
all zeros (and thus an empty string).

Fix this by making a local copy of `cacheid` before calling
`agent_get_passphrase()`. This way `cacheid` is guaranteed to point to
valid (untouched) data both during cache look up and update.

Signed-off-by: Waqar Hameed <whame at whame.dev>
---
This was working fine on my Debian 12 system (gpg version 2.2.40) and
broke when upgrading to Ubuntu 24.04 (gpg version 2.4.4). I haven't done
a git bisect to really understand how/when this occurred (mostly due to
difficulties building with different versions of the dependency
libraries). 

Also, a search on the internet reveals that many others have reported
this in various forums. As far as I can see no one really fixed this for
all these years. It got too annoying for me, I had to roll up my
sleeves and debug it myself :)

 agent/command.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/agent/command.c b/agent/command.c
index 21c95203c..644c30672 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -2023,8 +2023,8 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
   char *pw;
   char *response = NULL;
   char *response2 = NULL;
-  char *cacheid = NULL;  /* May point into LINE.  */
-  char *desc = NULL;     /* Ditto  */
+  char *cacheid = NULL;
+  char *desc = NULL;     /* May point into LINE.  */
   char *prompt = NULL;   /* Ditto  */
   char *errtext = NULL;  /* Ditto  */
   const char *desc2 = _("Please re-enter this passphrase");
@@ -2088,6 +2088,8 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
    * the cache.  */
   if (ctrl->restricted || !strcmp (cacheid, "X"))
     cacheid = NULL;
+  else
+    cacheid = xstrdup(cacheid);
   if (!strcmp (errtext, "X"))
     errtext = NULL;
   if (!strcmp (prompt, "X"))
@@ -2282,6 +2284,7 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
   xfree (entry_errtext);
   xfree (pi2);
   xfree (pi);
+  xfree (cacheid);
   return leave_cmd (ctx, rc);
 }
 
-- 
2.43.0





More information about the Gnupg-devel mailing list