İlt: Re: [RESEND][RFC/discuss] memfd_secret(): opt-in visibility for security monitoring (eBPF/audit)
BoxStrikesTeam
BoxStrikesTeam at proton.me
Fri Jul 10 21:51:32 UTC 2026
Proton Mail güvenli e-posta ile gönderildi.
------- Forwarded Message -------
Kimden: Paul Moore <paul at paul-moore.com>
Tarih: 11 Temmuz 2026 Cumartesi saat 00:00
Konu: Re: [RESEND][RFC/discuss] memfd_secret(): opt-in visibility for security monitoring (eBPF/audit)
Kime: BoxStrikesTeam <BoxStrikesTeam at proton.me>
CC: rppt at kernel.org <rppt at kernel.org>, akpm at linux-foundation.org <akpm at linux-foundation.org>, linux-mm at kvack.org <linux-mm at kvack.org>, linux-security-module at vger.kernel.org <linux-security-module at vger.kernel.org>, jmorris at namei.org <jmorris at namei.org>, serge at hallyn.com <serge at hallyn.com>
> On Thu, Jul 9, 2026 at 1:14 AM BoxStrikesTeam <BoxStrikesTeam at proton.me> wrote:
> > Paul,
> >
> > Thanks - I found the Gottsche/inode_init_security_anon() thread and can see it landed. That answers (a) cleanly: labeling exists, policy can be layered on top via SELinux/AppArmor if a site wants alerting on memfd_secret() creation. Good to have that confirmed as already solved.
> >
> > On (b), let me push on it a bit further, because I think it's worth spelling out explicitly rather than dropping it.
> >
> > My concern: as it stands, an unprivileged process can populate a memfd_secret() region and mseal() the mapping, producing memory that is (a) unreadable by any kernel-side introspection path, including root-owned eBPF tracing programs, and (b) can't be coerced back into an inspectable state via mprotect/munmap. From a host-based detection standpoint that's a blind spot an attacker can use to park a payload where a CAP_BPF-privileged monitoring agent - something that in most other respects can inspect any process on the box - simply cannot look, no matter what capabilities it holds.
> >
> > I understand the objection this invites, and I want to address it directly rather than pretend it isn't there: the memfd_secret() man page is explicit that its ROP protection rests on the absence of any in-kernel primitive for reading this memory. If I'm reading that right, the objection to (b) is that adding any such primitive - however capability-gated - re-creates exactly the artifact a ROP chain would want to call, undermining the "no primitive exists" property regardless of who's nominally allowed to invoke it.
> >
> > I don't think that objection is wrong, but I'm not sure it's fully dispositive either, and I'd like to hear the maintainers' take on the tradeoff explicitly:
> >
> > - The ROP threat model assumes an attacker who already has arbitrary kernel code execution (they're calling kernel functions directly). If they have that, they can likely already walk page tables and reconstruct the mapping by hand - the primitive removal raises the bar, but per the design's own caveat ("no 100% guarantee"), it was never advertised as absolute.
> > - The (b) scenario I'm raising is a different actor: a legitimate, privileged, kernel-mediated monitoring agent (eBPF LSM/tracing program) operating through the normal verifier-checked helper path, not an attacker executing arbitrary kernel code via a ROP chain. Conflating "any code path that can read this memory" with "a gadget a ROP chain can call" may be overly conservative if the new path is narrowly scoped (e.g., a new bpf_probe_read_secretmem() helper, verifier-restricted to CAP_PERFMON|CAP_BPF programs, opt-in per region via a memfd_secret() flag the owning process must set at creation time).
> >
> > If that distinction doesn't hold up - if any additional kernel-callable read path is considered equally exploitable regardless of gating - I'd genuinely like to understand why, since it would mean the confidentiality guarantee is fundamentally incompatible with any form of authorized introspection, which seems worth stating plainly in the documentation for anyone building EDR/monitoring tooling around eBPF.
> >
> > Even if (b) is rejected, I believe explicitly documenting that memfd_secret()+mseal() creates an introspection-proof region would be valuable for the security community, so EDR vendors can adjust their threat models accordingly.
>
> To be very honest, I'm not too concerned about out-of-tree, security
> products; I'm focused on the in-tree kernel code. If you are
> concerned about userspace making use of memfd_secret(), you could
> block the operation on a per-process/domain basis using either seccomp
> or SELinux (other LSMs may have similar functionality, that's an
> exercise left to the reader).
>
> Also, it is important to note that if you find the kernel
> documentation lacking in a particular area, I would encourage you to
> submit a patch to address the shortcomings.
>
> --
> paul-moore.com
>
Paul,
Thanks for the discussion and for the pointer to secretmem_file_create() — that resolves (a) for me.
On (b), I've thought about it further and agree a kernel patch isn't the right answer here. A few closing observations for the record:
1. Dynamic detection isn't actually closed off by memfd_secret()+mseal(). Every syscall a payload makes traps through the normal syscall entry path, and pt_regs->ip at that point reflects the calling address regardless of whether that address sits inside a secretmem VMA. Cross-referencing that IP against /proc/pid/maps (or vma->vm_start/vm_end in-kernel) lets a tracer attribute syscalls to a secretmem-backed region without ever reading the region's contents. So the confidentiality guarantee holds, but it doesn't buy an attacker syscall-level anonymity — only content opacity.
2. That said, I recognize this is a bypassable heuristic on its own (an attacker can proxy syscalls through a separate, non-secretmem code path), which is why I don't think dynamic detection alone is a complete answer either.
3. The more durable idea, I think, is one that doesn't touch confidentiality at all: hooking the memfd_secret()/mmap()/mseal() call sites and building a signature purely from call metadata — arguments, region size, protection flags, and the sequence/timing of these calls — rather than from region contents. This gives EDR/eBPF tooling something for static/behavioral matching without requiring any new in-kernel read primitive, since none of that metadata is protected by secretmem's threat model. This is achievable entirely in userspace/eBPF today with existing hooks, so no kernel change is needed for it either.
Given that, I don't think there's a kernel patch to propose here. This looks like it's squarely a detection-engineering problem for security products to solve on top of existing tracepoints, not a kernel gap. I'll leave the follow-through on that side to the community.
Thanks again for engaging with this — appreciated the back and forth.
Best,
Eneshan Erdoğan Karaca
More information about the Linux-security-module-archive
mailing list