Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we determine the resting state of memory cells? #169

Open
dwalton64 opened this issue Jan 26, 2023 · 2 comments
Open

Can we determine the resting state of memory cells? #169

dwalton64 opened this issue Jan 26, 2023 · 2 comments

Comments

@dwalton64
Copy link
Contributor

We would like to know if charge in the capacitor is treated as a 0 or a 1 for a particular memory cell.

Can we can information about which ways the bits flip (to 0 or to 1) when an attack flips a bit?

Can we turn off refresh, let the capacitors drain, perhaps for hours, and read memory to see what value is read from drained memory cells?

@yoongu
Copy link

yoongu commented Jan 26, 2023

Just to elaborate Drew's request, true/anti cells are those that map the charged/depleted state to the logical value of '1', respectively.

I find it convenient to think of it as a bitmask that gets XOR'd with the data before it gets written in. Such orientation (or polarity) of cells is important for rowhammer because of two reasons: (i) rowhammer-induced bitflips are biased toward one direction over the other, (ii) the likelihood of a particular cell flipping is heavily influenced by the charge stored in nearby cells in the same (victim) row as well as that stored in the cells in the neighboring (aggressor) row.

One of the easiest ways to reverse-engineer the polarity is to stop refreshing for a long period of time, and then reading the data back. The rationale is that the cells would have bled out most of their charge by then, so that the true cells would be read as '0', whereas the anti cells would be read as '1'. According to this presentation (slide 54), it takes dozens of minutes to do so. But even then, not all cells would reach their quiescent state -- so you might have to be clever about how you recognize and declare "zones" of true vs anti cells. This might very well be moot if all cells in the chip turn out to be either true or anti -- which I've seen before.

https://www.nipslab.org/wp-content/uploads/2019/09/NiPS_2019_cWeis.pdf

@tmichalak
Copy link
Member

Let me divide your question into 2 separate points and I’ll address them 1-by-1.

First question was if we can get direction bit flips when it finally flips.
Second question was if we can disable a refresher for hours and let a device drain.
Using both options you would like to observe which cells are normal polarity and which ones are reversed.

Answering your first question, I believe we only need to change parts of software to detect a bitflip direction and to pinpoint exact bit position in the memory module (column, row, bank).
This part of code needs to be edited to add this functionality

for i, word, expected in row_errors[row]:
base_addr = min(self.addresses_per_row(row))
addr = base_addr + 4 * i
bank, _row, col = self.converter.decode_bus(addr)
if self.verbose:
print(
"Error: 0x{:08x}: 0x{:08x} (row={}, col={})".format(
addr, word, _row, col))
bitflips = self.bitflip_list(word, expected)
and function:
def bitflip_list(val, exp):
# FIXME: add docstring
expr = f'{val ^ exp:#0{len(bin(exp))}b}'
return [i for i, c in enumerate(expr[2:]) if c == '1']
Since we know what was the original memory state (we initialize the memory with known pattern) we can calculate the flip direction.

And as for the second one, we also would need to do some software changes. Right now it is possible to disable refresh. We would need to add an option to disable it and wait some time before reading out memory to get bitflips. This part of the code would need time.sleep() added

if self.no_refresh:
print('\nDisabling refresh ...')
self.wb.regs.controller_settings_refresh.write(0)
This script would also need a new param to set the time wait value.
This doesn’t seem to be really complicated to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants