Great explanation with specific details. I went through the 4 most popular youtube videos today to understand this vulnerability.This is hands-down the best!. Thanks!!
Really helpful explanation! Your way of explaining is really much clearer and more intuitive than many papers. I wish you could post more technical sharing on varieties of topics! Many thanks!
Your explanation was very informative and just a balance of simple and complex. I think the sound was just fine i did not hear anything wrong, keep up the good work.
Sound isn't too quiet for me. I appreciate the clear, no-fuss presentation style. A better mic may provide fewer artifacts, environment noise, etc., but this is still pleasantly listenable.
Thanks! I'm using a somewhat decent mic (well a Snowball mic). Most of the issue is being too far away from it and being in a house with a 7- and 9-year old nearby :)
You might want to consider using audio normalization, compression and limiting to get a good consistent level. There are plenty of free plugins for that kind of stuff.
Thanks. Plugins for what though? I'm on Linux and I'm using a pretty simple screen capturer - do you have recommendations for what to post-produce these with? I was hoping UA-cam would have a "fix my audio" button, but alas...
Ah no not really. I'm a Linux user too but I keep a Windows machine specially for audio/video work as AV on Linux has traditionally been a bit of a dogs dinner. Ardour and Audacity are the two big fish and they may be better now than they were last time I tried to use them (about 5 years ago). For video I used to use KDEN live which had an awesome interface but used to crash every 10 minutes. In the end I just couldn't swallow the reliability issues, plugin compatibility issues, and the Pulse vs Alsa vs Jack nightmare. I was spending more time debugging than recording/editing. As I say the situation may be better now, the newer Steinberg VST3 plugins may run in Linux. Personally I use reaper for audio and the devs claim it runs well under wine though I've never tried it. It's just audio editing but that's no biggie, I just strip the audio off with ffmpeg, process it and save it then use ffmpeg to knit it all back together again.
Today I watched a GOTO; 2014 presentation you did, and it felt like you were explaining Metldown and/or Spectre. You did not, but you were so close and explaining important things. (And I loved your 6502 work/presentation too.
David Glaude wow thanks for the lovely and kind words. Glad you enjoy this stuff, it's absolutely my passion :). Finding ways to share it with more folks is my goal
Great video, wouldn't mind more of your work presentations ending up here lol Im still on an i7 930 from around the Mesozoic era so I'm going to hold off updating in fear of the perf hit on older architectures, at least on one of my OSes
Matt: at 14:14, you have said, "in the very very common case, people will be reading within the bounds of the array which means that branch that is implicit in the if statement there is never taken" I feel I am missing something here. If the read is within the bounds, this if branch is always going to be taken, so what do I miss here?
@@MattGodbolt Now I see what you meant by "not taken" is that the if statement is useless because, in most cases, it would always be "true", so we can execute the body without executing the if condition. Now, I see the whole point of speculative execution.
I believe it is safe to assume that very few normal programs will get a performance hit if a segfault causes a considerable delay. If you know of programs that use segfaults all the time, please comment. The attack is depending on timing. As you mention the current attack is on the timing of access to the cache, but it could be timings in other things as well. So what if a segfault caused a random delay? Would that thwart the attack?
There's no segfault actually happening. The fault only happens when the faulting instruction retires. And as a speculatively executed instruction which was incorrectly predicted, it is discarded before it retires. So, no segfault actually happens.
Sorry, I should have been clearer: When a _speculative_ segfault happens, then flush all caches (to make the caching attack fail) and wait a random time (to make timing attacks fail). Do we know how often a _speculative_ segfault happens in ordinary programs? Would it be acceptable to pay a high penalty if a speculative segfault happens?
Ole Tange but that's the thing: the speculative segfault doesn't happen. Faults are processed when the instruction that caused the fault retires. And these speculative page faults don't retire as they were incorrectly speculated
@@OleTange hi. I am about a year late, but I just wanted to point out that the following code is commonly used: char *a = get_some_ptr(); if (a) { *a; // dereference a and do something with it } If in this code the branch is mispredicted, a would be a null pointer, thus a *speculative* segfault will happen.
Great presentation! Thank you very much! First time I’m learning something about security vulnerabilities. Trying to understand how exactly these attacks work for a while now. I’m not quite sure I understand the Spectre v1 part. Does the read() function operate on the detectArray or does the value that was speculatively achieved by the read function crosses the function boundary, gets returned and is consequently used by the calling code before it is discarded? Or it is assumed that it will be inlined by the compiler? Thanks again!
Hi! Thanks for your comment. The read() function does not operate on the detectArray, it's a regular function call (inline or non-inline, it doesn't matter) to the read() function outlined earlier. The result of the call to read() is then used on the detectArray. The CPU doesn't distinguish between "function calls" or "inlining" -- it's just a stream of instructions to run as far as the Out-of-Order core is concerned. The fact that "read()" is speculated while the fault on "array size" is loaded from cache, but the results return to the caller and can be used (at least speculatively), is all that matters. Whether read() is CALLed or inlined doesn't matter. I hope that helps! If you have any more questions feel free to ask here or over email or twitter :)
I don't understand how speculative execution runs regardless of values it depends on being cached or not... for instance in your presented code at 32:20 𝚒𝚗𝚝 𝚛𝚎𝚊𝚍 (𝚒𝚗𝚝 𝚒𝚗𝚍𝚎𝚡) { 𝚒𝚗𝚝 𝚛𝚎𝚜𝚞𝚕𝚝 = -𝟷; 𝚒𝚏 (𝚒𝚗𝚍𝚎𝚡 < 𝚊𝚛𝚛𝚊𝚢𝚂𝚒𝚣𝚎) 𝚛𝚎𝚜𝚞𝚕𝚝 = 𝚊𝚛𝚛𝚊𝚢[𝚒𝚗𝚍𝚎𝚡]; 𝚛𝚎𝚝𝚞𝚛𝚗 𝚛𝚎𝚜𝚞𝚕𝚝; } I don't understand how we guarantee that 𝚊𝚛𝚛𝚊𝚢𝚂𝚒𝚣𝚎 gets flushed but the 𝚒𝚗𝚍𝚎𝚡 is used in speculative execution... Wouldn't 𝚒𝚗𝚍𝚎𝚡 also be flushed and therefore speculative execution would have to be halted, as 𝚒𝚗𝚍𝚎𝚡 also needs to be accessed from memory now? I don't suppose we can flush 𝚊𝚛𝚛𝚊𝚢𝚂𝚒𝚣𝚎 only and have to flush the whole cache!
@@MattGodbolt Hah because index is passed directly as an argument is it? So it gets stored directly in CPU registers that are predetermined for that purpose rather than memory (cache or otherwise)? Sorry, my knowledge in these issues is not the best, but I'm really interested in them!
How does the attacker know what the data in the secret bytes is? From what I understand, they only have the address of a privileged address (which they can't access).
The data is used to affect the cache. Then, afterwards, although the instructions that used the privileged data never complete... The attacker probes the cache and can use the influence the earlier (privileged) data had on it to infer the value
It seems to me that neither exploit has anything to do with caching, out-of-order execution, branch prediction, or speculative execution. Rather, it has to do with the CPU violating memory's read protection bits - it should not be reading a location in memory which the current process has no permission to read, regardless of whether that's within the context of branch prediction, speculative execution or otherwise. Simply fix the CPU so it never actually accesses a memory location which is read/write/execute (as appropriate) protected. Memory fetches from inaccessible (due to permissions) memory locations should simply not happen, any instructions which depend on them should stall, and once it is clear that an instruction which is causing a memory access violation will be executed, the memory access violation exception should be raised.
Is it possible to save the result/state of a mispredicted branch in your own code? Kind of like having an implicit thread that you cannot control the parameters of and it can only execute some # of instructions before it gives up. Imagine some algorithm that relied on the misprediction of a branch for perf gains.
Not as far as I understand it, no. The nearest thing one has is transactional memory, but that's more like an undo/redo buffer (like a mispredicted branch), and for competing memory accesses.
its very suspect that AMD CPU'S get a threat from the SPECTRE V2 and AMD'S fix will reduce performance on all CPU'S right before new launch of next gen. CPU'S this fall . betting it wont effect those .
Great explanation with specific details. I went through the 4 most popular youtube videos today to understand this vulnerability.This is hands-down the best!. Thanks!!
So much better than other explanations. Includes enough CODE to actually see the issues.
Thank you so much!
Really helpful explanation! Your way of explaining is really much clearer and more intuitive than many papers. I wish you could post more technical sharing on varieties of topics! Many thanks!
thank you. i have been struggling to understand these exploits, without success, until your excellent explanation.
Your explanation was very informative and just a balance of simple and complex. I think the sound was just fine i did not hear anything wrong, keep up the good work.
This explanation is amazing Matt!
Apologies for the quiet sound. I'm new to this and I'm working on the best way to record these.
Sound isn't too quiet for me. I appreciate the clear, no-fuss presentation style. A better mic may provide fewer artifacts, environment noise, etc., but this is still pleasantly listenable.
Thanks! I'm using a somewhat decent mic (well a Snowball mic). Most of the issue is being too far away from it and being in a house with a 7- and 9-year old nearby :)
You might want to consider using audio normalization, compression and limiting to get a good consistent level. There are plenty of free plugins for that kind of stuff.
Thanks. Plugins for what though? I'm on Linux and I'm using a pretty simple screen capturer - do you have recommendations for what to post-produce these with? I was hoping UA-cam would have a "fix my audio" button, but alas...
Ah no not really. I'm a Linux user too but I keep a Windows machine specially for audio/video work as AV on Linux has traditionally been a bit of a dogs dinner. Ardour and Audacity are the two big fish and they may be better now than they were last time I tried to use them (about 5 years ago). For video I used to use KDEN live which had an awesome interface but used to crash every 10 minutes. In the end I just couldn't swallow the reliability issues, plugin compatibility issues, and the Pulse vs Alsa vs Jack nightmare. I was spending more time debugging than recording/editing. As I say the situation may be better now, the newer Steinberg VST3 plugins may run in Linux. Personally I use reaper for audio and the devs claim it runs well under wine though I've never tried it. It's just audio editing but that's no biggie, I just strip the audio off with ffmpeg, process it and save it then use ffmpeg to knit it all back together again.
Today I watched a GOTO; 2014 presentation you did, and it felt like you were explaining Metldown and/or Spectre. You did not, but you were so close and explaining important things. (And I loved your 6502 work/presentation too.
David Glaude wow thanks for the lovely and kind words. Glad you enjoy this stuff, it's absolutely my passion :). Finding ways to share it with more folks is my goal
One of the best explanations on this topic! Great work!
Great video, wouldn't mind more of your work presentations ending up here lol
Im still on an i7 930 from around the Mesozoic era so I'm going to hold off updating in fear of the perf hit on older architectures, at least on one of my OSes
+disco__ thanks! Will look to putting more of my presentations online over the next few months
This was a very clear explanation of how Meltdown en Spectre work. It complements your explanation on CppCast Episode 132 nicely!
Thanks for the feedback!
Thanks Matt
I love the way you explain things! Keep up with the great talks, watched you on cppcon aswell :-)
Thank you very much!
Best explanation on UA-cam thanks a lot I now understand this properly.
Thank you very much! This is the best explanation that I've encountered!
This is a good explanation with good examples.
Great explanation!
Thank you!
Matt: at 14:14, you have said, "in the very very common case, people will be reading within the bounds of the array which means that branch that is implicit in the if statement there is never taken" I feel I am missing something here. If the read is within the bounds, this if branch is always going to be taken, so what do I miss here?
Right that's my point: it's so common as to be inevitable unless someone tries to access out of bounds (usually a bug).
@@MattGodbolt Now I see what you meant by "not taken" is that the if statement is useless because, in most cases, it would always be "true", so we can execute the body without executing the if condition. Now, I see the whole point of speculative execution.
Loved this! Very detailed explanation! Thank you!
I believe it is safe to assume that very few normal programs will get a performance hit if a segfault causes a considerable delay. If you know of programs that use segfaults all the time, please comment.
The attack is depending on timing. As you mention the current attack is on the timing of access to the cache, but it could be timings in other things as well.
So what if a segfault caused a random delay? Would that thwart the attack?
There's no segfault actually happening. The fault only happens when the faulting instruction retires. And as a speculatively executed instruction which was incorrectly predicted, it is discarded before it retires. So, no segfault actually happens.
Sorry, I should have been clearer: When a _speculative_ segfault happens, then flush all caches (to make the caching attack fail) and wait a random time (to make timing attacks fail). Do we know how often a _speculative_ segfault happens in ordinary programs? Would it be acceptable to pay a high penalty if a speculative segfault happens?
Ole Tange but that's the thing: the speculative segfault doesn't happen. Faults are processed when the instruction that caused the fault retires. And these speculative page faults don't retire as they were incorrectly speculated
@@OleTange hi. I am about a year late, but I just wanted to point out that the following code is commonly used:
char *a = get_some_ptr();
if (a) {
*a; // dereference a and do something with it
}
If in this code the branch is mispredicted, a would be a null pointer, thus a *speculative* segfault will happen.
Great presentation! Thank you very much!
First time I’m learning something about security vulnerabilities. Trying to understand how exactly these attacks work for a while now.
I’m not quite sure I understand the Spectre v1 part. Does the read() function operate on the detectArray or does the value that was speculatively achieved by the read function crosses the function boundary, gets returned and is consequently used by the calling code before it is discarded? Or it is assumed that it will be inlined by the compiler?
Thanks again!
Hi! Thanks for your comment. The read() function does not operate on the detectArray, it's a regular function call (inline or non-inline, it doesn't matter) to the read() function outlined earlier. The result of the call to read() is then used on the detectArray. The CPU doesn't distinguish between "function calls" or "inlining" -- it's just a stream of instructions to run as far as the Out-of-Order core is concerned. The fact that "read()" is speculated while the fault on "array size" is loaded from cache, but the results return to the caller and can be used (at least speculatively), is all that matters. Whether read() is CALLed or inlined doesn't matter.
I hope that helps! If you have any more questions feel free to ask here or over email or twitter :)
+Matt Godbolt thank you for the quick answer. I think, I'll send further questions to email.
Very nice presentation! Learned a lot :)
I don't understand how speculative execution runs regardless of values it depends on being cached or not...
for instance in your presented code at 32:20
𝚒𝚗𝚝 𝚛𝚎𝚊𝚍 (𝚒𝚗𝚝 𝚒𝚗𝚍𝚎𝚡) {
𝚒𝚗𝚝 𝚛𝚎𝚜𝚞𝚕𝚝 = -𝟷;
𝚒𝚏 (𝚒𝚗𝚍𝚎𝚡 < 𝚊𝚛𝚛𝚊𝚢𝚂𝚒𝚣𝚎)
𝚛𝚎𝚜𝚞𝚕𝚝 = 𝚊𝚛𝚛𝚊𝚢[𝚒𝚗𝚍𝚎𝚡];
𝚛𝚎𝚝𝚞𝚛𝚗 𝚛𝚎𝚜𝚞𝚕𝚝;
}
I don't understand how we guarantee that 𝚊𝚛𝚛𝚊𝚢𝚂𝚒𝚣𝚎 gets flushed but the 𝚒𝚗𝚍𝚎𝚡 is used in speculative execution... Wouldn't 𝚒𝚗𝚍𝚎𝚡 also be flushed and therefore speculative execution would have to be halted, as 𝚒𝚗𝚍𝚎𝚡 also needs to be accessed from memory now? I don't suppose we can flush 𝚊𝚛𝚛𝚊𝚢𝚂𝚒𝚣𝚎 only and have to flush the whole cache!
In this instance arraySize is stored in ram and can be cached (or otherwise). Index is a variable passed in a register and so its always available.
@@MattGodbolt Hah because index is passed directly as an argument is it? So it gets stored directly in CPU registers that are predetermined for that purpose rather than memory (cache or otherwise)? Sorry, my knowledge in these issues is not the best, but I'm really interested in them!
Very nice presentation. What did you use to create the slides if I may ask? Look amazing.
D0senpf4nd I use reveal.js here
Thanks for the reply!
How does the attacker know what the data in the secret bytes is? From what I understand, they only have the address of a privileged address (which they can't access).
The data is used to affect the cache. Then, afterwards, although the instructions that used the privileged data never complete... The attacker probes the cache and can use the influence the earlier (privileged) data had on it to infer the value
It seems to me that neither exploit has anything to do with caching, out-of-order execution, branch prediction, or speculative execution. Rather, it has to do with the CPU violating memory's read protection bits - it should not be reading a location in memory which the current process has no permission to read, regardless of whether that's within the context of branch prediction, speculative execution or otherwise. Simply fix the CPU so it never actually accesses a memory location which is read/write/execute (as appropriate) protected. Memory fetches from inaccessible (due to permissions) memory locations should simply not happen, any instructions which depend on them should stall, and once it is clear that an instruction which is causing a memory access violation will be executed, the memory access violation exception should be raised.
What if time-measuring-functions are randomized a little bit to make it hard to measure caching.
Is it possible to save the result/state of a mispredicted branch in your own code? Kind of like having an implicit thread that you cannot control the parameters of and it can only execute some # of instructions before it gives up. Imagine some algorithm that relied on the misprediction of a branch for perf gains.
Not as far as I understand it, no. The nearest thing one has is transactional memory, but that's more like an undo/redo buffer (like a mispredicted branch), and for competing memory accesses.
is there proof of concept code for spectre variant 4 , variant 2?
AMD is now known to have spectre vulnerabilities of its own, now, right?
I think your audience expects you to do an update on Spectre-NG ASAP. I know I do :)
its very suspect that AMD CPU'S get a threat from the SPECTRE V2 and AMD'S fix will reduce performance on all CPU'S right before new launch of next gen. CPU'S this fall . betting it wont effect those .
Given how bad these CPU speculations are, how is the CPU ever meant to be performant, no hyper threating, no cache.