Hacker News new | past | comments | ask | show | jobs | submit login
W^X enabled in OpenBSD Firefox port (undeadly.org)
141 points by protomyth on Oct 21, 2015 | hide | past | web | favorite | 31 comments



I would love to see this make it upstream. I use PaX/grsec under linux and one of my favorite things about them is that they try to enforce w^x.

Unfortunately, a ton of programs break this policy (seemingly for no benefit). Having upstream firefox respect w^x anyway would mean I could remove its exception under PaX and a whole class of possible security flaws just GoAway™.

Ideally, I'd love to see Linux embrace w^x generally, but the kernel devs do not seem terribly interested in that. Either way, keep up the rockin' work OpenBSD team!

Edit: Oh wait! The patch for this is actually upstream! This bit of news is OpenBSD enabling it! That's awesome! /me tries to rebuild firefox with the patch enabled.


>and a whole class of possible security flaws just GoAway™.

Technically not true, they don't go away, they're just harder(and not that much harder) to exploit.


It changes a broad class of attack exploits to require return-oriented programming techniques to exploit. Are you seriously claiming that ROP isn't "that much harder" than injecting arbitrary code?


libc by itself provides a Turing-complete set of ROP gadgets: <http://www.cs.ncsu.edu/faculty/jiang/pubs/RAID11.pdf>.


First of all: thanks! I'm excited to read this!

Second of all: ugh! Dear HackerNews team, please fix your URL matching algorithm so it doesn't include <> in URLs; they're actually explicitly recommended by the URI RFC as delimiters.

Sincerely,

halosghost


Here's the original paper of this attack (AFAIK): http://cseweb.ucsd.edu/~hovav/dist/geometry.pdf

The other paper shows that this technique is Turing complete.

But yes, basically W^X is defeated.


>Are you seriously claiming that ROP isn't "that much harder" than injecting arbitrary code?

Yes I am.


I think you're using overly vague classes if you can't point to classes of attack that are flat-out blocked.


Try running Gentoo hardened. It makes it a lot easier to run on Grsec and Pax kernel.


Actually, though I deeply enjoy grsec and pax, I find it to work just fine with Arch. I have definitely considered gentoo hardened though; the notion of being able to rebuild everything exactly how I'd like it is pretty damn tempting. Thank you for the recommendation; everytime someone gives me a serious recommendation for Gentoo, I always have to take a moment and give it a more serious thought :)


seconding the gentoo recommendation. PaX/grsec is far easier under OpenRC.


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.


Firefox on iOS, eh?


It's buildable and works, but you obviously could never submit it to the App Store.



That one uses WebKit. I wonder if anybody actually got Gecko to run on iOS. As I understand, there are "only" two problems - Apple not allowing other HTML/JS implementations, and Apple not allowing writable, executable memory. I don't know what the status of the first is, but you can get around the latter by just using an interpreter instead of a JIT (which is of course terribly slow).

Or, you decide Apple is never going to let your engine on the App store, and then you just include the JIT. The enforcement is done at time of submission to the app store, not at runtime. IIRC, you can just call a certain function to mark a memory region as writable or executable, but Apple detects this call statically.

I further wonder if you could just distribute binaries, outside of the app store, and your users would have $99 developer accounts, and run a little script to "build their project with XCode", signing and installing it to their device?


Prototype builds of Gecko running on iOS do exist, but they are not officially developed or maintained by Mozilla. You can track the progress of merging iOS support into the main Firefox repository in this bug:

https://bugzil.la/1163827


That looks pretty official to me.


Well, you certainly know more about Mozilla's iOS plans than I do :) but I thought Ted was just working on the patches on his own time, not in any official capacity.


You no longer need a paid developer account to deploy apps from source to a physical device.


Isn't the enforcement done at runtime? I remember testing this and the mprotect() call was simply giving me a EPERM back or so.


It uses WebKit rather than Gecko due to the appstore restrictions though


And it's not available on the AppStore for U.S. people yet (I had to build it myself).


We will do a global release soon.




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

Search: