# gnupg in a Jail: "agent_genkey failed: End of file" error



## patpro (Feb 18, 2016)

Hello,

I'm trying to run security/gnupg inside a Jail, but it fails creating a key, with this error:


```
root@yksm:~ # gpg2 --full-gen-key
gpg (GnuPG) 2.1.8; Copyright (C) 2015 Free Software Foundation, Inc.
../..
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: agent_genkey failed: End of file
Key generation failed: End of file
```

Inside the Jail, security/gnupg also issues a warning about memory:


```
gpg: Warning: using insecure memory!
```

When I try this on the host (ie. outside the Jail), with the same exact security/gnupg version, it works:


```
root@test10:~ #    gpg2 --full-gen-key
gpg (GnuPG) 2.1.8; Copyright (C) 2015 Free Software Foundation, Inc.
../..
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
Please enter the passphrase to
protect your new key
Passphrase:
../..
```

The warning about memory does not occur when command runs on the host.

System is 10.2-RELEASE-p9, amd64. Jails are created with sysutils/ezjail and are rather vanilla.

Is there a special setting that I would need to tune in order to make security/gnupg behaves properly inside a Jail?


----------



## Crest (Feb 19, 2016)

GnuPG warns about insecure memory because it can't use mlock()/mlockall() inside the jail. These system calls allow a process to prohibit the kernel from swapping the locked address space. There are two use cases for these:

* The process has to fulfil realtime constraints.
* The process doesn't trust the swap space with the contents of the address space.

GnuPG is an example of the later because its address space has to contain private key material during decryption and signing. The best solution is to use encrypted swap partitions and disable the warning in the GnuPG configuration.

* Disable all swap with `swapoff -a`
* Load the AES-NI kernel module if your CPU supports AES-NI with `kldload -n aesni`. Put aesni_load="YES" in /boot/loader.conf if it isn't already. You have to load the AES-NI kernel module from the bootloader because the rc.d script loading kernel modules is executed too late. That way you would end up with a software encrypted GELI instance.
* Append the ".eli" suffix to all swap devices.
* Enjoy your encrypted swap space with `swapon -a`
* Now disable the warning in your GnuPG configuration.

Locking address space with mlock()/mlockall() requires the kernel to wire down physical memory containing the address space. This can starve the system of resources. Used correctly it will only impact best effort performance slightly by reducing the physical memory available for demand paging, but if a malicious process with the required rights locks down all available memory the resource starvation is a threat to system stability.


----------



## patpro (Feb 19, 2016)

Thank you for this explanation and for the quick how-to about encrypted swap!

Do you think the failure of GnuPG to generate the key comes for the same problem? ie. the warning should then be a true error. Or is it something completely different?


----------



## Crest (Feb 19, 2016)

Does your jail contain a /dev/random (and /dev/urandom)?


----------



## patpro (Feb 19, 2016)

That's the first think I've checked, and it does. I've even tried to fetch random data out of it, and eventually broke my terminal: success. 
Interestingly, /dev/ is not mounted as devfs() inside the jail, or at least it's not seen as devfs.
From host's perspective, we have:


```
#    df -t devfs
Filesystem 1K-blocks Used Avail Capacity  Mounted on
devfs              1    1     0   100%    /dev
devfs              1    1     0   100%    /usr/jails/yval/dev
devfs              1    1     0   100%    /usr/jails/yksm/dev
```

inside a jail, we have:


```
# df -t devfs
# (nothing)
# df 
Filesystem        1K-blocks   Used   Avail Capacity  Mounted on
zroot/ezjail/yksm   5055228 118328 4936900     2%    /
#
# dd count=5 if=/dev/random
(randomness wreaks havoc)
```


----------



## patpro (Feb 26, 2016)

patpro said:


> Do you think the failure of GnuPG to generate the key comes for the same problem? ie. the warning should then be a true error. Or is it something completely different?



Ok, so after testing, the encrypted swap does not bring anything good: key creation still fails.
I've tried to ktrace the process, and it yields to this:


```
2022 pinentry-tty CALL  utimes(0x801809060,0)
  2022 pinentry-tty NAMI  "/root/.gnupg/S.gpg-agent"
  2022 pinentry-tty RET   utimes 0
  2022 pinentry-tty PSIG  SIGSEGV SIG_DFL code=SEGV_MAPERR
```

and later in the output:


```
2021 gpg-agent CALL  write(0x8,0x800d6472c,0x3)
  2021 gpg-agent RET   write -1 errno 32 Broken pipe
  2021 gpg-agent CALL  close(0x5)
...
  2021 gpg-agent CALL  write(0x2,0x802006c00,0x3f)
  2021 gpg-agent GIO   fd 2 wrote 63 bytes
       "gpg-agent[2021]: command 'GENKEY' failed: End of file <Pinentry"
  2021 gpg-agent RET   write 63/0x3f
  2021 gpg-agent CALL  write(0x2,0x43dfff,0x2)
  2021 gpg-agent GIO   fd 2 wrote 2 bytes
       ">
       "
```

Wild guess: I think the issue lies in `pinentry`, not in GnuPG.

`dmesg` confirms this:


```
pid 2022 (pinentry-tty), uid 0: exited on signal 11
```

After some more tests, it appears that pinentry crashes also on the host… I've replaced packages of gnupg and pinentry by compiled ports: same result.
Any hint ?


----------



## chrbr (Feb 27, 2016)

There exists PR 205246 about security/pinentry-tty. It might be related to the described problem.


----------



## patpro (Feb 27, 2016)

Thanks, I've added a comment on the PR.


----------

