Re: DRAM unreliable under specific access patern

From: Pavel Machek
Date: Wed Dec 24 2014 - 12:25:16 EST


On Wed 2014-12-24 09:13:32, Andy Lutomirski wrote:
> On Wed, Dec 24, 2014 at 8:38 AM, Pavel Machek <pavel@xxxxxx> wrote:
> > Hi!
> >
> > It seems that it is easy to induce DRAM bit errors by doing repeated
> > reads from adjacent memory cells on common hw. Details are at
> >
> > https://www.ece.cmu.edu/~safari/pubs/kim-isca14.pdf
> >
> > . Older memory modules seem to work better, and ECC should detect
> > this. Paper has inner loop that should trigger this.
> >
> > Workarounds seem to be at hardware level, and tricky, too.
>
> One mostly-effective solution would be to stop buying computers
> without ECC. Unfortunately, no one seems to sell non-server chips
> that can do ECC.

Or keep using old computers :-).

> > Does anyone have implementation of detector? Any ideas how to work
> > around it in software?
> >
>
> Platform-dependent page coloring with very strict, and impossible to
> implement fully correctly, page allocation constraints?

This seems to be at cacheline level, not at page level, if I
understand it correctly.

So the problem would is: I have something mapped read-only, and I can
still cause bitflips in it.

Hmm. So it is pretty obviously a security problem, no need for
java. Just do some bit flips in binary root is going to run, and it
will crash for him. You can map binaries read-only, so you have enough
access.

As far as I understand it, attached program could reproduce it on
affected machines?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
/* -*- linux-c -*-
*
* Try to trigger DRAM disturbance errors, as described in
*
* https://www.ece.cmu.edu/~safari/pubs/kim-isca14.pdf
*
* Copyright 2014 Pavel Machek <pavel@xxxxxx>, GPLv2+.
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void disturb(char *where)
{
unsigned int i;
for (i=0; i<0x1000000; i++) {
__asm__ __volatile__(
"movl 0(%0), %%eax \n" \
"movl 64(%0), %%eax \n" \
"clflush 0(%0) \n" \
"clflush 64(%0) \n" \
"mfence"
:: "r" (where)
: "eax"
);
}
}

int main(int argc, char *argv[])
{
long size = 1*1024*1024;
long i;
unsigned char *mem;

mem = malloc(size);
memset(mem, 0xff, size);

for (i=0; i<128; i+=4)
disturb(mem+i);

for (i=0; i<size; i++)
if (mem[i] != 0xff)
printf("At %lx, got %x\n", i, mem[i]);
}