gpg: open_db() does not fall back to read-only on EPERM

Bryan Lee hi at looping.me
Sat Oct 10 10:22:00 CEST 2026


Hi,

open_db() in g10/tdbio.c falls back to O_RDONLY only when the O_RDWR
open fails with EACCES or EROFS. The macOS sandbox (Seatbelt) refuses
writes with EPERM, so a sandboxed gpg that may read the trustdb but not
write it hits a fatal error on every verification that consults the
trustdb. Could EPERM be added to that check?

   db_fd = gnupg_open (db_name, O_RDWR | MY_O_BINARY, 0);
-  if (db_fd == -1 && (errno == EACCES
+  if (db_fd == -1 && (errno == EACCES || errno == EPERM
 #ifdef EROFS
                       || errno == EROFS
 #endif

To reproduce with GnuPG 2.5.24 (Homebrew, macOS 27.0.1 on arm64), in an
empty directory. sandbox-exec matches resolved paths, hence pwd -P:

  export GNUPGHOME=$(pwd -P)/gh
  mkdir -m 700 gh
  gpg --batch --passphrase '' --quick-gen-key test at example.org ed25519 sign never
  echo hello > msg
  gpg --batch -u test at example.org --detach-sign msg
  gpg --verify msg.sig msg
  sandbox-exec -p "(version 1)(allow default)(deny file-write* (literal \"$GNUPGHOME/trustdb.gpg\"))" \
    gpg --verify msg.sig msg

The first --verify succeeds. The sandboxed one ends with

  gpg: Fatal: can't open '/private/var/folders/.../gh/trustdb.gpg': Operation not permitted

and exits with status 2. (With use-keyboxd it hangs instead; I reported
that separately as "gpg 2.5.24 hangs in exit() after a trustdb error
when keyboxd is in use".) With chmod 400 on gh/trustdb.gpg in place of
the sandbox, gpg prints "Note: trustdb not writable" and the usual
"Good signature" line.

Even with that fallback, a read-only trustdb that is due for a check
still fails. In a fresh directory, doing the chmod 400 right after the
key generation, before any --verify, gives

  gpg: Note: trustdb not writable
  gpg: checking the trustdb
  gpg: trustdb rec 31: write failed (n=-1): Bad file descriptor
  gpg: Fatal: .../gh/trustdb.gpg: failed to append a record: Bad file descriptor

unless --no-auto-check-trustdb is given, in which case the key shows as
[unknown]. Perhaps a read-only open could skip the automatic check and
accept stale or unknown validity rather than fail.

Thanks,
Bryan


More information about the Gnupg-devel mailing list