comsec-group / blacksmith

Next-gen Rowhammer fuzzer that uses non-uniform, frequency-based patterns (IEEE S&P '22).
MIT License
222 stars 34 forks source link

Blacksmith on non-Coffee Lake CPUs #4

Open hariv opened 2 years ago

hariv commented 2 years ago

Did anyone try running blacksmith on CPUs other than Coffee Lake?

I was able to run it successfully on Kaby Lake, but it didn't work on Comet Lake. It errors out immediately saying it could not find conflicting address sets and asks if the number of banks has been defined correctly (which I checked is correct).

pjattke commented 2 years ago

Hi @hariv

The DRAM address functions are obtained from an i7-8700K (Coffee Lake). It is very likely that those functions are different on other CPUs. In this case, you would need to first-reverse engineer them (e.g., using DRAMA or TRRespass' DRAMA) and then update the DRAM addressing matrices in DRAMAddr.cpp.

hariv commented 2 years ago

Got it. Thank you @pjattke.

heechul commented 2 years ago

Hi @hariv

The DRAM address functions are obtained from an i7-8700K (Coffee Lake). It is very likely that those functions are different on other CPUs. In this case, you would need to first-reverse engineer them (e.g., using DRAMA or TRRespass' DRAMA) and then update the DRAM addressing matrices in DRAMAddr.cpp.

Hi. @pjattke. I've got the following TRRespass's DRAMA outcome on a skylake machine. can you explain how DRAMAddr.cpp should be modified to reflect the mapping? Thanks.


         Valid Function: 0x4080                  bits: 7 + 14
         Valid Function: 0x88000                 bits: 15 + 19
         Valid Function: 0x110000                bits: 16 + 20
         Valid Function: 0x220000                bits: 17 + 21
         Valid Function: 0x440000                bits: 18 + 22
         Valid Function: 0x4b300                 bits: 8 + 9 + 12 + 13 + 15 + 18
0x4080
0x88000
0x110000
0x220000
0x440000
0x4b300
DominikBucko commented 2 years ago

Could we get any followup on this? I used DRAMA tool as well and obtained memory functions, but don't know how to input them into the code.

pjattke commented 2 years ago

Dear @heechul and @DominikBucko,

I'm sorry for the late reply but I didn't have time to work on that yet. I'll soon (in the next days) provide you with a script that generates the addressing matrices that you can input into Blacksmith.

Thanks for your patience and understanding!

pjattke commented 2 years ago

Dear @heechul and @DominikBucko,

Finally, I managed to find some time to update our DRAM addressing matrices script. Sorry for the delay.

You can find the script mat-gen.py in this gist. You can find a # TODO note showing the section that you need to edit. It should be enough if you fill out dram_fns and row_fn based on the information from DRAMA.

Regards, Patrick

heechul commented 2 years ago

Hi @pjattke

Thanks a lot for sharing the script. I have a question.

If I'm not mistaken, the output of the script seems a bit different from the default configuration in the blacksmith repository when dram_fns and row_fn in the script was configured to match with the known functions in the repository (i.e., dram_fns = [0x2040, 0x24000, 0x48000, 0x90000], row_fn = 0x3ffe0000). For example, in the aforementioned single_rank configuration, DRAM_MTX[4] - DRAM_MTX[10] are shifted right by 1 bit in the generated matrix compared to the matrix in the code repository. Can you clarify on this?

Thanks

Heechul.

pjattke commented 2 years ago

Hi @heechul

To summarize what my colleague told me, who has implemented this part of Blacksmith:

It shouldn't matter all that much because changing one bit changes also the other one if you want to stay in the same bank, so it's either/or. If we assume we have the row/col bit overlapping with a bank function (multiple XORed bits), then having that row bit on the higher bit or the lower bit shouldn't matter since you can't change one without changing the other.

This is because the bank/rank functions on our CPU (i7-8700K) consist each of two bits that are combined by XOR. So if you change any of them, you will end up in a different bank.

However, coming back to your question: I cannot tell why the output is different (shifted by one bit). My colleague told me that he will look into this more once he finds time. Meanwhile, you can just try to use the output generated by mat-gen.py and report back if that worked for you.

In any way, I will try to replace this DRAM addressing part in the next couple of weeks by something that makes it easier to work with as I recognize that the current solution is cumbersome.

heechul commented 2 years ago

Hi @pjattke

Thanks for following this up.

Thanks

pjattke commented 2 years ago

Dear @heechul,

Thanks for your update.

Regards, Patrick

heechul commented 2 years ago

Hi @pjattke

Thanks for confirming the annotation. I can report that we got bitflips with the mat-gen.py generated matrices. Thanks for the pointers regarding Skylake mapping functions.

Happy new year! Heechul

JKRde commented 2 years ago

Hi Patrik,

for an i3-8350k system I have created a log with DRAMA, see attachment. Unfortunately I don't know how to get the values for dram_fns and row-fn out of this information. Could you explain how to determine these?

drama_output.log

pjattke commented 2 years ago

Hi @JKRde, Could you meanwhile figure it out or do you need help? Basically, you need to take the bits DRAMA found to be part of the masks, then create its hexadecimal representation, and then use the mat-gen.py script to translate the masks into the DRAM addressing matrices used by Blacksmith.

JKRde commented 2 years ago

Hi Patrik,

Unfortunately I have not yet managed to determine the dram_fns & row_fn values with the TRRespass' DRAMA tools. Maybe you could give me a step by step guide for dummies ;-)

BR Jens

TheSilentDawn commented 1 year ago

Hi @pjattke , I have run the drama from Trrespass repo and get the result of DRAM mapping function info as below.

~~~~~~~~~~ Found Functions ~~~~~~~~~~
     Valid Function: 0x8000          bits: 15 
     Valid Function: 0x10000         bits: 16 
     Valid Function: 0x20080         bits: 7 + 17 
     Valid Function: 0x1000040       bits: 6 + 24 
     Valid Function: 0x2200000       bits: 21 + 25 
     Valid Function: 0x4400000       bits: 22 + 26 
     Valid Function: 0x8800000       bits: 23 + 27 
     Valid Function: 0x145140        bits: 6 + 8 + 12 + 14 + 18 + 20 
0x8000
0x10000
0x20080
0x1000040
0x2200000
0x4400000
0x8800000
0x145140
~~~~~~~~~~ Looking for row bits ~~~~~~~~~~
[LOG] - Set #0
[LOG] - 184716da80 - 18824693eb  Time: 273 <== GOTCHA
[LOG] - 184716da80 - 18553ecda1  Time: 270 <== GOTCHA
[LOG] - 184716da80 - 18160cf469  Time: 270 <== GOTCHA
[LOG] - 184716da80 - 189352a594  Time: 267 <== GOTCHA
[LOG] - 184716da80 - 180714b92f  Time: 264 <== GOTCHA
[LOG] - Set #1
[LOG] - 1833714c40 - 18541b138a  Time: 273 <== GOTCHA
[LOG] - 1833714c40 - 1899d90349  Time: 276 <== GOTCHA
[LOG] - 1833714c40 - 18373f65f1  Time: 279 <== GOTCHA
[LOG] - 1833714c40 - 1808cd7a0f  Time: 279 <== GOTCHA
[LOG] - 1833714c40 - 1822712c20  Time: 279 <== GOTCHA
[LOG] - Row mask: 0xffff800000       bits: 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 
0xffff800000

Continuously, I parse them into the script mat-gen.py as below.

num_channels = 4
num_dimms = 16
num_ranks = 2
num_banks = 16

dram_fns = [0x8000, 0x10000, 0x20080, 0x1000040, 0x2200000, 0x4400000, 0x8800000, 0x145140]
row_fn = 0xffff800000
col_fn = 8192 - 1

However, the script mat-gen.py will throw the error because https://gist.github.com/pjattke/b56baff62be77f16ad8d33376789be67#file-mat-gen-py-L56 requires a 30x30 square which is not satisfied by my drama result and parsed info in mat-gen.py. I'm confused with that is 30x30 enforced? Obviously, my daram result is not.

pjattke commented 1 year ago

Hi @TheSilentDawn. Thanks for your interest in Blacksmith. Could you please provide us with some more information:

  1. Which CPU are these functions from?
  2. Do you really have a system equipped with 4 x 16 = 64 dual-rank DIMMs? The timing-based DRAMA cannot figure out the DIMM/channel functions.

The 30x30 constraint comes from the fact that we are using a superpage, and thus cannot control any bits higher than bit 30. It needs to be a square matrix and invertible (i.e., have full rank) such that we can compute the -to- translation matrix using linear algebra.

Best Patrick

TheSilentDawn commented 1 year ago

Hi @pjattke , Thanks for your prompt reply.

  1. I'm using Intel Xeon E5-2690 v3.
  2. Yes, the server is equipped with 64 dual-rank DIMMs. However, to simplify the process, I have unplugged them and only one DRAM is left whose information is below.
    num_channels = 1
    num_dimms = 1
    num_ranks = 2
    num_banks = 16

I rerun drama from trrespass. The result is below.

root@ubuntu: ~/trrespass-master/drama/obj#./tester -s 16 -t 460 -o access.csv -v
...
~~~~~~~~~~ Found Functions ~~~~~~~~~~
     Valid Function: 0x2000          bits: 13 
     Valid Function: 0x200040        bits: 6 + 21 
     Valid Function: 0x440000        bits: 18 + 22 
     Valid Function: 0x880000        bits: 19 + 23 
     Valid Function: 0x1100000       bits: 20 + 24 
0x2000
0x200040
0x440000
0x880000
0x1100000
~~~~~~~~~~ Looking for row bits ~~~~~~~~~~
[LOG] - Set #0
[LOG] - 3d6b5b940 - 3bb6a30f0    Time: 413 <== GOTCHA
[LOG] - 3d6b5b940 - 39cb725cd    Time: 407 <== GOTCHA
[LOG] - 3d6b5b940 - 3aa59e8af    Time: 458 <== GOTCHA
[LOG] - 3d6b5b940 - 3e097750e    Time: 458 <== GOTCHA
[LOG] - 3d6b5b940 - 3961e2b9a    Time: 458 <== GOTCHA
[LOG] - Set #1
[LOG] - 3c86ac200 - 3e0485651    Time: 458 <== GOTCHA
[LOG] - 3c86ac200 - 3e8c106cb    Time: 458 <== GOTCHA
[LOG] - 3c86ac200 - 3b1f18208    Time: 458 <== GOTCHA
[LOG] - 3c86ac200 - 3f53f1a9f    Time: 458 <== GOTCHA
[LOG] - 3c86ac200 - 3ddf18e91    Time: 458 <== GOTCHA
[LOG] - Row mask: 0xffff000000       bits: 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 
0xffff000000

Based on my understanding the variable dram_fns in mat-gen.py should be configurated as [0x2000, 0x200040, 0x440000, 0x880000, 0x1100000] and the variable row_fn should be configurated as 0xffff000000 following the result from trrespass drama. However, I'm confused with the variable col_fn, which value should it be? If I try to create a 30x30 matrix, it should be 524288 - 1. But the script mat-gen.py will throw an error meaning not invertible.

TheSilentDawn commented 1 year ago

Hi @pjattke , I also got another result running on Intel(R) Xeon(R) CPU E5-2690 and 1x16G DRAM which Part Number is HMT42GR7BFR4A-PB. The drama output is below.

xxx:~/trrespass-master/drama # ./obj/tester -s 8 -o ddr3.csv -v
~~~~~~~~~~ Found Functions ~~~~~~~~~~
         Valid Function: 0x4000                  bits: 14
         Valid Function: 0x80000                 bits: 19
         Valid Function: 0x42000                 bits: 13 + 18
0x4000
0x80000
0x42000
~~~~~~~~~~ Looking for row bits ~~~~~~~~~~
[LOG] - Set #0
[LOG] - 2d9cde780 - 2fe09de11    Time: 288 <== GOTCHA
[LOG] - 2d9cde780 - 2de7842b5    Time: 280 <== GOTCHA
[LOG] - 2d9cde780 - 2a4b8df0f    Time: 272 <== GOTCHA
[LOG] - 2d9cde780 - 2e74ac4b4    Time: 280 <== GOTCHA
[LOG] - 2d9cde780 - 2b10de59e    Time: 304 <== GOTCHA
[LOG] - Set #1
[LOG] - 2f0f163c0 - 2b636d892    Time: 280 <== GOTCHA
[LOG] - 2f0f163c0 - 2af73e536    Time: 304 <== GOTCHA
[LOG] - 2f0f163c0 - 29eb7593b    Time: 284 <== GOTCHA
[LOG] - 2f0f163c0 - 2d2d4c2c3    Time: 284 <== GOTCHA
[LOG] - 2f0f163c0 - 2f3074bc3    Time: 276 <== GOTCHA
[LOG] - Row mask: 0xffff000000           bits: 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39
0xffff000000

Could you please help to explain what configuration should be in mat-gen.py?

pjattke commented 1 year ago

Hi @TheSilentDawn. I'm sorry, but I do not have the resources anytime in near future to help with this further. There is a little chance that one of my students will have the time to make mat-gen.py nice over the next weeks, but I cannot promise.

You will need to study the mat-gen.py carefully. It's basically just a translation matrix that it computes, so you need to have a square matrix (e.g., 30x30) with full rank (i.e., linearly independent rows). If this is not given, you either have the wrong functions (or row/column masks), or you need to augment it with "dummy" matrix rows (this would correspond to bits not involved in DRAM addressing).

I'm sorry that I cannot give you a more positive reply. I hope you understand. Good luck!

its-luca commented 1 year ago

@pjattke We have a student who is using blacksmith in a project. As part of the project he did some polishing on the address function import part of blacksmith and will post a PR soon.

missyoufenglan87 commented 1 month ago

Has anyone successfully caused bitflips on DRAMs produced by Blacksmith between 2023-2024 ? I ran the project without any error message, but I didn't flip any bits on any DRAMs.Has this method now become impossible to bypass the existing TRR mechanism?

pjattke commented 1 month ago

Hi @missyoufenglan87, we have also found more recent DIMMs where we could not trigger bit flips with Blacksmith anymore. We have not investigated this further on a larger scale though. It is likely that the DRAM vendors meanwhile have improved their mitigations.

Chapoly1305 commented 3 weeks ago

Great work and this repo is the best and the only we can Confirmed Reproduce.

Memory Module: HMA81GU6JJR8N-VK This is a Rank 1 Bank 8 module. PC Model: OptiPlex-7060 Detailed Computer Spec: dmidecode.txt OS: Ubuntu 22.04

Steps:

  1. Get a copy of TRespass
  2. Using sudo, run TRespass/drama/hugepage.sh. Run again if computer rebooted, you can ignore the error saying directory existed.
  3. Compile TRespass/drama.
  4. Using sudo, run TRespass/drama/obj/tester -s 16 --mem 1024000. This step shall generate result fairly quick. We expect the whole process done in 30 seconds. If not, kill it and try again. We sometime observe the result is offset to most of the results, we don't know why. Our results are 0x2040,0x24000,0x48000,0x90000 (use for dram_fns) and 0x3ffe0000 (use for row_fn).
  5. Get mat-gen.py. Run the with updated dram_fns and row_fn.
  6. Update blacksmith/src/Memory/DRAMAddr.cpp with generated content. We have also updated blacksmith/include/GlobalDefines.hpp to match our module. updated_files.zip
  7. Ensure you have enabled hugepage, if not, repeat step 2.
  8. Compile and run blacksmith. sudo blacksmith/build/blacksmith --dimm-id 1 --ranks 1 -t 2160000 Logs: stdout.zip