Monorail Project: project-zero Issues People Development process History Sign in
New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 16 users
Status: Fixed
Owner:
Email to this user bounced
Closed: Mar 2015
Cc:



Sign in to add a comment
Rowhammer: Linux kernel privilege escalation PoC
Reported by cevans@google.com, Mar 9 2015 Back to list
The issue is a placeholder for the PoC for a working Linux privilege escalation for the "rowhammer" DRAM vulnerability.
 
run.sh
277 bytes View Download
privesc.cc
23.2 KB Download
target_prog.c
159 bytes Download
find_ptes.py
2.9 KB View Download
README
683 bytes View Download
qemu_runner.py
1.2 KB View Download
Comment 1 by cevans@google.com, Mar 9 2015
Labels: -Restrict-View-Commit
hey guys. Is there guy success this test?
I failed compile.
Comment 3 Deleted
Comment 4 Deleted
I tried running the full demo "run.sh" ( have to run it "sudo" to use KVM), but it hangs in "qemu_runner.py", waiting for input to the ReadLines() function.

When I get bored and break out of it, it reports this:
----%>< snip----
...
pte_pages=913408, pte_size=3568 MB, rate=44.5 MB/sec
Running target executable...
Hello world -- in innocent program
Test mode: Flipping bit at address b0702100...
  before:  val=0x8000000057b32027
  after:   val=0x8000000057a32027
  Changed bit 20 to 0
Searching for modified PTE...
  Found at index 0xdf23e20
  In page table 15 (out of 16 per mmap())
  Entry 0 contains 0x0
  Entry 32 contains 0x800000005c329027
Modifying PTE...
Searching for page that uses this PTE...
  Found at index 0xbdc7601
  Points to 0xf000ff53f000ff53
Running target executable...
Escape!

Test mode: Cleaning up: Undoing bit flip
Test mode: Flipping bit at address b0702100...
  before:  val=0x8000000057a32067
  after:   val=0x8000000057b32067
  Changed bit 20 to 1
** exited with status 0 (0x0)
^Cqemu: terminating on signal 2
Traceback (most recent call last):
  File "qemu_runner.py", line 57, in <module>
    Main()
  File "qemu_runner.py", line 45, in Main
    for line in ReadLines(os.fdopen(read_fd, 'r')):
  File "qemu_runner.py", line 11, in ReadLines
    ch = stream.read(1)
KeyboardInterrupt

Hey, prof,mon...
What is your machine(OS, RAM)?
> #6 william....@gmail.com
> Hey, prof,mon...
> What is your machine(OS, RAM)?

I built a Linux kernel, 3.19.1, with pretty much stock options except for disabling CONFIG_STRICT_DEVMEM (also turned off Bluetooth).  Ran it in a VM on a Ubuntu 14.04 physical host w/ 6GB of RAM.  If I understand the "qemu_runner.py" script correctly, it gave the VM 4000 megabytes of memory.
> Running target executable...
> Escape!

That shows that the exploit worked -- the test passed.
Comment 9 by rehiz...@gmail.com, Mar 16 2015
This doesn't have payload, right?
@comment #9: The proof-of-concept code linked above just overwrites a test executable with code that calls write() and then _exit().  It's a trivial payload, for test purposes, but it wouldn't be difficult to modify it to call execve() instead.
in privesc.cc:565, I'm confused what does target_pt_size mean?

target_pt_size = memory_size - file_size

what does "memory_size - file_size" mean?

in my test, the final file_size is 32M, and the iterations is 57088, and the reverse_size is 1784G!!!!

Is there something wrong? How can it be that large?
target_pt_size is the amount of physical memory we're aiming to fill with page tables, in bytes.

reserve_size is the amount of virtual address space we're mmap()'ing, in bytes.  It's fine for this to be 1784 GB, because it's not all backed by unique pages of physical memory.  1784 GB of virtual address space requires 1784 / 512 = 3.48 GB of page tables to map.
Hi, I ran the test but the system hangs up with the  following output:
117 blocks
use_kvm=True 
I just stopped after a while but I didn't see it outputs anything. Can anyone make me what am doing wrong here?
Also attached a screenshot for your reference. Am using Samsung NP300E5C 
OS: ubuntu 12.04
kernel: linux 3.2-0-29 generic
and the bZImage I build its from Linux kernel 3.18.1.

Comment 14 Deleted
I installed qemu that also runs the same ubuntu 12.04 .Screenshot of my output below
Screenshot from 2015-05-11 14:04:42.png
460 KB View Download
compilation failed!

privesc.cc: In function ‘BitFlipper* find_bit_flipper(const char*)’:
privesc.cc:258:28: error: expected ‘)’ before ‘PRIx64’
privesc.cc:261:61: error: spurious trailing ‘%’ in format [-Werror=format]
privesc.cc:261:61: error: too many arguments for format [-Werror=format-extra-args]
cc1plus: all warnings being treated as errors

@comment #16: What system are you compiling on?
output of uname -a

Linux localhost 3.18.0-kali3-amd64 #1 SMP Debian 3.18.6-1~kali2 (2015-03-02) x86_64 GNU/Linux

however, I've tried to solve the problem changin this code:
line 257:
int got = fscanf(fp, "RESULT PAIR,"
                     "0x%" PRIx64 ","
                     "0x%" PRIx64 ","
                     "0x%" PRIx64,
                     &addrs.agg1, &addrs.agg2, &addrs.victim);

to this code:

int got = fscanf(fp, "RESULT PAIR,"
                     "0x%lu", &addrs.agg1, ","
                     "0x%lu", &addrs.agg2, ","
                     "0x%lu", &addrs.victim);

and removed the $cflags in the compilation.. in this way it compiles but I don't really know if I'm breaking something.

When I run it ask me for:
Usage: ./init <bit-flip-addrs-file>

Which input should I provide?

Thanks for your time!




PRIx64 is normally #defined by inttypes.h.  If it's not #defined, there's something not right with the C library headers provided by the Linux distro you're using.

The input file is a list of physical addresses of victim/aggressor locations where bit flips occur, in the format described here:
https://github.com/google/rowhammer-test/tree/master/extended_test

"rowhammer_test_ext" from that Git repo can generate such a file.
Sign in to add a comment