How Rowhammer Works: Flipping Bits in Memory You Were Never Allowed to Touch

How Rowhammer Works: Flipping Bits in Memory You Were Never Allowed to Touch

Written by

in

Rowhammer is a hardware level attack that flips bits in memory the attacker was never allowed to touch. It works because DRAM stores each bit as a tiny charge in a cell, the cells are packed extremely close together, and repeatedly activating one row of cells leaks charge into the physically adjacent rows. Do it fast enough, often enough, and a bit in a neighboring row changes from a one to a zero or back, with no read or write permission on that row required. The bug lives below the software stack entirely, in the silicon, which is what makes it so unsettling. This post walks the mechanism one step at a time: how a DRAM cell holds a bit, what the activate and precharge cycle is, why the disturbance appears, how an attacker turns a random flip into a broken security boundary, and what the later browser and mobile variants and the ECC and TRR defenses actually do.

What rowhammer is, in one paragraph

A DRAM chip is a grid of cells, each a capacitor that holds a charge and a transistor that gates access to it. Charge present means one logical value, charge absent means the other. The cells are organized into rows, and reading or writing any cell means activating the whole row it sits in. The discovery behind rowhammer, published by Yoonsung Kim and colleagues at ISCA 2014, is that hammering one row over and over, activating it thousands of times in a short window, disturbs the charge in the rows next to it enough to corrupt their stored bits. The attacker reads and writes only rows they are allowed to touch. The damage lands in a row they are not. That gap between what the attack accesses and what it corrupts is the whole story, and it is why the original paper is titled Flipping Bits in Memory Without Accessing Them.

How a DRAM cell stores a bit

Start at the bottom. A single DRAM cell is one capacitor and one transistor. The capacitor either holds a charge or it does not, and that presence or absence is the bit. The transistor is a switch that connects the capacitor to a wire called a bitline when you want to read or write it. Because a capacitor leaks charge over time, DRAM is dynamic: every cell has to be refreshed periodically, read out and written back, or the bit decays into noise. On commodity hardware that refresh happens on a fixed interval, traditionally every 64 milliseconds for the whole array.

Cells do not stand alone. They are wired into a grid of rows and columns. All the cells in one row share a wire called a wordline, and all the cells in one column share a bitline. To touch any cell, the chip raises the voltage on that cell’s wordline, which switches on every transistor along the row at once and connects all of those capacitors to their bitlines. You cannot read a single cell in isolation. You read its entire row into a buffer, then pick the column you wanted.

The activate and precharge cycle

Getting at a row is a two step dance. First the memory controller issues an activate command for the row. That raises the wordline, dumps the row’s charges onto the bitlines, and latches the result into a strip of sense amplifiers called the row buffer. Now the row is open and its columns can be read or written quickly. When you are done with that row and want a different one in the same bank, the controller issues a precharge, which closes the open row, writes its contents back into the cells, and resets the bitlines to a neutral level so the next activate can begin cleanly.

Every activate sends a voltage swing down a wordline that runs right past its neighbors. A single activate is harmless. The trouble is what happens when you force the same row through the activate and precharge cycle again and again, as fast as the chip allows, thousands of times before the next scheduled refresh comes around to repair the neighbors. That is the literal hammering in rowhammer.

Why shrinking process nodes made the disturbance appear

This was not a problem on older, larger memory. As DRAM makers shrank the process node to pack more capacity into the same die, the cells moved physically closer together and each capacitor got smaller, holding less charge to begin with. Closer cells mean stronger electrical coupling between a wordline and its neighbors, and smaller charge means a flip needs less disturbance to push a cell across its threshold. Past a certain density the repeated voltage activity on one row started leaking enough into adjacent rows to corrupt them before the periodic refresh could top them back up. The ISCA 2014 study tested modules from the three major vendors and found a large majority of recent DRAM modules vulnerable to these disturbance errors. The defect is not a manufacturing mistake in one batch. It is a consequence of how dense modern DRAM has to be, and it gets harder to avoid, not easier, as each generation packs the cells tighter.

From a hammer to a bit flip: single sided and double sided

Knowing that hammering corrupts neighbors, the next question is how to hammer effectively. Two refinements matter, and both come down to a detail of the activate cycle: a row only disturbs its neighbors while it is being opened and closed, so you have to keep forcing fresh activates rather than reading the same already open row.

To guarantee that, an attacker accesses two different rows in the same bank in a tight loop and flushes them from the CPU cache between accesses, so each loop iteration forces a real activate down to the chip instead of being served from cache or the row buffer. This is single sided hammering: pick a couple of aggressor rows, pound them, and hope the disturbance lands on whatever victim row happens to sit beside one of them. The cache flush is the subtle part. Modern CPUs cache memory aggressively, so a naive loop that reads the same address repeatedly never reaches the DRAM at all; the second read onward is served from cache and the chip is never activated. Early proofs of concept used an explicit cache flush instruction, on x86 the clflush instruction, to evict the line after each access and guarantee the next read goes all the way down to the memory chip. Two aggressor rows in the same bank also help here, because alternating between them forces the row buffer to close one and open the other every time, which is exactly the activate and precharge churn that produces disturbance.

