sandsifter
sandsifter copied to clipboard
Injector crashes in certain instruction range on Zen 2
I'm sifting my Ryzen 5 3600 on Arch Linux and am having trouble running a full scan.
The processor will fall into a hole with instructions looking like this:
0f0104060f0104060f0104060f...
and after a while of executing instructions in that range, the injector will crash.
If running with the --save
flag, and resuming with the --resume
flag, it will resume after the instruction that crashed it and will go until it crashes again in that range.
The first instruction that crashes it is:
0f0104060f0104060f0104060fa9
Okay, so after looking further at it, this seems to be a hardware problem.
0fa9
does not crash the process.
260fa9
does not crash the process.
0f0104060fa9
crashes the process.
0f010f06260fa9
crashes the process.
0f01
followed by 04, 06, 07, 08, 0f, and probably more, will all fall back down into that instruction hole. I have to run the injector with -X 0f01
.
Please send me the output dump of that run if you can?
As in, the log that it outputs before it crashes?
Yeah, just want to validate that the prior ones are actually also executing as expected. Because truth be told on sandsifter I've never actually seen a processor execute into that path. fwiw 0f01 is a fun 386 remapped instruction space. But the decode for it isn't exactly sensible for 0f0104060f0104060f0104060fa9
It's supposedly 3 SGDT operations followed by a POPQ GS.
EDIT: Also please explain what the actual crash is that you are getting, what do you see printed to dmesg.
GitHub won't let me attach the file here, so I put it on my mega.nz account. https://mega.nz/file/M0snVa4R#1vT1HdBM6M95q_g8scHKqcA32L35eBQ16bYnoLoK5Mo Careful, as loading this log into the dissector may use over 20GiB of memory at times.
The crash is *** stack smashing detected ***: terminated
dmesg output:
[29028.113384] umip_printk: 94446077 callbacks suppressed
[29028.113386] umip: sifter-injector[20126] ip:f2bff1 sp:974800: SGDT instruction cannot be used by applications.
[29028.113387] umip: sifter-injector[20126] ip:f2bff1 sp:974800: For now, expensive software emulation returns the result.
[29028.113388] umip: sifter-injector[20126] ip:f2bff5 sp:974800: SGDT instruction cannot be used by applications.
[29028.113389] umip: sifter-injector[20126] ip:f2bff5 sp:974800: For now, expensive software emulation returns the result.
[29028.113398] umip: sifter-injector[20126] ip:f2bffc sp:974800: SGDT instruction cannot be used by applications.
[29148.115770] umip_printk: 156624411 callbacks suppressed
[29148.115772] umip: sifter-injector[20126] ip:f2bff2 sp:974800: SGDT instruction cannot be used by applications.
[29148.115774] umip: sifter-injector[20126] ip:f2bff2 sp:974800: For now, expensive software emulation returns the result.
[29148.115775] umip: sifter-injector[20126] ip:f2bff6 sp:974800: SGDT instruction cannot be used by applications.
[29148.115776] umip: sifter-injector[20126] ip:f2bff6 sp:974800: For now, expensive software emulation returns the result.
[29148.115777] umip: sifter-injector[20126] ip:f2bffa sp:974800: SGDT instruction cannot be used by applications.
I figured it out.
Running SGDT will run it and the following instruction without passing control back to the debugger until the following instruction completes.
Stepping forward once results in:
So by chaining a bunch of these instructions after each other, we end up making a slide of sorts that doesn't pass control back to the injector until it all finishes.
Now that we know this, think about what the command that crashes it does.
SGDT
SGDT
SGDT
POPQ
That POPQ will execute no matter what, and is probably messing up the stack.
Looking further, it looks as if all there are a lot more instructions that do this.
smsw
sidt
str
sldt
sgdt
Perhaps blacklisting instructions we find will let us exhaustively find them? Although that sounds like a lot of waiting around...
Yes this is what I will have to do. We can simply extend the BLACKLIST array in injector.c Most of these instructions should only ever be called by the operating system and not user applications.
I'm just wondering what about your system or processors is so different that causes it to run and crash in the 0f01 instruction sequences. I've not had any other system actually execute into that range before. It's likely we'll need some more data from other Zen 2 users to confirm this.
Are you using any special kernel build?
For now we'll have to go with -X 0f01
And then likely add CPUID specific blacklisting of instructions.
The full blacklist I needed to use was:
0f0104 0f0106 0f0107 0f0108 0f0109 0f010a 0f010b 0f010c 0f010e 0f010f
0f0120 0f0121 0f0122 0f0123 0f0124 0f0126 0f0127 0f01e0 0f01e1 0f01e2
0f01e3 0f01e4 0f01e5 0f01e6 0f01e7
I'm using the normal linux kernel.