In 2016, I noticed a quirk of the x86 architecture that leads to an interesting side channel. On x86, it is possible for a userland process to detect when it has been interrupted by an interrupt handler, without resorting to timing. This is because the usual mechanism for handling interrupts (without using virtualisation) doesn't always preserve all userland registers across an interrupt handler.…
Here's an interesting report of skulduggery related to the rowhammer bug . PassMark say they received an offer to not release a rowhammer test in their MemTest86 tool, in return for payment: "We had anonymous contact offering to act as a go between between us and unnamed memory companies, with a view to paying us not release the new version of MemTest86. Who knows how serious the offer was.…
Handles on Windows are analogous to file descriptors (FDs) on Unix, and both can be passed between processes. However, the way in which handles/FDs can be passed between processes is quite different on Unix and Windows. In this blog post I'll explain the difference. You might find this useful if you are familiar with systems programming on either Unix or Windows but not both. Similarities I'll…
There are indications that it is possible to cause bit flips in memory by row hammering without using CLFLUSH , using normal cached memory accesses. This makes me wonder: Is it possible to do double-sided row hammering using cached memory accesses, or only single-sided row hammering? The former is more likely to cause bit flips, and might be the only way to cause bit flips on some machines, such…
In my previous blog post , I discussed how Intel Sandy Bridge CPUs map physical addresses to locations in the L3 cache. Now I'll discuss how these CPUs' memory controllers map physical addresses to locations in DRAM -- specifically, to row, bank and column numbers in DRAM modules. Let's call this the DRAM address mapping . I'll use one test machine as a case study. Motivation: the rowhammer bug I…
In 2013, some researchers reverse-engineered how Intel Sandy Bridge CPUs map physical addresses to cache sets in the L3 cache (the last-level cache). They were interested in the cache mapping because it can be used to defeat kernel ASLR . I'm interested because the cache mapping can be used to test whether cached memory accesses can do row hammering (which can cause exploitable bit flips in some…
I've been researching the DRAM rowhammer issue and its security implications for a while. We've finally published our findings on the Project Zero blog: Exploiting the DRAM rowhammer bug to gain kernel privileges .
Is it better to use #ifdef PLATFORM or #if PLATFORM when writing code that needs to be conditionalised according to OS, CPU architecture, etc.? Chromium's codebase uses the former. For example, it uses #ifdef OS_WIN or #if defined(OS_WIN) , where OS_WIN is #define d on Windows (by build/build_config.h ) and undefined elsewhere. In contrast, NaCl's codebase uses the latter. It uses #if NACL_WINDOWS…
The Mill is a new CPU architecture that claims to provide high performance but at a much better performance-per-watt than conventional CPUs that use out-of-order execution. The Mill achieves this by making various architectural simplifications. One of those is to remove the TLB from the fast path of memory accesses. Rather than having the TLB between the CPU core and the cache, the Mill's TLB is…
Merging in Git is usually not history-sensitive. By this I mean: if you're merging branches A and B together, Git looks at the content at the tips of branches A and B, and the content of the common ancestor commit(s) of A and B, but it doesn't look at any commits inbetween. Git just does a 3-way merge. This can make merging more painful than it needs to be. History-sensitive merging is a merge…
Mac OS X is a curious operating system because its kernel is derived from two kernel codebases -- the Mach kernel and a BSD kernel -- that have been glued together. From these two ancestors, OS X inherits two different mechanisms for processes to handle hardware exceptions (a.k.a. faults): POSIX signals: In-process only. Registered per-process. The handler is always called on the thread that…
Lately I've been working on Portable Native Client ("PNaCl" for short). Native Client (NaCl) is a sandboxing system that allows safe execution of native code in a web browser -- typically C/C++ code compiled to x86-32, x86-64 or ARM native code (with some support for MIPS too). The problem with NaCl has always been that you have to compile your program multiple times, once for each target…
Last year, I found a security hole in Native Client on 64-bit Windows that could be used to escape from the Native Client sandbox. Fortunately I found the hole before Native Client was enabled by default in Chrome. I recently wrote up the document below to explain the bug and how we fixed it. Native Client currently relies on a small, process-local, in-memory patch to NTDLL on 64-bit versions of…
Recently, I've been looking at how x86-64 Windows does stack unwinding in 64-bit processes, and I've found some odd behaviour. If the stack unwinder finds a return address on the stack that does not have associated unwind info, it applies a fallback unwind rule that does not make much sense. I've been wondering if this could make some x86-64 programs more easily exploitable if they corrupt the…
If you're familiar with the ARM architecture you'll probably know that self-modifying code has to be careful to flush the instruction cache on ARM. (Back in the 1990s, the introduction of the StrongARM with its split instruction and data caches broke a lot of programs on RISC OS.) On ARM Linux there's a syscall, cacheflush , for flushing the instruction cache for a range of virtual addresses. This…
Last year I wrote a blog post, "The trouble with Buildbot" , about how Buildbot creates a dilemma for complex projects because it forces you to choose between two ways of describing a project's build steps: You can describe build steps in the Buildbot config. Buildbot configs are awkward to update -- someone has to restart the Buildbot master -- and hard to test, but you get the benefit that the…
Although Chrome's sandbox does not protect one web site from another in general, it can provide such protection in some cases. Those cases are ones in which HTTP cookies are either reduced in scope or not used at all. One lesson we could draw from this is that cookies reduce the usefulness of Chrome's sandbox. The scenario we are exploring supposes that there is a vulnerability in Chrome's…
A common misconception about the Chrome web browser is that its sandbox protects one web site from another. For example, suppose you are logged into your e-mail account on mail.com in one tab, and have evil.com open in another tab. Suppose evil.com finds an exploit in the renderer process, such as a memory safety bug, that lets it run arbitrary code there. Can evil.com get hold of your HTTP…
Inserting printf() calls is often considered to be a primitive fallback when other debugging tools are not available, such as stack backtraces with source line numbers. But there are some situations in low-level programming where most libc calls don't work and so even printf() and assert() are unavailable luxuries. This can happen: when libc is not properly initialised yet; when we writing code…
In my last blog post , I described one of the features in FreeBSD-Capsicum : process descriptors. Now it's time for an overview of Capsicum. Capsicum is a set of new features for FreeBSD that adds better support for sandboxing, using a capability model in which the capabilities are Unix file descriptors (FDs). Capsicum takes a fairly conservative approach, in that it does not make operations on…
Capsicum is a set of new features for FreeBSD that adds better support for sandboxing, adding a capability mode in which the capabilities are Unix file descriptors (FDs). The features Capsicum adds are orthogonal, which is nice. One of the new features is process descriptors . Capsicum adds a replacement for fork() called pdfork(), which returns a process descriptor (a new type of FD) rather than…
Git's model of changes (which is shared by Mercurial, Bazaar and Monotone) makes it awkward to revise earlier patches. This can make things difficult when you are sending out multiple, dependent changes for code review. Suppose I create changes A and B. B depends functionally on A, i.e. tests will not pass for B without A also being applied. There might or might not be a textual dependency (B…
Although modern version control systems have improved a lot on CVS, I get the feeling that there is a fundamental version control problem that the modern VCSes (Git, Mercurial, Bazaar, and I'll include Subversion too!) haven't solved. The curious thing is that CVS had sort of made some steps towards addressing it. In CVS, history is stored per file. If you commit a change that crosses multiple…
The trouble with Buildbot is that it encourages you to put rules into a Buildbot-specific build configuration that is separate from the normal configuration files that you might use to build a project (configure scripts, makefiles, etc.). This is not a big problem if your Buildbot configuration is simple and just consists of, say, "svn up", "./configure", "make", "make test", and never changes.…
Here is a useful trick I discovered recently while debugging some changes to the seccomp sandbox . To trigger a breakpoint on x86, just do: __asm__("int3"); Then it is possible to inspect registers, memory, the call stack, etc. in gdb, without having to get gdb to set a breakpoint. The instruction triggers a SIGTRAP, so if the process is not running under gdb and has no signal handler for SIGTRAP,…