Double sided hammering is sharper. A row has two immediate neighbors, the one above and the one below. If the attacker can hammer both of a victim row’s neighbors, the rows at position N minus one and N plus one, the victim row in the middle absorbs disturbance from both sides at once. Project Zero found this technique flipped vastly more bits and was necessary to get results on many of the machines they tested. Double sided hammering needs the attacker to know which physical rows are adjacent, which takes some reverse engineering of how addresses map to rows, but the payoff is a much higher flip rate on a chosen target.

Weaponizing a flip: the page table entry attack

A random bit flip somewhere in physical memory is, on its own, just a crash or a glitch. Turning it into a security boundary break is the hard and clever part, and the canonical demonstration is the 2015 Google Project Zero post Exploiting the DRAM rowhammer bug to gain kernel privileges, by Mark Seaborn and Thomas Dullien. They built two working exploits on real Linux machines.

The first targets page table entries. On a modern system the operating system keeps page tables that map a process’s virtual addresses to physical memory, and each page table entry, a PTE, names a physical page and the permissions on it. The attack works like this. The exploit first sprays memory so it is filled almost entirely with the process’s own page tables, then hammers until it finds a flip that lands inside a PTE. If the flipped bit changes the physical page number that the PTE points at, there is a good chance the PTE now points at a page that is itself one of the attacker’s page tables. The moment that happens, the process has a writable mapping of its own page table. It can edit page table entries directly, point them at any physical page it likes, and from there it has read and write access to all of physical memory, including the kernel. That is full privilege escalation driven by a single well placed flip in a structure the attacker was never allowed to modify.

The attacker never writes to the page table. The hardware changes it for them, one bit at a time, from a row next door.

The second Project Zero exploit escapes the Native Client sandbox, NaCl, which was a way to run untrusted native code safely in the browser by validating that the code only used a restricted set of instruction sequences. The attack hammers the sandboxed code itself. NaCl enforces safe indirect jumps by masking the target address with a fixed instruction sequence, and a bit flip that changes a register number inside one of those sequences can turn a safe, validated jump into an unsafe one that lands on an unaligned address. From that misaligned landing the attacker reaches instruction bytes the validator never checked, including hidden syscall instructions, and breaks out of the sandbox. Two different boundaries, the kernel and the sandbox, both broken by the same physical effect.

Browser and mobile variants

The early proofs of concept needed special conditions, a native binary and often a cache flush instruction. The research that followed steadily stripped those requirements away, which is the part of the story that turned rowhammer from a lab curiosity into a broad concern.

Rowhammer.js: from the browser, no native code

Rowhammer.js, by Daniel Gruss and colleagues, showed that the attack could be triggered from plain JavaScript running in a browser, with no native binary and no special CPU instruction to flush the cache. The researchers built a memory access pattern that evicts cache lines using ordinary accesses alone, so that the hammering reaches DRAM even without a flush instruction available to scripts. That made rowhammer a remote concern: a flip could in principle be induced by visiting a web page, narrowing the gap between the hardware defect and an ordinary attacker.

Drammer: deterministic flips on Android and ARM

Drammer, from the VUSec group, carried the attack to mobile. It demonstrated rowhammer on ARM based Android phones and, importantly, made the exploit deterministic rather than probabilistic. It did this by abusing the phone’s memory allocator to land a page table in a physical location the attacker had already found to be flippable, so the flip reliably hit a useful target. Drammer was a root privilege escalation that relied on no software vulnerability at all, only the hardware bug, on a class of devices many people assumed were out of reach.

One location hammering

Later work showed that on some systems you do not even need two aggressor rows. One location hammering repeatedly activates a single row, relying on the memory controller’s row policy to keep closing and reopening it so each access becomes a fresh activate. It works where the controller uses a closed page or adaptive policy, and it further trimmed the conditions an attacker needs to satisfy.

Defeating the defenses: ECC and TRR

Two mitigations were widely treated as the answer to rowhammer. Research has shown both can be defeated, which is the honest state of the field, even though both still raise the bar.

Error correcting code memory and ECCploit

ECC memory adds redundant bits so the controller can detect and correct errors, typically correcting a single bit flip in a word and detecting two. The intuition was that rowhammer flips would simply be corrected away. ECCploit, from VUSec, showed this is not a clean defense. By using timing side channels to learn how the ECC scheme behaves and carefully arranging multiple flips in the same word, an attacker can engineer corruption that slips past correction. ECC raises the cost and the number of flips required, but it does not make a vulnerable module safe.

Target Row Refresh, TRRespass, and Half-Double

Target Row Refresh, TRR, is a defense built into DDR4 memory. The idea is that the chip watches for rows being activated unusually often and proactively refreshes their neighbors before a flip can develop, repairing the victim before the disturbance accumulates. It was marketed as the fix that closed rowhammer for good. It did not. TRRespass, from VUSec, showed that TRR implementations track only a limited number of aggressor rows at once, so an attacker who hammers many rows at the same time, a many sided pattern, can overwhelm the tracker and still flip bits on DDR4 modules that TRR was supposed to protect. Half-Double, demonstrated by Google, exploits a different gap: as cells shrink further the disturbance reaches beyond the immediate neighbor to rows two steps away, and the very act of TRR refreshing a near neighbor can itself contribute disturbance to a row further out. Both results say the same thing. The in chip mitigations narrowed the attack but did not end it.

