Hi Andrew,

Dne 27. 02. 25 v 1:41 Andrew Cooper napsal(a):
For SYSCALL/SYSENTER it's a little more complicated.  I think you want
to move the selectors so they don't alias __KERN_CS directly, so you can
then move back to __KERN_CS in a similar way

Yes I thought the CHECK_CS could be right before KERN_DS so at least kernel SS is right.

Give or take paranoid_entry for the IST vectors, any entrypoint that
finds itself on __KERN_CS did not get there through the CPU loading a
new context.

Yes

It would depend on an attacker not being able to include a FAR CALL into
their exploit chain, or be able toe write the IDT.  I don't know how
reasonable that would be if we're ruling out all architectural paths not
beginning with an ENDBR, but FAR CALLs are rare in general owing to them
being dog slow in general, and an attacker who can write the IDT doesn't
need these kinds of games to pivot.

In fact I wanted to use far jump, but is it OK? On 64-bit architecture, there is no absolute direct jump with CS change, only indirect one. Do all CPUs with FineIBT somehow reasonably handle all the spectre v2 and various other indirect branch speculation problems? To speed it up we can use "fallthrough" speculation to our advantage and include the target right after the instruction.

Anyone fancy doing a prototype of this?

Maybe we can discuss following before, if you find this conversation still entertaining :)

1) Implement the different %cs for entry points

Looks non-trivial for an attacker to obtain right %cs before landing on the IDT/SYSCALL entrypoints.

Each entrypoint would check if current %cs is __KERN_CHECK_CS, and if not panic. Then it would change the %CS back to __KERN_CS via far jump.

I don't know how slow is to do the jump back via far jump.

2) Implement some weaker version of what I was proposing and mostly checking the %ss. The attacker would need to control/load %SS before jumping to endbr64 or provide a reasonable exception stack

SYSCALL:
- maybe do "cli" to avoid issues with interrupts/nesting
- would use valid but different %ss selector from __KERN_DS
- would check if %ss == __KERN_CHECK_DS, if not panic
- reload %SS with __KERN_DS selector

IDT entrypoints:
- maybe do "cli" to avoid issues with interrupts/nesting
- if %SS == 0, skip other checks because CPL changed (maybe too weak?)
- perform more sanity checks on exception stack maybe in a direction what I proposed in other email - depends if it makes attacker life miserable or not
- reload %SS with __KERN_DS selector if CPL changed (maybe needed?)

And very last idea would be to somehow persuade the Last Branch
Recording to record exception entries only and just check it from MSR.
But maybe it is too costly and/or not possible.

This doesn't cover all cases, I don't think.  It also won't work under
virt, where LBR isn't reliably available.  Also LBR is reasonably full
of errata, and quite slow.

OK thanks, it was just an idea.

Thanks,
Rudolf


Reply via email to