An introduction to reverse-engineering x86 microcode and writing it
media.ccc.de
media.ccc.de
AMD microarchitecture exploration seems to have progressed quite a lot farther than Intel in general -- Google "9C5A203A" for some more interesting reading...
As the speakers in this talk point out, open microcode would allow extending the CPU with brand-new capabilities, including not only high-performance instrumentation frameworks, but also, I think, nearly-free ASAN-like and CFG-like runtime safety checks.
Is security a reason not to open the microcode architecture? I don't think so. I know this talk happened at CCC, but I don't see the security consequences of open microcode being severe: if you're in a position to install a microcode update, you've already won.*
Backward compatibility? Sure. Microcode can change generation-to-generation, or even stepping-to-stepping. Public microcode programs would have to be written with the understanding that no stability is guaranteed. But you can still get a lot of useful work done that way --- for example, people write Linux kernel drivers all the time.
Trade secrets? Eh. Does it really matter whether a processor has 32 or 64 internal temporary registers? I'm not sure what secrets proprietary microcode might protect against an adversary that has a dedicated chip design team and electron microscopes.
So, yeah, this talk represents impressive work, but none of this work should be necessary. Then again, if wishes were horses, beggars would ride. We can't even get Intel to ship a processor without the damn management engine.
* Granted, microcode backdoors have the virtue of being subtle and easy to hide. This paragraph doesn't apply if microcode updates let you break the processor's internal security model, but it sounds like, from the talk, that microcode obeys security invariants.
The development cycle could be littered with dead processors, but worse for Intel, if a widely used microcode has a very infrequent chip stressing flaw it will manifest as “Intel chips aren’t reliable.”
EDIT: http://vswww.kaist.ac.kr/ENGLISH/old_lecture/ee878-2002/lect...
It probably does not imply that the chip is indestructible through microcode though.
Selecting a register through a tri-state based bus demands a circuit with a O(1) critical path. Selecting a register through a logical selector demands a circuit with O(log n) critical path, and a large constant factor.
and how much are you really going to enable? some funny bit ops? some explicitly interleaved fetch and computation? its pretty cool to try to understand things, but is it worth it for Intel? alot of stuff seems to baked in hardware too...pretty sure the cache coherency protocol isn't on the table...maybe some different concurrency primitives?
They are default the now though. As far as I know hardwired control logic wasn't used for very long before people moved to using microcode. Maybe I am misunderstanding that part of your comment?
Can we assume you must be kidding too when you use the phrase "Normal CPU architectures"?
Besides obvious documentation, tools and dev.support costs, also compatibility cost. Currently Intel/AMD can change the microarchitecture however they see fit, potentially even between revisions, as long as the instruction set stay stable.
Changing the microarchitecture itself is not trivial either, and you can bet that they've got it all documented internally along with tools and whatever else. They could just open it up, as in post everything on their website for download --- they don't have to provide "support". The only real reason they don't is because there are things in there that they don't want the world to know.
Major changing is not trivial. However I can see how they can implement minor tweaks between revisions that don’t affect their main interface (i.e. AMD64 instruction set + extensions) but do affect microcode.
> you can bet that they've got it all documented internally
I’ve worked in a couple of large US software companies. I won’t point fingers but the internal documentation I’ve worked with wasn’t OK. The only exceptions is when the company provided a public API. When that was the case, they allocated resources (developer’s time, plus sometimes a technical writer position) and did the job.
> along with tools and whatever else
Legal issues are likely. E.g. GPL-licensed code is fine in an internal tool, but if you want to distribute it, you have to also distribute the source code of everything else that’s linked. Sometimes you don’t want to, other times you just can’t (if it links to a commercial library you’ve bought).
> because there are things in there that they don't want the world to know
I don’t eliminate the possibility but I don’t think that’s likely. As you see, there’re pragmatic reasons (i.e. money) why they aren’t doing that.
The good thing is, if anyone (Intel, AMD, I dunno, Apple, Qualcomm) will do that, and it will indeed deliver a great value to the users (such as free ASAN), the rest of them will do the same really fast, because competition.
Soft flashed roms must be cryptographically signed anyway... the main danger is surely in making various types of timing attacks or side-channel attacks substantially easier to derive, usually those attacks are inferred with great effort. The argument of security through obscurity is more complex compared to higher level software, it's not purely about finding bugs and refining implementation.
Exactly this is why CPU vendors won't do anything in that regard. They don't want people to have a way to avoid upgrading the hardware by buying a new processor.
You can implement entirely new instructions in microcode.
The connection to this talk is that they demo triggering a backdoor hidden in microcode by executing some WebAssembly code in an up-to-date FireFox.
With that in mind, what realistically is possible to do, over than to declare that everything can only be read as plain text (and hope there's no exploitable bugs in font rendering of system fonts)?
(The latter is an annoyance, BTW: there's no reason to treat Java bytecode, say, differently from PROT_EXEC pages. Executable protection should have nothing to do with active or inactive list membership.)
Also, JavaScript and WebAssembly (the latest starting with this talk) are actively used for unauthorized access to computers. It's not like I'm pointing out theoretical attack possibilities. This makes the matter more urgent.
JS does provide some very valid use-cases, and two of them that come to mind are interactivity and displaying static data that has no neat representation in HTML (e.g., Mathjax and d3.js for charting).
My point is that JS is far from the only massive, complex, potentially security-laden hole in a modern web browser. Audio/video codecs are notoriously complex, and font rendering also has this nasty habit of causing kernel crashes on Windows. These have been used for active exploits. The way you achieve security is you have to look at the risks and work out ways to mitigate them. There are ways to be quite secure even allowing JS execution.
Giving an attacker a JIT makes it easier for them to lay out memory with the NX bit set to zero (executable memory) that they can later jump into.
Return-oriented programming can still be used to hijack a program that whose executable parts are locked down at runtime, having a JIT just makes things easier.
This argument has been rehashed over and over again. Some of the mass appeal of the web, as a platform, is that random arbitrary code can be downloaded and run inside a sandbox. It appears that these web technologies will continue to be used regardless of any security implications.
If users demand something like JavaScript or WebAssembly, do you have an alternative proposal to satisfy them?
Users don't demand JavaScript nor WebAssembly, some developers do. Users want to easily discover new programs/games/whatever. If they were presented those equally easy and convenient in another form, they wouldn't even care.
Those developers that demand JavaScript and WebAssembly have mostly interests that go against the interests of the users. The developers might want to hide parts of their code or underlying data from the user, or force presentation in a certain form (ads), or avoid the orderly way of delivering software through proven ways like distributions, possibly to achieve the former two goals.
Now, where does Mozilla stand in this conflict? I realize they don't stand where I thought they would stand.
I want the web, but without random drive-by code execution. Code must be delivered by other, more accounted for ways.
Exactly. One of the biggest use-cases I see for JS/Wasm is in implementing DRM obfuscation and more insidious advertising/tracking code.
This is stating the obvious, but...
For anything even mildly interactive, JavaScript is absolutely essential to creating a good (or even bearable) user experience. With purely static HTML, every interaction requires a page reload, which is painful. Users absolutely do want modern, low-latency UX.
Moreover, you literally cannot build things like Slack or Google Docs without JavaScript. Users want these products. HTML-only GMail is barely possible but it's really painful to use. Users want GMail with JavaScript.
Maybe you don't want these things. Maybe you are happy with pure-HTML interfaces, or doing anything interactive through dedicated native apps. But there are very few people who prefer it that way. Please don't presume to speak for all users, or accuse Mozilla of working against users, when it's your specific needs that are unusual.
I agree that HTML-only GMail in the browser right now is a mess, but that's because a browser is not an e-mail client, and shouldn't be one.
People are trained for certain behaviours and often don't want to change from that. On the other hand they like new shiney software and things to try out. That explains in my eyes why for example Google Docs (seriously, office editing in the browser?!) is used. Also, Google has a good reputation for software.
I think most people are simply not aware of the dangers, downsides and alternatives of this approach. The behaviour was learned when people talking about a globally snooping NSA were called crackpots.
On top of that, Google has no business interest in offering a standalone office solution, so people either use Google Docs in their browser, or not at all. Supply creates its own demands.
How discoverability and ease of obtaining trusted code is solved, is a technical problem. I could imagine markup-only webpages which can call locally installed programs to appear in the tab, but the prorams are installed in trusted ways. That's just one spontaneous idea.
Mozilla is making it easier for people to use technical solutions that are suboptimal for them. This has a network effect and shapes the web to be a worse place. That is what I accuse Mozilla of, and I stand by it.
HTML is capable of very specific, fixed functions. Sure, video is one of them. But video is not very interactive. You press play, and then you watch. Interactivity in plain HTML is very difficult.
> People are trained for certain behaviours and often don't want to change from that. On the other hand they like new shiney software and things to try out.
No no. People don't use these products because they were "trained" for it. The world of installed native applications existed before the web. The web took off because it's actually way better for many people. Not having to manage installing apps is awesome. Being able to access your data from multiple devices trivially is awesome. Not having to worry about backups is awesome. Being able to collaborate in real time is awesome. People don't just like this stuff because it's "shiney", they like it because it's really, genuinely useful.
> I could imagine markup-only webpages which can call locally installed programs to appear in the tab, but the prorams are installed in trusted ways.
That would actually be way less secure, because those locally-installed programs are almost certainly not security reviewed to the extent that the JavaScript sandbox is. They are far more likely to have exploitable bugs than your JavaScript sandbox. It doesn't matter that you "trust" them.
In practice, the vast majority of programmers do not know how to write secure code. We can't realistically fix that. The answer is to give them programming environments where they can't get it wrong, or at least they can only hurt their own app. We accomplish that with sandboxing.
That the local and native programs are not as good as the browser-based abominations is no argument for that technology; there are reasons for the businesses to choose this way despite (or because) how bad it is for users.
Code that comes for example from a distribution is signed and maintained by someone I can easily identify. It is looked at by more than the author. I can track the path of the code backwards, if something nefarious happens. That justifies trust in that code.
The comparison of that code with the JavaScript sandbox is invalid, it's to be compared with the delivered JavaScript. There is no reason why even trustably delivered code shouldn't be sandboxed. The comparison of that sandbox with the JavaScript sandbox would be apt.
I agree that sandboxing is important, even for local programs.
But you're still in denial about the fact that web app delivery is hugely valuable to a lot of people (yes, to users). This isn't even remotely debatable. SaaS is now a $100B/yr industry and growing rapidly. People wouldn't be rapidly replacing locally-installed apps with SaaS if they didn't really want it.
You really can't just proclaim that everyone should give all that up based on your ideology about how software "should" be delivered.
The size of the market is no argument. Supply drives demand.
I don't simply proclaim how things should be done. I point out problems, criticize the status quo based on sound facts, and point to better solutions. What else do you suggest?
There's no shortage of supply of desktop apps, yet web apps are gaining ground rapidly. This indicates that people prefer web apps for some reason.
> What else do you suggest?
Build it. If you truly have a solution that is better for users, then you can make a lot of money if you bring it to market. Then you not only prove you were right, but you make the world a better place and get rich in the process. :)
But somehow you're going to need to make desktop apps significantly better than they are today. You won't win by telling users that their preferences are wrong, you win by giving them something better.
In those cases, it's certainly easier to use javascript, though.
In the meantime, before they deliver "non-programmable HTML6", they deliver HTML 5.2 (or was it .3?) with DRM inside. Mozilla? They produced buggy, resource-hungry browser for decade (was less resource-hungry than competition, now the same). What to expect from them? These Xmas time, when opening a new empty browser page, they show an ad phishing me for money. And that's exactly what everyone expects from them.
The stories about HTML with DRM and unsolicited adds from Mozilla were discussed here on HN. So again, no idea what tinfoil hat you wear, but godspeed with keeping it up.
These are three reasons why developing and supporting WebAssembly is finally against the interest of the users.
The harder, less efficient and cumbersome this type of drive-by code deployment is, the less attractive and used it'll be.
Also, sandboxing helps only until it doesn't. It's a futile task, especially when we don't have complete control of the hardware, which we don't, because the chip developers don't tell us complete specificiations and functionality.
Regardless, it’s a trade off. Although I agree we should have a web that doesn’t need JavaScript to function - I believe that is a separate argument - I think in this case, while we already have it, I’ll take WebAssembly for the speed and new applications it helps support.
I certainly wouldn’t want to see “Web Assembly” blobs in my browser that I’m not allowed to inspect, which again is another argument, IMO.
> Also, sandboxing helps only until it doesn't. It's a futile task,
It really isn't futile. How many major security holes in Chrome's sandbox have actually done serious damage? Yes, they happen from time to time, but not that often, and they are automatically patched shortly after (or before) disclosure, making them really uninteresting for attackers to try to exploit.
Realistically, the biggest security threat to real users is phishing or similar deception. Many users can be fooled by a page that looks like an error from their operating system telling them that their computer has a virus and they should download a tool to fix it. You don't need JavaScript for that.
Realistically, the highest-impact non-user-error security problems are logic flaws in complicated server code that never intended to run attacker-supplied code in the first place. Think SQL injection, confused deputies, missing access control checks, buffer overruns, SMB (Windows file sharing) bugs exploited by worms, etc.
Ironically, modern JavaScript sandboxing is so good -- with so much careful scrutiny by really smart security researchers -- that realistically it's not remotely the easiest target on your system these days. The easy targets are the software that isn't written with security in mind, and the users themselves (phishing).
> especially when we don't have complete control of the hardware, which we don't, because the chip developers don't tell us complete specificiations and functionality.
JavaScript and WebAssembly don't have direct access to hardware. WebAssembly is not assembly, it's a platform-neutral bytecode that gets recompiled for the host after download.
It is because WASM does not allow self-modifying code, which is a highly effective obfuscation technique as it can hinder static analysis. On the other hand, JavaScript has eval among other things that can be used to dynamically craft and execute code during execution. I've never seen such JavaScript but it would be quite cumbersome to trace code within a call to eval within a call to eval, and so on. You might need to build a custom V8 to record strings passed to eval when reversing such code.
This is absolutely not true if you have a MMU and something like a protection ring. In such an environment code by default can do nothing malicious. The only thing making it insecure in any way are the syscalls offered by the operating system.
Exploiting HTML or font rendering is more work, but as you still run known instructions in a known sequence processing known data the primitives are still there. The same can happen for anything that processes foreign data, be it script, video, images or just CSV.
I see your point. However, if it's harder for the attacker, it is already a win. Also, this is just one example where JavaScript/WebAssembly are used to deliver/activate malware. There are many other examples.
Besides that, even if JavaScript/WebAssembly implementations were provably secure (which they aren't), I would be against them for the other reasons I described in other comments here.
So, are your concerns about side channel attacks? Side channels are nothing more than undocumented (and sometimes unfixable) logical features. Opening the microcode for inspection and making it patchable will only reduce the number of undocumented features.
Please take my opinions as my own.
I don't mean to justify but rather to give context when I say that these discussion are not easy because there are lots of arguments and comments of varying degree of quality and emotional content, and contradicting voting. It's hard to represent an unpopular opinion. Still no justification whatsoever.
Mozilla's decisions speak for themselves. There is no need to reference individuals, and less so without very solid basis (which there wasn't).
AFAIK the Intel ones use public-key encryption[1], so you would not really gain anything. They obviously thought of this.
[1] http://inertiawar.com/microcode/ - 2048-bit RSA too, so not really breakable in the near future either.
Without the processor oracle, it would have been hard to impossible to start guessing the semantics of bitstrings. Also the physical ROM bits are not in the same order as the bits the CPU actually excutes during runtime. The mapping function is non trivial and we do not fully understand it yet. Finding this function required knowing what valid, plaintext microcode looks like so we could match the bitstrings from the ROM to it.