What actually helps

No single mitigation closes rowhammer cleanly, so defense is layered. Increasing the refresh rate, refreshing the whole array more often than the standard interval, gives disturbance less time to accumulate before a victim row is repaired, at a cost in performance and power. ECC and TRR each raise the number of flips or the precision an attacker needs, even though neither is sufficient alone. The deeper fixes are in hardware: probabilistic or counter based schemes that track how often each row is activated and refresh threatened neighbors accurately, and successor memory standards that build stronger row activation tracking into the specification rather than leaving it to a vendor’s opaque, limited TRR logic. The direction of travel is to move the defense into the silicon where the bug lives, because nothing in software can stop a charge from leaking between two cells the manufacturer placed a few nanometers apart. There are also operating system and allocator level mitigations that try to keep security sensitive structures like page tables physically away from memory an attacker can hammer, which raises the difficulty of the targeting step even when the underlying flip is still possible.

It is worth being precise about what is demonstrated versus theoretical. The bit flips themselves, the PTE and NaCl exploits, the JavaScript and Android variants, and the bypasses of ECC and TRR are all demonstrated on real hardware in published research. What any given attacker can do against a specific deployed machine depends heavily on the exact memory modules, the controller policy, and the mitigations in place, and reliable exploitation in the wild is harder than a lab proof of concept. The bug is real and the exploits are real; the difficulty is in the targeting.

Rowhammer also sits near other low level boundary breaks. Once an attacker flips a PTE and gains arbitrary physical memory access, what follows is privilege escalation in the classic sense, climbing from an unprivileged process to kernel level control. The difference is where the leverage comes from. Here it does not come from a logic bug in code. It comes from the memory itself betraying the software running on top of it.

The assumption that breaks

Step back from the wordlines and the page tables and one assumption is holding everything up. Every piece of software running on a computer trusts that memory it did not write cannot change underneath it. A program reads back what it stored. The kernel assumes its page tables say what it set them to say. The whole edifice of memory protection, of one process being walled off from another, rests on the substrate being inert, a passive box that holds bits faithfully until something with permission changes them. Rowhammer is the discovery that the substrate is not inert. Charge leaks between cells that were supposed to be independent, and an attacker with no permission on a row can reach into it through the silicon and change what it holds. The boundary everyone drew at the permission check actually ran somewhere lower, in the physics of how the bits are stored, and that lower boundary was never enforced at all.

The bug is not a coding mistake you can find by reading the source. It is an assumption baked so deep into the model of computing that almost nobody thought to question it, that the hardware keeps your bits the way you left them. That kind of flaw, the unstated premise that the layer below you is trustworthy, is exactly what you find by asking what each layer trusts and why, rather than by scanning for a known bad pattern. It is the kind of assumption an autonomous researcher built to test assumptions is meant to catch, the ones nobody wrote down because they seemed too obvious to fail. Learn more about that approach on our about page.

Frequently asked questions

What is rowhammer and how does it flip bits?

Rowhammer is a hardware level defect in DRAM. Each bit is a charge in a tiny capacitor, the cells are packed very close together, and repeatedly activating one row leaks charge into the physically adjacent rows until a bit in those neighbors flips. The attacker reads and writes only rows they are allowed to touch, but the corruption lands in a row they are not. The seminal study by Kim and colleagues, Flipping Bits in Memory Without Accessing Them, first characterized this disturbance error across DRAM from all three major vendors.

What is the difference between single sided and double sided hammering?

Single sided hammering pounds a small set of aggressor rows and hopes the disturbance lands on whatever victim row sits beside one of them. Double sided hammering targets both immediate neighbors of a chosen victim, the rows at N minus one and N plus one, so the victim in the middle absorbs disturbance from both sides at once. Google Project Zero reported in Exploiting the DRAM rowhammer bug to gain kernel privileges that double sided hammering flipped vastly more bits and was necessary on many machines they tested.

How does a random bit flip become a kernel privilege escalation?

An attacker sprays memory with their own page tables, then hammers until a flip lands inside a page table entry and changes the physical page it points at. With luck the entry now maps one of the attacker’s own page tables as writable, giving them direct edit access to address translation and from there read and write access to all of physical memory, including the kernel. The full Project Zero writeup walks both this PTE attack and a Native Client sandbox escape.

Do ECC and Target Row Refresh stop rowhammer?

They raise the bar but neither is a clean fix. ECCploit showed that carefully arranged multiple flips in one word can slip past error correction, and TRRespass showed that Target Row Refresh tracks only a limited number of aggressor rows, so a many sided hammering pattern can overwhelm it and still flip bits on DDR4. The VUSec TRRespass project page documents how built in TRR defenses were bypassed on real modules from all three major vendors.