Re: [PATCH v18 0/9] mm: introduce memfd_secret system call to create "secret" memory areas

James Bottomley
2021-05-06T15:29:25Z

On Wed, 2021-05-05 at 12:08 -0700, Andrew Morton wrote:
> On Wed, 3 Mar 2021 18:22:00 +0200 Mike Rapoport <rppt@kernel.org>
> wrote:
>
> > This is an implementation of "secret" mappings backed by a file
> > descriptor.
> >
> > The file descriptor backing secret memory mappings is created using
> > a dedicated memfd_secret system call The desired protection mode
> > for the memory is configured using flags parameter of the system
> > call. The mmap() of the file descriptor created with memfd_secret()
> > will create a "secret" memory mapping. The pages in that mapping
> > will be marked as not present in the direct map and will be present
> > only in the page table of the owning mm.
> >
> > Although normally Linux userspace mappings are protected from other
> > users, such secret mappings are useful for environments where a
> > hostile tenant is trying to trick the kernel into giving them
> > access to other tenants mappings.
>
> I continue to struggle with this and I don't recall seeing much
> enthusiasm from others. Perhaps we're all missing the value point
> and some additional selling is needed.
>
> Am I correct in understanding that the overall direction here is to
> protect keys (and perhaps other things) from kernel bugs? That if
> the kernel was bug-free then there would be no need for this
> feature? If so, that's a bit sad. But realistic I guess.

Secret memory really serves several purposes. The "increase the level
of difficulty of secret exfiltration" you describe. And, as you say,
if the kernel were bug free this wouldn't be necessary.

But also:

1. Memory safety for use space code. Once the secret memory is
allocated, the user can't accidentally pass it into the kernel to be
transmitted somewhere.
2. It also serves as a basis for context protection of virtual
machines, but other groups are working on this aspect, and it is
broadly similar to the secret exfiltration from the kernel problem.

>
> Is this intended to protect keys/etc after the attacker has gained
> the ability to run arbitrary kernel-mode code? If so, that seems
> optimistic, doesn't it?

Not exactly: there are many types of kernel attack, but mostly the
attacker either manages to effect a privilege escalation to root or
gets the ability to run a ROP gadget. The object of this code is to be
completely secure against root trying to extract the secret (some what
similar to the lockdown idea), thus defeating privilege escalation and
to provide "sufficient" protection against ROP gadgets.

The ROP gadget thing needs more explanation: the usual defeatist
approach is to say that once the attacker gains the stack, they can do
anything because they can find enough ROP gadgets to be turing
complete. However, in the real world, given the kernel stack size
limit and address space layout randomization making finding gadgets
really hard, usually the attacker gets one or at most two gadgets to
string together. Not having any in-kernel primitive for accessing
secret memory means the one gadget ROP attack can't work. Since the
only way to access secret memory is to reconstruct the missing mapping
entry, the attacker has to recover the physical page and insert a PTE
pointing to it in the kernel and then retrieve the contents. That
takes at least three gadgets which is a level of difficulty beyond most
standard attacks.

> I think that a very complete description of the threats which this
> feature addresses would be helpful.

It's designed to protect against three different threats:

1. Detection of user secret memory mismanagement
2. significant protection against privilege escalation
3. enhanced protection (in conjunction with all the other in-kernel
attack prevention systems) against ROP attacks.

Do you want us to add this to one of the patch descriptions?

James