[RFC/discuss] memfd_secret(): opt-in visibility for security monitoring (eBPF/audit)

BoxStrikesTeam <[email protected]>
Newsgroups org.kernel.vger.linux-security-module,org.kvack.linux-mm
Message-ID <umQp9Qs18vw53oZDFIgYE4MyUWNemeNL8-Vbs-BOYEvQByiyPSZ3RrEvOpmdWUZ1YtjEHpjlgZnMo5DkJuJziwrKWTYS_A0QF_B3ixToMBY=@proton.me>

Hi,

While experimenting with mseal() and memfd_secret() together on a
recent kernel, I ran into what looks like a gap worth discussing:
content placed in memfd_secret()-backed memory is invisible not just
to other processes, but also to in-kernel tracing/observability
mechanisms such as eBPF's bpf_probe_read_user() (EFAULT, as expected,
since the region is removed from the direct map and kernel page
tables entirely).

That's working as designed for the threat model memfd_secret targets
(protect secrets even from a compromised kernel / ROP-based
exfiltration). But it does mean a local, unprivileged process can
now allocate memory that:

 1. Is invisible to kernel-side introspection (eBPF tracing,
 /proc/<pid>/mem, ptrace-based tooling) once populated via
 memfd_secret(), and
 2. Can additionally be sealed against mprotect()/munmap()/mremap()
 via mseal() so its protection bits can't be relaxed either.

Neither primitive alone is new or alarming - mseal() protects mapping
metadata, not confidentiality, and memfd_secret() is explicitly
opt-in and disabled by default. But combined, they let a process
carve out a region that a host-based EDR relying on eBPF
tracing/probe_read helpers cannot inspect, and cannot force back into
an inspectable state either. For userland security tooling that
assumes 'anything a tracing eBPF program can attach to, it can read',
this is a small blind spot.

I want to be clear I'm not suggesting memfd_secret()'s core guarantee
should be weakened - the ability to keep data hidden from a
compromised kernel is the entire point, and forcibly exposing content
to tracing programs would undermine that model and create a new
attack surface via the eBPF verifier/helper path itself.

What I'd like to raise for discussion instead is something closer to
what was already anticipated in the original series - Mike, your
commit message for memfd_secret() mentions: 'Once there will be a use
case that will require exposing secretmem to the kernel it will be an
opt-in request in the system call flags.' Two lighter-weight
directions that stay consistent with that opt-in philosophy:

 a) An LSM hook / audit event at memfd_secret() call time (this
 echoes Christian Gottsche's 2022 RFC to label secretmem inodes
 via inode_init_security_anon for SELinux). Even without content
 visibility, logging 'process X created a N-byte kernel-invisible
 mapping' gives EDR/audit systems a behavioral signal to alert on,
 without touching the confidentiality guarantee at all.

 b) A distinct opt-in flag (as foreshadowed in the original commit)
 that a process could set to allow a CAP_BPF/CAP_SYS_ADMIN-gated
 tracing context to read the region for legitimate
 monitoring/debugging - fully opt-in, off by default, and never
 implicitly available to unprivileged tracers.

Is (a) something that's been considered further since the 2022
secretmem-inode-labeling thread? And is there any existing tracking
issue for the kind of opt-in-visibility idea in (b), or was it
dropped as not worth the complexity?

Happy to help test/write a small selftest if there's interest in
pursuing either direction.

Thanks,
BoxStrike Team.
Researcher:Eneshan Erdoğan Karaca, Other ananymous


Researcher emails:[email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.