Page MenuHome GnuPG

Gpg-agent gets confused when a homedir is moved
Closed, WontfixPublic

Description

{F1822230}This might be on the border line between a bug and an enhancement request. Retag if desired.

We have been hit by the gpg-agent ending up in somewhat of an inconsistent state after the homedir had been moved. This happens in our build process, but I've attached a transcript illustrating the problem in a simplified way in an attachment. What happens is essentially.

  1. A GnuPG homedir is extracted from a tar file. This was created by an old GnuPG version, and thus contains a secring.gpg file with the secret keys.
  2. When using this homedir, the secret keys are automatically migrated to a private-keys-v1.d subdirectory.
  3. The homedir is moved to another name.
  4. The original contents of the homedir is extracted again.
  5. When using this new homedir, the agent will believe it is serving the new instance of the directory. Also, it uses inotify, and since the directory still exists, there hasn't been any notification. But the gpg client command will not see any migration, so it will try the migration again. This will fail, since the agent will try to write to the directory private-keys-v1.d inside the new copy of the directory, where no such directory exists.

The root of the problem is as I understand it that gpg-agent uses inode in one case but the path in another case. From my linux-only perspective it seems like a possible solution would be to.

  1. Let gpg-agent do chdir() into the homedir. That way, it could use relative paths to everything inside, and not be dependent on the directory's position inside the full file tree.
  2. Use a device-inode combination rather than the path to identify the gpg-agent inside /run/user/<uid>/gnupg. That way, the gpg client would not think the agent is serving the new copy of the directory, and instead start a new agent instance. Conversely a client that tried to use the old homedir under its new name would find the agent for it, and could avoid starting a second.

OS: Red Hat Enterprise Linux 8
GnuPG package: gnupg2-2.2.9-1.el8.x86_64

Details

Version
2.2.9

Event Timeline

werner triaged this task as Normal priority.Sep 22 2020, 4:32 PM
werner added a project: gnupg (gpg22).

The inotify thing is only used to detect a deleted homedir and stop the agent. AFAIU your problem is that a migration is triggered again. The migration status is a file ~/.gnupg/.gpg-v21-migrated - are you sure that you have extracted it again?

I'm pretty sure what happens, but apparently I haven't been able to explain it clear enough. To reproduce you can do like this:

  1. On an old machine having GnuPG version 1, e.g. Red Hat Enterprise 5:
    1. gpg --homedir $PWD/homedir --gen-key
    2. tar cf homedir.tar homedir/pubring.gpg homedir/secring.gpg
  2. On a more modern machine having GnuPG version 2, e.g. Red Hat Enterprise 8:
    1. tar xf homedir.tar
    2. touch apa bepa
    3. gpg --homedir $PWD/homedir --sign apa # Does the migration, and signs "apa"
    4. mv homedir homedir.moved # Don't remove, just move
    5. tar xf homedir.tar
    6. gpg --homedir $PWD/homedir --sign bepa # This will fail as explaine in point 5 of the initial description

I hope this made it clearer.

Before step 2.d you should stop gpg-agent and other daemon

gpgconf --kill all

This way a new gpg-agent is started. I think this is a good workaround.

Using relative directory names and cd-ing to GNUPGHOME has a high potential of regressions and thus we won't do that. Using an inode based socket directory would work but being incompatible with current installations and thus has also a high potential or problems.

werner claimed this task.

Killing the daemon using gpgconf is fine if you are aware you need to do it. We weren't, and I suspect few other users would be either.

But it is your call, of course.