From: Jennifer Miller <jmill@asu.edu>
To: Jann Horn <jannh@google.com>
Cc: Andy Lutomirski <luto@kernel.org>,
linux-hardening@vger.kernel.org, kees@kernel.org,
joao@overdrivepizza.com, samitolvanen@google.com,
kernel list <linux-kernel@vger.kernel.org>,
Andrew Cooper <andrew.cooper3@citrix.com>
Subject: Re: [RFC] Circumventing FineIBT Via Entrypoints
Date: Wed, 12 Feb 2025 23:15:05 -0700 [thread overview]
Message-ID: <Z62N6cGmaN+OZfoY@ubun> (raw)
In-Reply-To: <CAG48ez09JuZPt112nnE6N=hS6cfCLkT-iHUAmidQ-QGNGMVoBw@mail.gmail.com>
On Wed, Feb 12, 2025 at 11:29:02PM +0100, Jann Horn wrote:
> +Andy Lutomirski (X86 entry code maintainer)
>
> On Wed, Feb 12, 2025 at 10:08 PM Jennifer Miller <jmill@asu.edu> wrote:
> > As part of a recently accepted paper we demonstrated that syscall
> > entrypoints can be misused on x86-64 systems to generically bypass
> > FineIBT/KERNEL_IBT from forwards-edge control flow hijacking. We
> > communicated this finding to s@k.o before submitting the paper and were
> > encouraged to bring the issue to hardening after the paper was accepted to
> > have a discussion on how to address the issue.
> >
> > The bypass takes advantage of the architectural requirement of entrypoints
> > to begin with the endbr64 instruction and the ability to control GS_BASE
> > from userspace via wrgsbase, from to the FSGSBASE extension, in order to
> > perform a stack pivot to a ROP-chain.
>
> Oh, fun, that's a gnarly quirk.
yeag :)
> Since the kernel, as far as I understand, uses FineIBT without
> backwards control flow protection (in other words, I think we assume
> that the kernel stack is trusted?), could we build a cheaper
> check on that basis somehow? For example, maybe we could do something like:
>
> ```
> endbr64
> test rsp, rsp
> js slowpath
> swapgs
> ```
>
> So we'd have the fast normal case where RSP points to userspace
> (meaning we can't be coming from the kernel unless our stack has
> already been pivoted, in which case forward edge protection alone
> can't help anymore), and the slow case where RSP points to kernel
> memory - in that case we'd then have to do some slower checks to
> figure out whether weird userspace is making a syscall with RSP
> pointing to the kernel, or whether we're coming from hijacked kernel
> control flow.
I've been tinkering this idea a bit and came with something.
In short, we could have the slowpath branch as you suggested, in the
slowpath permit the stack switch and preserving of the registers on the
stack, but then do a sanity check according to the __per_cpu_offset array
and decide from there whether we should continue executing the entrypoint
or die/attempt to recover.
Here is some napkin asm for this I wrote for the 64-bit syscall entrypoint,
I think more or less the same could be done for the other entrypoints.
```
endbr64
test rsp, rsp
js slowpath
swapgs
~~fastpath continues~~
; path taken when rsp was a kernel address
; we have no choice really but to switch to the stack from the untrusted
; gsbase but after doing so we have to be careful about what we put on the
; stack
slowpath:
swapgs
; swap stacks as normal
mov QWORD PTR gs:[rip+0x7f005f85],rsp # 0x6014 <cpu_tss_rw+20>
mov rsp,QWORD PTR gs:[rip+0x7f02c56d] # 0x2c618 <pcpu_hot+24>
~~normal push and clear GPRs sequence here~~
; we entered with an rsp in the kernel address range.
; we already did swapgs but we don't know if we can trust our gsbase yet.
; we should be able to trust the ro_after_init __per_cpu_offset array
; though.
; check that gsbase is the expected value for our current cpu
rdtscp
mov rax, QWORD PTR [8*ecx-0x7d7be460] <__per_cpu_offset>
rdgsbase rbx
cmp rbx, rax
je fastpath_after_regs_preserved
wrgsbase rax
; if we reach here we are being exploited and should explode or attempt
; to recover
```
The unfortunate part is that it would still result in the register state
being dumped on top of some attacker controlled address, so if the error
path is recoverable someone could still use entrypoints to convert control
flow hijacking into memory corruption via register dump. So it would kill
the ability to get ROP but it would still be possible to dump regs over
modprobe_path, core_pattern, etc.
Does this seem feasible and any better than the alternative of overwriting
and restoring KERNEL_GS_BASE?
~Jennifer
next prev parent reply other threads:[~2025-02-13 6:15 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <Z60NwR4w/28Z7XUa@ubun>
2025-02-12 22:29 ` [RFC] Circumventing FineIBT Via Entrypoints Jann Horn
2025-02-13 1:31 ` Andrew Cooper
2025-02-13 2:09 ` Jann Horn
2025-02-13 2:42 ` Andrew Cooper
2025-02-22 20:43 ` Rudolf Marek
2025-02-25 18:10 ` Andrew Cooper
2025-02-25 20:06 ` Rudolf Marek
2025-02-25 21:14 ` Andrew Cooper
2025-02-26 2:55 ` Kees Cook
2025-02-26 22:48 ` Rudolf Marek
2025-02-27 0:41 ` Andrew Cooper
2025-03-01 22:48 ` Rudolf Marek
2025-03-02 19:16 ` Rudolf Marek
2025-03-02 22:31 ` Andrew Cooper
2025-02-28 12:13 ` Florian Weimer
2025-02-13 20:28 ` Kees Cook
2025-02-13 20:41 ` Andrew Cooper
2025-02-13 20:53 ` Kees Cook
2025-02-13 20:57 ` Jann Horn
2025-02-16 23:42 ` Kees Cook
2025-02-14 9:57 ` Peter Zijlstra
2025-02-15 21:07 ` Peter Zijlstra
2025-02-16 23:51 ` Kees Cook
2025-02-17 10:39 ` Peter Zijlstra
2025-02-17 13:06 ` David Laight
2025-02-17 13:13 ` Peter Zijlstra
2025-02-17 18:38 ` David Laight
2025-02-17 18:54 ` Peter Zijlstra
2025-02-14 10:05 ` Peter Zijlstra
2025-02-14 9:54 ` Peter Zijlstra
2025-02-13 6:15 ` Jennifer Miller [this message]
2025-02-13 19:23 ` Jann Horn
2025-02-13 21:24 ` Andrew Cooper
2025-02-13 23:24 ` Jennifer Miller
2025-02-13 23:43 ` Jann Horn
2025-02-14 23:06 ` Andrew Cooper
2025-02-15 0:07 ` Jennifer Miller
2025-02-15 0:11 ` Andrew Cooper
2025-02-15 0:19 ` Jennifer Miller
2025-02-14 22:25 ` Josh Poimboeuf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z62N6cGmaN+OZfoY@ubun \
--to=jmill@asu.edu \
--cc=andrew.cooper3@citrix.com \
--cc=jannh@google.com \
--cc=joao@overdrivepizza.com \
--cc=kees@kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=samitolvanen@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox