Re: [PATCH v2 00/39] Shadowstacks for userspace
From: Jann Horn <jannh@google.com>
Date: 2022-10-03 17:26:22
Also in:
linux-arch, linux-doc, linux-mm, lkml
On Mon, Oct 3, 2022 at 7:04 PM Kees Cook [off-list ref] wrote:
On Thu, Sep 29, 2022 at 03:28:57PM -0700, Rick Edgecombe wrote:quoted
This is an overdue followup to the “Shadow stacks for userspace” CET series. Thanks for all the comments on the first version [0]. They drove a decent amount of changes for v2. Since it has been awhile, I’ll try to summarize the areas that got major changes since last time. Smaller changes are listed in each patch.Thanks for the write-up!quoted
[...] GUP --- Shadow stack memory is generally treated as writable by the kernel, but it behaves differently then other writable memory with respect to GUP. FOLL_WRITE will not GUP shadow stack memory unless FOLL_FORCE is also set. Shadow stack memory is writable from the perspective of being changeable by userspace, but it is also protected memory from userspace’s perspective. So preventing it from being writable via FOLL_WRITE help’s make it harder for userspace to arbitrarily write to it. However, like read-only memory, FOLL_FORCE can still write through it. This means shadow stacks can be written to via things like “/proc/self/mem”. Apps that want extra security will have to prevent access to kernel features that can write with FOLL_FORCE.This seems like a problem to me -- the point of SS is that there cannot be a way to write to them without specific instruction sequences. The fact that /proc/self/mem bypasses memory protections was an old design mistake that keeps leading to surprising behaviors. It would be much nicer to draw the line somewhere and just say that FOLL_FORCE doesn't work on VM_SHADOW_STACK. Why must FOLL_FORCE be allowed to write to SS?
But once you have FOLL_FORCE, you can also just write over stuff like executable code instead of writing over the stack. I don't think allowing FOLL_FORCE writes over shadow stacks from /proc/$pid/mem is making things worse in any way, and it's probably helpful for stuff like debuggers. If you don't want /proc/$pid/mem to be able to do stuff like that, then IMO the way to go is to change when /proc/$pid/mem uses FOLL_FORCE, or to limit overall write access to /proc/$pid/mem.