Page MenuHome GnuPG

FIPS-enabled libgcrypt traps gnome-keyring daemon in an infinite loop
Closed, ResolvedPublic


When a user logs in via gdm on a FIPS-enabled system, gnome keyring daemon gets stuck in an infinite loop, which prevents successful login.
Tested with gkd 3.20.0 and libgcrypt 1.8.1.

Here's what happens:

libgcrypt gets initialized by gkd's egg_libgcrypt_initialize().
_gcry_rndlinux_gather_random opens /dev/random and stores the file descriptor to a static variable fd_random.

To become a daemon, gnome keyring performs a double fork and later does a descriptor cleanup in redirect_fds_after_fork(), which reopens /dev/null over descriptors 0-2.

Descriptor 2 before gkd's redirect_fds_after_fork():

# ls -l  /proc/10049/fd/2
lr-x------ 1 test users 64 19. říj 17.38 /proc/10049/fd/2 -> /dev/random


# ls -l  /proc/10049/fd/2
lr-x------ 1 test users 64 19. říj 17.38 /proc/10049/fd/2 -> /dev/null

libgcrypt however still believes that descriptor 2 points to the random device, so when _gcry_rndlinux_gather_random() is invoked again, it repeatedly read()s 0 byte blocks from the descriptor, creating an infinite loop.

This bug manifests itself only in FIPS mode, because DRBG gets fully seeded on initialization, whereas CSPRNG doesn't do a full initialization, so _gcry_rndlinux_gather_random doesn't get called before the descriptors are cleared.

I reported this also against gnome-keyring, because it looks it should rather be fixed on the gnome-keyring side.



Event Timeline

Right, we can't do anything in Libgcrypt except for adding a way to return the open fds. This is the usual problem with libraries and the required closing of fds before an exec. Anyway the FIPS mode is questionable because it has not been adjusted for many years and does not take account newer requirements.

FIPS rules changed anyway and thus more rework will be needed anyway. I keep this open at low priorirty.

werner claimed this task.

Fixed in master and 1.8 by detecting a fork and re-opening the devices