-
Notifications
You must be signed in to change notification settings - Fork 88
Description
Hi all,
when researching the attack, I found a strange thing.
Not sure whether this is the best place for discussion but it seems this is the most recent PoC repository I could find on gh.
What does not work
What I found was that the attack will not work quite right without the initial printfs before leaking bytes.
Hardware
I tested this on:
- AMD Ryzen 7 3700X (Linux 6.1.0-12-amd64, debian 12)
- Intel Xeon Skylake, IBRS (Linux 6.1.0-12-amd64, debian 12) - at least that is what my cloud provider says ^^
The patch to reconstruct the issue
See the following diff I applied to the original source. I am basically removing all printfs before finding the first secret byte.
diff --git a/spectre.c b/spectre.c
index 864d12d..2b4bb64 100644
--- a/spectre.c
+++ b/spectre.c
@@ -324,49 +324,8 @@ int main(int argc,
sscanf(argv[3], "%d", &len);
}
- /* Print git commit hash */
- #ifdef GIT_COMMIT_HASH
- printf("Version: commit " GIT_COMMIT_HASH "\n");
- #endif
-
- /* Print cache hit threshold */
- printf("Using a cache hit threshold of %d.\n", cache_hit_threshold);
-
- /* Print build configuration */
- printf("Build: ");
- #ifndef NORDTSCP
- printf("RDTSCP_SUPPORTED ");
- #else
- printf("RDTSCP_NOT_SUPPORTED ");
- #endif
- #ifndef NOMFENCE
- printf("MFENCE_SUPPORTED ");
- #else
- printf("MFENCE_NOT_SUPPORTED ");
- #endif
- #ifndef NOCLFLUSH
- printf("CLFLUSH_SUPPORTED ");
- #else
- printf("CLFLUSH_NOT_SUPPORTED ");
- #endif
- #ifdef INTEL_MITIGATION
- printf("INTEL_MITIGATION_ENABLED ");
- #else
- printf("INTEL_MITIGATION_DISABLED ");
- #endif
- #ifdef LINUX_KERNEL_MITIGATION
- printf("LINUX_KERNEL_MITIGATION_ENABLED ");
- #else
- printf("LINUX_KERNEL_MITIGATION_DISABLED ");
- #endif
-
- printf("\n");
-
- printf("Reading %d bytes:\n", len);
-
/* Start the read loop to read each address */
while (--len >= 0) {
- printf("Reading at malicious_x = %p... ", (void * ) malicious_x);
/* Call readMemoryByte with the required cache hit threshold and
malicious x address. value and score are arrays that areApplying that patch, the following output is shown:
Success: 0x02=’?’ score=51 (second best: 0x01=’?’ score=23) <<-- This line changes.
Unclear: 0x68=’h’ score=992 (second best: 0x02=’?’ score=813)
Unclear: 0x65=’e’ score=999 (second best: 0x02=’?’ score=861)
Unclear: 0x20=’ ’ score=992 (second best: 0x02=’?’ score=869)
Unclear: 0x4D=’M’ score=987 (second best: 0x02=’?’ score=857)
Unclear: 0x61=’a’ score=989 (second best: 0x02=’?’ score=843)
Unclear: 0x67=’g’ score=998 (second best: 0x02=’?’ score=838)
The first byte cannot be leaked anymore. Removing all printfs leads to no byte being leaked correctly.
Why?
Currently, I am not sure why that happens. My assumption is that printf somehow changes state of some pages without which the attack does not work.
For this, I added 1 printf and stopped right before it with GDB. Using pagemap, I dumped the page table and had a look at differences before and after the printf (left side is before the printf).
One can see that amongst having a heap now, some additional libc pages are present. Calling malloc instead of printf does not work and still produces wrong bytes.
4c4
< 0x555555556000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /home/rh/spectre/cache-timing/spectre.out
---
> 0x555555556000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /home/rh/spectre/cache-timing/spectre.out
38a39,71
> 0x555555579000 : soft-dirty 1 file/shared 0 swapped 0 present 1 library [heap]
> 0x55555557a000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x55555557b000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x55555557c000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x55555557d000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x55555557e000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x55555557f000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555580000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555581000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555582000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555583000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555584000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555585000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555586000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555587000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555588000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555589000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x55555558a000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x55555558b000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x55555558c000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x55555558d000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x55555558e000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x55555558f000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555590000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555591000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555592000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555593000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555594000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555595000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555596000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555597000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555598000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
> 0x555555599000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library [heap]
101c134
< 0x7ffff7e09000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
---
> 0x7ffff7e09000 : soft-dirty 1 file/shared 0 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
156,171c189,204
< 0x7ffff7e40000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e41000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e42000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e43000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e44000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e45000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e46000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e47000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e48000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e49000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e4a000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e4b000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e4c000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e4d000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e4e000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
< 0x7ffff7e4f000 : soft-dirty 1 file/shared 0 swapped 0 present 0 library /usr/lib/x86_64-linux-gnu/libc.so.6
---
> 0x7ffff7e40000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e41000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e42000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e43000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e44000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e45000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e46000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e47000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e48000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e49000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e4a000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e4b000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e4c000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e4d000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e4e000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6
> 0x7ffff7e4f000 : soft-dirty 1 file/shared 1 swapped 0 present 1 library /usr/lib/x86_64-linux-gnu/libc.so.6I would be glad if someone had an idea why this happens. 😊 Actually I am not sure what internal state this printf changes.