From 844fb87cdb32cc1999123606b734539e964e4407 Mon Sep 17 00:00:00 2001 From: Matt Watson Date: Tue, 18 Aug 2026 13:51:29 -0700 Subject: [PATCH] common: explain why mlock() failed instead of a bare abort. mlock_tal_memory() aborts when sodium_mlock() fails, with no output at all. The operator sees only "lightning_hsmd: FATAL SIGNAL 6" and has no indication of the cause. This is easy to hit. FreeBSD jails deny mlock(2) unless the jail has allow.mlock set, and containerized Linux deployments hit the same wall against RLIMIT_MEMLOCK. In both cases the failure is indistinguishable from a crash. Keep the abort -- falling back to unlocked memory would silently leave the secret in swappable pages -- but say what failed and how to grant the privilege. Changelog-Fixed: Report the cause when locking secret memory fails, instead of aborting with no diagnostic. --- common/utils.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/common/utils.c b/common/utils.c index 0bd7a72cb341..6c8ad7252993 100644 --- a/common/utils.c +++ b/common/utils.c @@ -1,6 +1,7 @@ #include "config.h" #include #include +#include #include #include #include @@ -11,6 +12,7 @@ #include #include #include +#include const tal_t *wally_tal_ctx = NULL; secp256k1_context *secp256k1_ctx; @@ -100,8 +102,21 @@ static void destroy_munlock(const tal_t *ptr) void mlock_tal_memory(const tal_t *ptr) { - if (sodium_mlock((void *)ptr, tal_bytelen(ptr)) != 0) + if (sodium_mlock((void *)ptr, tal_bytelen(ptr)) != 0) { + warnx("FATAL: could not lock %zu bytes of sensitive memory" + " into RAM: %s\n" + "Memory locking is required to keep secrets out of" + " swap.\n" + "If you are running in a container or jail, the" + " privilege must be granted:\n" + " FreeBSD jail: set allow.mlock=1 for the jail\n" + " Linux: raise RLIMIT_MEMLOCK (ulimit -l), or grant" + " the CAP_IPC_LOCK capability\n" + " Docker/Podman: --ulimit memlock=-1:-1 or" + " --cap-add=IPC_LOCK", + tal_bytelen(ptr), strerror(errno)); abort(); + } tal_add_destructor(ptr, destroy_munlock); }