
Microsoft Engineer Proposes “Trampfd” for Improving Linux Security - rbanffy
https://www.phoronix.com/scan.php?page=news_item&px=Microsoft-TRAMPFD-Linux
======
jchw
Someone in the Phoronix comments wondered why not just map it (the kernel-
assisted trampoline memory page) executable and not writeable, to avoid the
attack surface but be significantly faster. I also wonder exactly why,
admittedly I haven’t read the mailing list thread entirely but purely working
on theory I wonder what the advantages of working on page fault is. Less
abusable gadgets in memory? More flexibility? Perhaps additional Spectre-type
mitigations?

~~~
sild
Currently the page must be writeable at some point in order to create the
trampoline.

A page fault is used as a way of executing the trampoline without the page
having to be made executable/writable---the page fault handler recognises the
page as a special trampoline page and handles the jump to the trampolines
target address (which was previously registered using the new syscall).

Note that AFAICS this is unrelated to Spectre. The intended use is for
constructing closures for use in FFI libraries such as libffi.

EDIT: I think I perhaps misunderstood your query---are you saying why not just
make a system call where the kernel creates the page for you with the desired
trampoline code and execute permissions?

~~~
ori_b
Double map it, like a JIT does. Once writable, and once executable. Put the
pointers into different shared objects so that ASLR puts a randomized offset
between them and you can't discover the write pointers from the execute
pointer, and vice versa.

~~~
vardump
You still need to store the write pointers somewhere. So this very quickly
becomes a game of cat and mouse.

~~~
saagarjha
JavaScriptCore had an amusing scheme where they'd make an (executable) memcpy
gadget with the address hardcoded, then throw away read permissions to that
memory. So the pointer's address is thus not readable without modifying memory
permissions.

------
tomphoolery
Does it really matter that he's a "Microsoft Engineer" or is that just thrown
in there to ruffle old people's feathers?

~~~
paulie_a
I think it gives credability right off the bat.

~~~
saagarjha
Ideally, it wouldn't.

~~~
paulie_a
But we don't live in that world. Someone that name drops their company name is
more credible that some random blogger that works at a hardware store

------
saagarjha
Sounds a bit like how vsyscall works, except without kernel ABI reasons to
back it up :/ Trying to have the kernel/application figure out if a trampoline
is “legit” sounds like a bad idea, just like GCC’s nested functions in the
first place (which people have been told to avoid for quite a while). Why not
tell applications to migrate to iOS-style trampoline page remapping that’s
used for imp_implementationWithBlock:
[https://landonf.org/code/objc/imp_implementationWithBlock.20...](https://landonf.org/code/objc/imp_implementationWithBlock.20110413.html)?
libffi will likely be migrating away from its current technique to support
Apple Silicon, anyhow.

~~~
Gibbon1
Nested functions in c are totally awesome and perfectly safe as long as a) you
don't pass them as function pointers and b) care about executable stacks. The
nice thing is you avoid gross preprocessor crap.

~~~
saagarjha
You probably want blocks, then:
[https://en.wikipedia.org/wiki/Blocks_(C_language_extension)](https://en.wikipedia.org/wiki/Blocks_\(C_language_extension\))

~~~
Gibbon1
I'm very happy to see blocks show up, despite that they aren't yet supported
by gcc. I keep hoping.

------
haecceity
Why can't they write the code to a writeable page then remove the write
permissions when they need to execute it?

~~~
saagarjha
Probably too slow?

------
atgreen
I guess I should monitor the libffi patch queue more carefully, as I only
learned about their proposed changes by following the hacker news > phoronx >
lkml rabbit hole.

------
ape4
Um, so a trampoline is some kind of redirect?

~~~
quietbritishjim
I think there are several slightly different variations, but generally a
trampoline is something like this pseudo-code:

    
    
        while (next_fn_to_call != nullptr) {
           next_fn_to_call = next_fn_to_call()
        }
    

So each function potentially wants to call a new function once it's done, but
you don't want to blow the stack (or maybe use a stack at all) so it returns
that function (pointer) rather than calling it. Then you need a little loop to
call the return value: that's your trampoline.

The article is potentially a bit lower level given it's talking about things
down at the CPU level, but I imagine its a vaguely connected idea.

------
dane-pgp
I'm waiting for a Red Hat engineer to return the favor by proposing "Drampft"
for improving the performance of DRAM in Windows.

