Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I was going to post something about how I wonder how useful this is since my understanding is that JIT engines need to be able to write executable code to memory, and if you can't protect that, which seems to be the largest attack vector for browsers currently.

Then I actually looked at the post, and it's about enabling W^X on JIT pages in memory. Very cool.



I think I remember reading old articles about how they're doing this. Once the code has been JIT'd they put it on a page (or pages) by itself, and then toggle the write bit so it can be executed. Once it's JIT'd anyway it won't ever be changed, other than to maybe be dropped in favor of some other code. This still can have some security issues if someone can manage to get the JIT engine to output arbitrary code directly but it prevents a huge class of attacks of overwriting the JIT pages and getting the browser to then execute them. Or the usual stack overflows and other things of course.


> Once it's JIT'd anyway it won't ever be changed,

That's not necessarily how it works. JITs often use inline caches that get populated at runtime. JITs usually implement W^X by mapping the same physical memory into two different address ranges. Once as RW for modification and once as RX for execution.

Having a single mapping is possible, but comes with performance penalties because execution needs to reach a safe/bailout point where that can happen instead of just atomically patching the code.


Doesn't mapping the same physical memory into two places actually end up defeating the W^X bit entirely? Since you can write to the RW mapped page and have it change the RX page?


Those pages would be mapped at a different, random address while the executing code has an instruction pointer pointing right at the RX page.

It's much more difficult getting access to the JIT's internal data structures, traversing them to find the correct RW page, then modify it, then jump to the same place in the RX page. If you already have that much control you're probably not far from getting the JIT to emit arbitrary code anyway.

Note that writing to ICs can happen from a different thread, so the current thread stack does not need to know much of the JIT's internal data.


Wouldn't it potentially waste a bunch of memory, or does JIT output tend to be greater than a 4K page?


An individual function would often be smaller than 4K, and it's up to the JIT to decide how much to compile at one time, and you can also coalesce new code with old code to compact it.


You can check the end of this talk, when someone asks about this:

https://events.yandex.com/events/ruBSD/2013/talks/103/

I would recommend, however, watch from the beginning.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: