[Bug 2067089] Re: GnuPG gpg-agent KEYTOCARD Invalid time (memory overwritten)
Steven Chou
2067089 at bugs.launchpad.net
Fri May 24 16:23:06 UTC 2024
** Information type changed from Private Security to Public
--
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to gnupg2 in Ubuntu.
https://bugs.launchpad.net/bugs/2067089
Title:
GnuPG gpg-agent KEYTOCARD Invalid time (memory overwritten)
Status in gnupg2 package in Ubuntu:
New
Bug description:
OS: Ubuntu 24.04 LTS
HW: Raspberry Pi Arm64
Related packages:
- gnupg2 2.4.4-2ubuntu17
- libassuan0:arm64 2.5.6-1build1
When I am trying to fully generate and transfer a new set of GPG
private keys to my new YubiKey 5 security key, following this guide:
https://github.com/drduh/YubiKey-Guide. I encountered bellow error
when running `gpg --pinentry-mode=loopback --edit-key ${KEYID}` with
the `keytocard`command:
```
gpg: KEYTOCARD failed: Invalid time
```
After some digging around, attaching gdb to the running `gpg-agent`
process. I found that after the function call to `agent_key_from_file`
from `gnupg/agent/command.c:3278`, which communicated the client and
acquired master certify key passphrase, the memory used by `argv`
variable in `cmd_keytocard` function has been wiped to zeros. This
caused later usage of the variable to fail, resulted in a timestamp
conversion error with code `GPG_ERR_INV_TIME`.
```
(gdb) bt
#0 agent_key_from_file (ctrl=0xaaab192410e0, cache_nonce=0x0, desc_text=0x0,
grip=0xffff8440e740 "__________________________________________________________________",
shadow_info=0xffff8440e6d0, cache_mode=CACHE_MODE_IGNORE, lookup_ttl=0x0, result=0xffff8440e6d8, r_passphrase=0x0,
r_timestamp=0xffff8440e6c8) at ../../agent/findkey.c:1368
#1 0x0000aaaae369a538 in cmd_keytocard (ctx=0xffff7c027b40, line=<optimized out>) at ../../agent/command.c:3278
#2 0x0000ffff8471a288 in dispatch_command (ctx=ctx at entry=0xffff7c027b40,
line=0xffff7c027c9a "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", line at entry=0xffff7c027c90 "KEYTOCARD",
linelen=<optimized out>) at ../../src/assuan-handler.c:676
#3 0x0000ffff8471a8e0 in process_request (ctx=0xffff7c027b40) at ../../src/assuan-handler.c:872
#4 assuan_process (ctx=0xffff7c027b40) at ../../src/assuan-handler.c:895
#5 0x0000aaaae36bcfb8 in start_command_handler.constprop.0 (ctrl=ctrl at entry=0xaaab192410e0, fd=11, listen_fd=-1)
at ../../agent/command.c:4460
#6 0x0000aaaae368da70 in do_start_connection_thread (ctrl=0xaaab192410e0) at ../../agent/gpg-agent.c:2860
#7 0x0000ffff846e1bf4 in thread_start (startup_arg=<optimized out>) at ../../src/npth.c:306
#8 0x0000ffff8455597c in start_thread (arg=0xffff84893080) at ./nptl/pthread_create.c:447
#9 0x0000ffff845bba4c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/clone3.S:76
(gdb) frame 1
#1 0x0000aaaae369a538 in cmd_keytocard (ctx=0xffff7c027b40, line=<optimized out>) at ../../agent/command.c:3278
3278 err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
(gdb) p argv
$16 = {0xffff7c027c9a "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 0xffff7c027cc3 "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
0xffff7c027ce4 "OPENPGP.1", 0xffff7c027cee "20240524T123456", 0xaaaae36c6a80 "Assuan processing failed: %s\n"}
(gdb) watch *0xffff7c027c9a
Hardware watchpoint 9: *0xffff7c027c9a
(gdb) c
Continuing.
Downloading source file /build/libassuan-Uieq6Z/libassuan-2.5.6/build/src/../../src/assuan-inquire.c
Thread 2 "gpg-agent" hit Hardware watchpoint 9: *0xffff7c027c9a
Old value = 111111111
New value = 222222222
0x0000ffff8471afd4 in assuan_inquire (ctx=ctx at entry=0xffff7c027b40, keyword=keyword at entry=0xaaaae36c2820 "PASSPHRASE",
r_buffer=r_buffer at entry=0xffff8440dff8, r_length=r_length at entry=0xffff8440dff0, maxlen=maxlen at entry=255)
at ../../src/assuan-inquire.c:263
263 wipememory (ctx->inbound.line, LINELENGTH);
(gdb) bt
#0 0x0000ffff8471afd4 in assuan_inquire (ctx=ctx at entry=0xffff7c027b40,
keyword=keyword at entry=0xaaaae36c2820 "PASSPHRASE", r_buffer=r_buffer at entry=0xffff8440dff8,
r_length=r_length at entry=0xffff8440dff0, maxlen=maxlen at entry=255) at ../../src/assuan-inquire.c:263
#1 0x0000aaaae36a1e2c in pinentry_loopback (ctrl=0xff, max_length=255, size=0xffff8440dff0, buffer=0xffff8440dff8,
keyword=0xaaaae36c2820 "PASSPHRASE") at ../../agent/command.c:4507
#2 agent_askpin (ctrl=ctrl at entry=0xaaab192410e0, desc_text=desc_text at entry=0x0, prompt_text=prompt_text at entry=0x0,
initial_errtext=initial_errtext at entry=0x0, pininfo=pininfo at entry=0xffff844677d0,
keyinfo=keyinfo at entry=0xffff8440e538 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
cache_mode=cache_mode at entry=CACHE_MODE_IGNORE) at ../../agent/call-pinentry.c:1453
#3 0x0000aaaae36aa2f0 in agent_askpin (cache_mode=CACHE_MODE_IGNORE,
keyinfo=0xffff8440e538 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", pininfo=0xffff844677d0, initial_errtext=0x0,
prompt_text=0x0, desc_text=0x0, ctrl=0xaaab192410e0) at ../../agent/call-pinentry.c:1440
#4 unprotect (r_passphrase=0x0, lookup_ttl=0x0, cache_mode=CACHE_MODE_IGNORE, grip=<optimized out>,
keybuf=0xffff8440e4d0, desc_text=0x0, cache_nonce=0x0, ctrl=0xaaab192410e0) at ../../agent/findkey.c:959
#5 agent_key_from_file (ctrl=0xaaab192410e0, cache_nonce=0x0, desc_text=<optimized out>, grip=<optimized out>,
shadow_info=<optimized out>, cache_mode=CACHE_MODE_IGNORE, lookup_ttl=0x0, result=0xffff8440e6d8,
r_passphrase=0x0, r_timestamp=0xffff8440e6c8) at ../../agent/findkey.c:1520
#6 0x0000aaaae369a538 in cmd_keytocard (ctx=0xffff7c027b40, line=<optimized out>) at ../../agent/command.c:3278
#7 0x0000ffff8471a288 in dispatch_command (ctx=ctx at entry=0xffff7c027b40, line=0xffff7c027c9a "",
line at entry=0xffff7c027c90 "", linelen=<optimized out>) at ../../src/assuan-handler.c:676
#8 0x0000ffff8471a8e0 in process_request (ctx=0xffff7c027b40) at ../../src/assuan-handler.c:872
#9 assuan_process (ctx=0xffff7c027b40) at ../../src/assuan-handler.c:895
#10 0x0000aaaae36bcfb8 in start_command_handler.constprop.0 (ctrl=ctrl at entry=0xaaab192410e0, fd=11, listen_fd=-1)
at ../../agent/command.c:4460
#11 0x0000aaaae368da70 in do_start_connection_thread (ctrl=0xaaab192410e0) at ../../agent/gpg-agent.c:2860
#12 0x0000ffff846e1bf4 in thread_start (startup_arg=<optimized out>) at ../../src/npth.c:306
#13 0x0000ffff8455597c in start_thread (arg=0xffff84893080) at ./nptl/pthread_create.c:447
#14 0x0000ffff845bba4c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/clone3.S:76
(gdb) frame 6
#6 0x0000aaaae369a538 in cmd_keytocard (ctx=0xffff7c027b40, line=<optimized out>) at ../../agent/command.c:3278
3278 err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
(gdb) p argv
$17 = {0xffff7c027c9a "", 0xffff7c027cc3 "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY", 0xffff7c027ce4 "OPENPGP.1",
0xffff7c027cee "20240524T123456", 0xaaaae36c6a80 "Assuan processing failed: %s\n"}
(gdb) frame 0
#0 0x0000ffff8471afd4 in assuan_inquire (ctx=ctx at entry=0xffff7c027b40,
keyword=keyword at entry=0xaaaae36c2820 "PASSPHRASE", r_buffer=r_buffer at entry=0xffff8440dff8,
r_length=r_length at entry=0xffff8440dff0, maxlen=maxlen at entry=255) at ../../src/assuan-inquire.c:263
263 wipememory (ctx->inbound.line, LINELENGTH);
(gdb) p ctx->inbound.line
$18 = '\000' <repeats 11 times>, "AAAAAAAAAAAAAAAAAAAA\000END\nXXXXXXXXXXXXXX\000YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY\000OPENPGP.1\00020240524T123456", '\000' <repeats 892 times>
```
I can see from the last print result, the passphrase (AAA...) from the
client is already overwritten part of the Key ID (XXX...) in the same
line buffer. The `argv` variable in the context of the `cmd_keytocard`
function is also using the same underlying buffer. I have no in-depth
knowledge of how GnuPG is implemented. It seems to be either the
gnupg2 or libassuan0 issue, possibly also related to `--pinentry-
mode=loopback`. Hope someone can classify this bug properly and help
fix it for good. Thanks.
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/gnupg2/+bug/2067089/+subscriptions
More information about the foundations-bugs
mailing list