Re: Shadow stack enabling from dynamic loader v/s kernel on exec

From: Edgecombe, Rick P
Date: Mon Nov 27 2023 - 12:41:50 EST


On Wed, 2023-11-22 at 16:19 -0800, Deepak Gupta wrote:
> I don't want to divert focus from patch specific comments on shadow
> stack patches that're being
> discussed in the mailing list. And that's starting this separate
> thread about enabling the shadow
> stack in the dynamic loader v/s kernel. I've put relevant folks in
> "To" and "kernel" and "libc" in CC.

Thanks. As we look at adding some final glibc support, I've wondered if
there might be enough topics to warrant an occasional meeting to
discuss stuff like this. I'd also like to discuss the shadow stack life
cycle issues (uncontext, etc), alt shadow stacks and all of the
compatibility last mile problems. Towards the goal of avoiding
unnecessary divergence on app developer expectations.

> This has many advantages
> - dynamic loaders (and static binary) are protected from loader
> specific ROP attack in a small window

Loaders can call the prctl() as the first step, so the loader is
protected. The x86 glibc patches did this at one point. So the prctl
supports enabling at pretty close to either point, "exec time" or later
in the loader process. Enabling before the first CALL (or unwound to
that point) leaves the shadow stack's balanced.

I think the main disadvantage are:
- *Maybe* it requires duplication for the seccomp use case
- Requires mapping, then unmapping shadow stack for cases of
incompatible DSO or disable via TUNABLE

It is probably worth noting, the old elf bit based enabling would
enable shadow stack if the *loader* DSO had the elf bit set. Then the
loader would check the elf bit of the execing binary, and disable
shadow stack if not supported. This means with shadow stack enabled
kernel and glibc, all legacy apps would be subjected to a map and unmap
of the shadow stack. It probably isn't the biggest deal, but it's nice
to avoid.