sandsifter icon indicating copy to clipboard operation
sandsifter copied to clipboard

Injector crashes in certain instruction range on Zen 2

Open Prism019 opened this issue 4 years ago • 9 comments

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

Prism019 avatar Apr 07 '20 18:04 Prism019

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.

Prism019 avatar Apr 07 '20 19:04 Prism019

Please send me the output dump of that run if you can?

rigred avatar Apr 07 '20 21:04 rigred

As in, the log that it outputs before it crashes?

Prism019 avatar Apr 07 '20 22:04 Prism019

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.

rigred avatar Apr 07 '20 23:04 rigred

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.

Prism019 avatar Apr 08 '20 03:04 Prism019

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.

image Stepping forward once results in: image image

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.

Prism019 avatar Apr 08 '20 07:04 Prism019

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...

Prism019 avatar Apr 08 '20 18:04 Prism019

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.

rigred avatar Apr 08 '20 19:04 rigred

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.

Prism019 avatar Apr 08 '20 22:04 Prism019