Skip to content

Attack not working without printf #35

@felix-gohla

Description

@felix-gohla

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 are

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

I would be glad if someone had an idea why this happens. 😊 Actually I am not sure what internal state this printf changes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions