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

Injector crashes in certain instruction range on Zen 2 #14

Open
Prism019 opened this issue Apr 7, 2020 · 9 comments
Open

Injector crashes in certain instruction range on Zen 2 #14

Prism019 opened this issue Apr 7, 2020 · 9 comments

Comments

@Prism019
Copy link

Prism019 commented Apr 7, 2020

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
Copy link
Author

Prism019 commented Apr 7, 2020

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.

@rigred
Copy link
Owner

rigred commented Apr 7, 2020

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

@Prism019
Copy link
Author

Prism019 commented Apr 7, 2020

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

@rigred
Copy link
Owner

rigred commented Apr 7, 2020

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.

@Prism019
Copy link
Author

Prism019 commented Apr 8, 2020

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
Copy link
Author

Prism019 commented Apr 8, 2020

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
Copy link
Author

Prism019 commented Apr 8, 2020

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

@rigred
Copy link
Owner

rigred commented Apr 8, 2020

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.

@Prism019
Copy link
Author

Prism019 commented Apr 8, 2020

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.

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

2 participants