GnuPG: Segfaults trying to encrypt / locate by mbox for specific keys
Open, HighPublic


Both with GnuPG 2.3 from our packages and latest stable branch GnuPG crashes pretty reliably for me if I search for "foo@bar.baz" a user id I often use for testing. It is reproducible if you import the keys at the bottom of this message. Please try several times if it does not crash for you immediately. I have not tested on different systems. Base system is debian stretch. Libgcrypt is also latest master.

Full testblock with 12 keys:

Minimal testblock with 3 keys:

After import run:

gpg --homedir=$HOMEDIR -er foo@bar.baz

This can result in free errors, segfaults, output that looks like random memory. Most often it runs into an assert though:

gpg: keybox '/tmp/tmp.rM96opTZ6a/pubring.kbx' created
gpg: /tmp/tmp.rM96opTZ6a/trustdb.gpg: trustdb created
gpg: key 2D6B40CF5FC72C19: public key "test test again kleo (asd) <foo@bar.baz>" imported
gpg: key E0B024EEFDAA15EE: public key "foo@bar.baz" imported
gpg: key 7A6BC11AA5030C21: public key "foo@bar.baz22423" imported
gpg: Total number processed: 3
gpg:               imported: 3
gpg: It is only intended for test purposes and should NOT be
gpg: used in a production environment or with production keys!
gpg: Ohhhh jeeee: Assertion "uid->ref > 0" in free_user_id failed (../../../src/gnupg/g10/free-packet.c:321)

I have tried to minimize my example keyset. If I leave any one of the three keys out the crashes no longer happen. But to me it appears that the more keys for a userid there are the more likely it is to run into this error. So I've attached both the minimal keyblock and my full keyblock for "foo@bar.baz"

Here are some errors:

gpg: E1F4F6E8B72FAA47: There is no assurance this key belongs to the named user

sub  brainpoolP256r1/E1F4F6E8B72FAA47 2016-08-25 \xf0\xc3K\xf9\x1eV\0\0\xa0\xc3\x4b\xf9\x1eV\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc0\xe3K\xf9\x1eV\0\0 \xd1\xe3W\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\x09\0\0\0\0\0\0\0\0\0\0\0foo2@bar.baz\0\0\0\0\x90\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\xa0\xc3\x4b\xf9\x1eV\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc1\x00\0\0\0\0\0\0@\xb2K\xf9\x1eV\0\0\xb0\xe2\x4b\xf9\x1eV\0\0\0\0\0\0
gpg: malloc.c:2406: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
[1]    338 abort      gpg -er foo@bar.baz
*** Error in `gpg': free(): invalid next size (normal): 0x000056373254a4c0 ***
aheinecke renamed this task from GnuPG: Segfaults trying to encrypt / locate by mbox to GnuPG: Segfaults trying to encrypt / locate by mbox for specific keys.Apr 18 2019, 12:04 PM

I have a fix. I'll commit it later.

FWIW, with 4a130bbc2c2f4be6e8c6357512a943f435ade28f I fixed a similar report by @syscomet but lacking a test case this was a blind flight ("This patch is not tested but a good guess."). Thanks for tracking it down.