From 1cc4b9a458c9f8e52d4380761d1e806484272df5 Mon Sep 17 00:00:00 2001 From: eduardo Date: Sun, 10 Dec 2023 09:13:22 -0300 Subject: [PATCH] make vdso poc easier to read --- pocs/cpus/reptar/minimized/README.md | 2 +- pocs/cpus/reptar/minimized/reptar.vdso.elf.bin.asm | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pocs/cpus/reptar/minimized/README.md b/pocs/cpus/reptar/minimized/README.md index edf06de7..86a468f9 100644 --- a/pocs/cpus/reptar/minimized/README.md +++ b/pocs/cpus/reptar/minimized/README.md @@ -12,7 +12,7 @@ You can build them all simply by running `make`. Building the code requires `nas - **reptar.spec.elf.asm**: This is a test used to check if the bug works under speculation. Its setup similar to `reptar.align.elf.asm` but only runs a few iterations and prints the speed at which its able to access memory. During the "loop" generated by the bug, we access specific parts of memory which would also happen if the bug executed speculatively. Run the code as `./reptar.spec.elf | od -i`. If speculation worked, you would see multiple "short" (<150 cycles) accesses and if it didn't work, you will only see one. - **reptar.loopless.elf.asm**: This is an easier to modify reproducer that will also trigger the bug somewhat reliably but also allows to modify the instructions executed before and after. Note the registers that the program uses at the top. - **reptar.loop.elf.asm**: This is a more documented reproducer that explains what happens when the bug triggers and which instructions execute and which don't. Running the program on GDB should allow for quick debugging. -- **reptar.vdso.elf.bin.asm**: This is an experiment where we map ourselves just before the VDSO (you must disable ASLR first and adjust the addresses) and then make the "wrong RIP" point to the VDSO address of the time() function. As a result, the current time is stored in the address pointed to by RAX, which is then clflushed so it triggers a segfault to the current time. If we had corrupted the uop$ then we would instead expect a crash, so it appears that a long jump to the VDSO doesn't corrupt the uop$. To test try: `taskset -c 7 gdb ./reptar.vdso.elf.bin -ex r -ex 'python import datetime;print(datetime.datetime.utcfromtimestamp(gdb.parse_and_eval("*$rdi")))' -ex 'p $rsp' -ex q` - if the uop$ was not corrupted, you should see the current date/time. If it was, we would expect a segfault when writing to `0x42` at the poisoned address. +- **reptar.vdso.elf.bin.asm**: This is an experiment where we map ourselves just before the VDSO (you must disable ASLR first and adjust the addresses) and then make the "wrong RIP" point to the VDSO address of the time() function. As a result, the current time is stored in the address pointed to by RAX, which is then clflushed so it triggers a segfault to the current time. If we had corrupted the uop$ then we would instead expect a crash, so it appears that a long jump to the VDSO doesn't corrupt the uop$. To test try: `while :; do taskset -c 7 ./reptar.vdso.elf.bin | od -i | awk '{if($2){print strftime("%x %X",$2)}}' ; done` - if the uop$ was not corrupted, you should see the current date/time. If it was, we would expect a segfault when writing to `0x42` from the poisoned address. - **reptar.uncan.elf.bin.asm**: This is an experiment where we map ourselves at the end of the canonical address space for x86_64 (needs ASLR to be enabled) and then runs for as long as it can before it innevitably faults to see how far it can get into invalid address space. Error should be something like: `general protection fault ip:8000000019f5 error:0` with the last 4 bytes varying depending on how many iterations it did. - **reptar.mce.elf.asm**: Trigger this with `./log_mce.sh` and adjust the cpu 15/7 so they are siblings. This code will trigger an MCE on some affected CPUs and log the details. Look at `mce.txt` for the expected MCE errors. If no MCE is visible, define `MCE_INSTRUCTION='rep movsb'` as that works instead on some CPUs. - **reptar.mce.boot.bin.asm**: Same as mce, but instead intended to be ran from a VM using KVM. `qemu-system-x86_64 --enable-kvm -fda reptar.mce.boot.bin`. diff --git a/pocs/cpus/reptar/minimized/reptar.vdso.elf.bin.asm b/pocs/cpus/reptar/minimized/reptar.vdso.elf.bin.asm index 22a87338..f0f52e7f 100644 --- a/pocs/cpus/reptar/minimized/reptar.vdso.elf.bin.asm +++ b/pocs/cpus/reptar/minimized/reptar.vdso.elf.bin.asm @@ -3,6 +3,7 @@ _start: lea rax, [rsp - 0x1000] mov rbx, rax + add rbx, 16 mov r14, 0x41 xor rbp, rbp mov rdx, .end_of_program @@ -53,8 +54,11 @@ _start: inc rbp jmp .loop_for_every_iteration .end_of_program: - int3 - int3 + mov rax, 1 + mov rdi, 1 + mov rdx, 4 + syscall + ret %endmacro %include "third_party/tiny_elf.asm"