From 6cf0ead0dacaf958bec4b627d2dc41d2e8b6d47a Mon Sep 17 00:00:00 2001 From: Xaver Fabian Date: Thu, 19 Feb 2026 19:06:44 +0100 Subject: [PATCH] Enhance Tests for the journal version --- README.md | 8 +- journal/README.md | 25 ++ journal/combinations_tests/README.md | 11 + journal/combinations_tests/combined12.muasm | 12 + journal/combinations_tests/combined124.muasm | 16 ++ journal/combinations_tests/combined1245.muasm | 31 +++ .../combined1245_barrier.muasm | 32 +++ journal/combinations_tests/combined1246.muasm | 23 ++ .../combined1246_barrier.muasm | 24 ++ .../combined124_barrier.muasm | 17 ++ journal/combinations_tests/combined125.muasm | 27 ++ .../combined125_barrier.muasm | 28 ++ journal/combinations_tests/combined126.muasm | 17 ++ .../combined126_barrier.muasm | 18 ++ .../combined12_barrier.muasm | 13 + journal/combinations_tests/combined14.muasm | 16 ++ journal/combinations_tests/combined145.muasm | 31 +++ .../combined145_barrier.muasm | 32 +++ journal/combinations_tests/combined146.muasm | 19 ++ .../combined146_barrier.muasm | 20 ++ .../combined14_barrier.muasm | 17 ++ journal/combinations_tests/combined15.muasm | 26 ++ .../combined15_barrier.muasm | 27 ++ .../combined15_barrier_old.muasm | 27 ++ journal/combinations_tests/combined16.muasm | 15 ++ .../combined16_barrier.muasm | 15 ++ journal/combinations_tests/combined24.muasm | 15 ++ journal/combinations_tests/combined245.muasm | 28 ++ .../combined245_barrier.muasm | 29 +++ journal/combinations_tests/combined246.muasm | 20 ++ .../combined246_barrier.muasm | 21 ++ .../combined24_barrier.muasm | 16 ++ journal/combinations_tests/combined25.muasm | 26 ++ .../combined25_barrier.muasm | 26 ++ journal/combinations_tests/combined26.muasm | 16 ++ .../combined26_barrier.muasm | 17 ++ journal/combinations_tests/combined45.muasm | 27 ++ .../combined45_barrier.muasm | 28 ++ journal/combinations_tests/combined46.muasm | 16 ++ .../combined46_barrier.muasm | 17 ++ journal/combinations_tests/exec_all_combs.sh | 34 +++ .../exec_all_combs_barrier.sh | 33 +++ journal/combinations_tests/policy | 3 + journal/sls_tests/README.md | 4 + journal/sls_tests/example_sls.muasm | 8 + journal/sls_tests/example_sls_barrier.muasm | 9 + journal/sls_tests/execute_sls.sh | 18 ++ journal/sls_tests/leaky_functions.c | 28 ++ journal/sls_tests/leaky_functions.s | 134 ++++++++++ journal/sls_tests/leaky_functions_barrier.c | 29 +++ journal/sls_tests/leaky_functions_barrier.s | 139 ++++++++++ journal/sls_tests/leaky_main.c | 22 ++ journal/sls_tests/leaky_main.s | 107 ++++++++ journal/sls_tests/leaky_main_barrier.c | 23 ++ journal/sls_tests/leaky_main_barrier.s | 112 ++++++++ journal/sls_tests/makefile | 8 + journal/v2_tests/README.md | 8 + journal/v2_tests/examplev2.muasm | 13 + journal/v2_tests/examplev2_barrier.muasm | 13 + journal/v2_tests/execute_v2.sh | 19 ++ journal/v2_tests/func_table.c | 32 +++ journal/v2_tests/func_table.s | 240 ++++++++++++++++++ journal/v2_tests/func_table_barrier.c | 32 +++ journal/v2_tests/func_table_barrier.s | 240 ++++++++++++++++++ journal/v2_tests/jump_table.c | 38 +++ journal/v2_tests/jump_table.s | 156 ++++++++++++ journal/v2_tests/jump_table_barrier.c | 39 +++ journal/v2_tests/jump_table_barrier.s | 161 ++++++++++++ journal/v2_tests/makefile | 19 ++ .../v2_tests/retpoline_defense/func_table.c | 31 +++ .../v2_tests/retpoline_defense/func_table.s | 231 +++++++++++++++++ .../v2_tests/retpoline_defense/jump_table.c | 38 +++ .../v2_tests/retpoline_defense/jump_table.s | 153 +++++++++++ journal/v2_tests/retpoline_defense/makefile | 14 + journal/v4_tests/README.md | 6 + journal/v4_tests/case2_working_barrier.s | 78 ++++++ journal/v4_tests/case2_working_offsets.s | 73 ++++++ journal/v4_tests/litmus_stl/case1.c | 39 +++ journal/v4_tests/litmus_stl/case1.s | 85 +++++++ journal/v4_tests/litmus_stl/case10.c | 29 +++ journal/v4_tests/litmus_stl/case10.s | 98 +++++++ journal/v4_tests/litmus_stl/case11.c | 30 +++ journal/v4_tests/litmus_stl/case11.s | 99 ++++++++ journal/v4_tests/litmus_stl/case12.c | 29 +++ journal/v4_tests/litmus_stl/case12.s | 97 +++++++ journal/v4_tests/litmus_stl/case13.c | 33 +++ journal/v4_tests/litmus_stl/case13.s | 100 ++++++++ journal/v4_tests/litmus_stl/case2.c | 20 ++ .../litmus_stl/case2_working_offsets.s | 73 ++++++ journal/v4_tests/litmus_stl/case3.c | 22 ++ journal/v4_tests/litmus_stl/case3.s | 73 ++++++ journal/v4_tests/litmus_stl/case4.c | 24 ++ journal/v4_tests/litmus_stl/case4.s | 75 ++++++ journal/v4_tests/litmus_stl/case5_reg.c | 28 ++ journal/v4_tests/litmus_stl/case5_reg.s | 85 +++++++ journal/v4_tests/litmus_stl/case6.s | 93 +++++++ journal/v4_tests/litmus_stl/case6_reg.c | 29 +++ journal/v4_tests/litmus_stl/case6_reg.s | 93 +++++++ journal/v4_tests/litmus_stl/case7.c | 24 ++ journal/v4_tests/litmus_stl/case7.s | 82 ++++++ journal/v4_tests/litmus_stl/case8.c | 23 ++ journal/v4_tests/litmus_stl/case8.s | 80 ++++++ journal/v4_tests/litmus_stl/case9/case9.c | 32 +++ journal/v4_tests/litmus_stl/case9/case9.s | 94 +++++++ .../v4_tests/litmus_stl/execute_spectector.sh | 14 + journal/v4_tests/litmus_stl/makefile | 9 + journal/v4_tests/litmus_stl_barrier/case1.c | 38 +++ journal/v4_tests/litmus_stl_barrier/case1.s | 95 +++++++ journal/v4_tests/litmus_stl_barrier/case10.c | 29 +++ journal/v4_tests/litmus_stl_barrier/case10.s | 103 ++++++++ journal/v4_tests/litmus_stl_barrier/case11.c | 30 +++ journal/v4_tests/litmus_stl_barrier/case11.s | 104 ++++++++ journal/v4_tests/litmus_stl_barrier/case13.c | 33 +++ journal/v4_tests/litmus_stl_barrier/case13.s | 105 ++++++++ .../case2_working_barrier.s | 78 ++++++ journal/v4_tests/litmus_stl_barrier/case4.c | 24 ++ journal/v4_tests/litmus_stl_barrier/case4.s | 80 ++++++ .../v4_tests/litmus_stl_barrier/case5_mod.c | 28 ++ .../v4_tests/litmus_stl_barrier/case5_mod.s | 90 +++++++ .../v4_tests/litmus_stl_barrier/case6_mod.c | 29 +++ .../v4_tests/litmus_stl_barrier/case6_mod.s | 98 +++++++ journal/v4_tests/litmus_stl_barrier/case7.c | 24 ++ journal/v4_tests/litmus_stl_barrier/case7.s | 87 +++++++ journal/v4_tests/litmus_stl_barrier/case8.c | 23 ++ journal/v4_tests/litmus_stl_barrier/case8.s | 85 +++++++ journal/v4_tests/litmus_stl_barrier/config | 4 + .../litmus_stl_barrier/execute_spectector.sh | 11 + journal/v4_tests/litmus_stl_barrier/makefile | 9 + journal/v5_tests/README.md | 9 + journal/v5_tests/execute_v5.sh | 65 +++++ journal/v5_tests/makefile | 3 + journal/v5_tests/ret2spec_test/makefile | 9 + .../ret2spec_test/ret2spec_call_ret.c | 32 +++ .../ret2spec_test/ret2spec_call_ret.s | 128 ++++++++++ .../ret2spec_test/ret2spec_call_ret_barr.c | 33 +++ .../ret2spec_test/ret2spec_call_ret_barr.s | 133 ++++++++++ .../ret2spec_call_ret_retpoline.c | 38 +++ .../ret2spec_call_ret_retpoline.s | 149 +++++++++++ .../ret2spec_call_ret_test_new.c | 52 ++++ .../ret2spec_call_ret_test_new.s | 171 +++++++++++++ journal/v5_tests/transfail/ca_ip.c | 31 +++ journal/v5_tests/transfail/ca_ip.s | 133 ++++++++++ journal/v5_tests/transfail/ca_ip_barr.c | 32 +++ journal/v5_tests/transfail/ca_ip_barr.s | 138 ++++++++++ journal/v5_tests/transfail/ca_ip_retpoline.c | 38 +++ journal/v5_tests/transfail/ca_ip_retpoline.s | 160 ++++++++++++ journal/v5_tests/transfail/ca_oop.c | 27 ++ journal/v5_tests/transfail/ca_oop.s | 125 +++++++++ journal/v5_tests/transfail/ca_oop_barr.c | 27 ++ journal/v5_tests/transfail/ca_oop_barr.s | 130 ++++++++++ journal/v5_tests/transfail/ca_oop_retpoline.c | 41 +++ journal/v5_tests/transfail/ca_oop_retpoline.s | 150 +++++++++++ journal/v5_tests/transfail/makefile | 9 + journal/v5_tests/transfail/sa_ip.c | 37 +++ journal/v5_tests/transfail/sa_ip.s | 179 +++++++++++++ journal/v5_tests/transfail/sa_ip_barr.c | 38 +++ journal/v5_tests/transfail/sa_ip_barr.s | 182 +++++++++++++ journal/v5_tests/transfail/sa_ip_retpoline.c | 44 ++++ journal/v5_tests/transfail/sa_ip_retpoline.s | 204 +++++++++++++++ journal/v5_tests/transfail/sa_oop.c | 60 +++++ journal/v5_tests/transfail/sa_oop.s | 165 ++++++++++++ journal/v5_tests/transfail/sa_oop_barr.c | 61 +++++ journal/v5_tests/transfail/sa_oop_barr.s | 170 +++++++++++++ journal/v5_tests/transfail/sa_oop_min.c | 42 +++ journal/v5_tests/transfail/sa_oop_min.s | 133 ++++++++++ journal/v5_tests/transfail/sa_oop_retpoline.c | 67 +++++ .../v5_tests/transfail/sa_oop_retpoline.c~ | 66 +++++ .../v5_tests/transfail/sa_oop_retpoline.muasm | 34 +++ journal/v5_tests/transfail/sa_oop_retpoline.s | 190 ++++++++++++++ journal/v5_tests/transfail/transfail_ca_oop.s | 142 +++++++++++ 170 files changed, 9688 insertions(+), 2 deletions(-) create mode 100644 journal/README.md create mode 100644 journal/combinations_tests/README.md create mode 100644 journal/combinations_tests/combined12.muasm create mode 100644 journal/combinations_tests/combined124.muasm create mode 100644 journal/combinations_tests/combined1245.muasm create mode 100644 journal/combinations_tests/combined1245_barrier.muasm create mode 100644 journal/combinations_tests/combined1246.muasm create mode 100644 journal/combinations_tests/combined1246_barrier.muasm create mode 100644 journal/combinations_tests/combined124_barrier.muasm create mode 100644 journal/combinations_tests/combined125.muasm create mode 100644 journal/combinations_tests/combined125_barrier.muasm create mode 100644 journal/combinations_tests/combined126.muasm create mode 100644 journal/combinations_tests/combined126_barrier.muasm create mode 100644 journal/combinations_tests/combined12_barrier.muasm create mode 100644 journal/combinations_tests/combined14.muasm create mode 100644 journal/combinations_tests/combined145.muasm create mode 100644 journal/combinations_tests/combined145_barrier.muasm create mode 100644 journal/combinations_tests/combined146.muasm create mode 100644 journal/combinations_tests/combined146_barrier.muasm create mode 100644 journal/combinations_tests/combined14_barrier.muasm create mode 100644 journal/combinations_tests/combined15.muasm create mode 100644 journal/combinations_tests/combined15_barrier.muasm create mode 100644 journal/combinations_tests/combined15_barrier_old.muasm create mode 100644 journal/combinations_tests/combined16.muasm create mode 100644 journal/combinations_tests/combined16_barrier.muasm create mode 100644 journal/combinations_tests/combined24.muasm create mode 100644 journal/combinations_tests/combined245.muasm create mode 100644 journal/combinations_tests/combined245_barrier.muasm create mode 100644 journal/combinations_tests/combined246.muasm create mode 100644 journal/combinations_tests/combined246_barrier.muasm create mode 100644 journal/combinations_tests/combined24_barrier.muasm create mode 100644 journal/combinations_tests/combined25.muasm create mode 100644 journal/combinations_tests/combined25_barrier.muasm create mode 100644 journal/combinations_tests/combined26.muasm create mode 100644 journal/combinations_tests/combined26_barrier.muasm create mode 100644 journal/combinations_tests/combined45.muasm create mode 100644 journal/combinations_tests/combined45_barrier.muasm create mode 100644 journal/combinations_tests/combined46.muasm create mode 100644 journal/combinations_tests/combined46_barrier.muasm create mode 100755 journal/combinations_tests/exec_all_combs.sh create mode 100755 journal/combinations_tests/exec_all_combs_barrier.sh create mode 100644 journal/combinations_tests/policy create mode 100644 journal/sls_tests/README.md create mode 100644 journal/sls_tests/example_sls.muasm create mode 100644 journal/sls_tests/example_sls_barrier.muasm create mode 100755 journal/sls_tests/execute_sls.sh create mode 100644 journal/sls_tests/leaky_functions.c create mode 100644 journal/sls_tests/leaky_functions.s create mode 100644 journal/sls_tests/leaky_functions_barrier.c create mode 100644 journal/sls_tests/leaky_functions_barrier.s create mode 100644 journal/sls_tests/leaky_main.c create mode 100644 journal/sls_tests/leaky_main.s create mode 100644 journal/sls_tests/leaky_main_barrier.c create mode 100644 journal/sls_tests/leaky_main_barrier.s create mode 100644 journal/sls_tests/makefile create mode 100644 journal/v2_tests/README.md create mode 100644 journal/v2_tests/examplev2.muasm create mode 100644 journal/v2_tests/examplev2_barrier.muasm create mode 100755 journal/v2_tests/execute_v2.sh create mode 100644 journal/v2_tests/func_table.c create mode 100644 journal/v2_tests/func_table.s create mode 100644 journal/v2_tests/func_table_barrier.c create mode 100644 journal/v2_tests/func_table_barrier.s create mode 100644 journal/v2_tests/jump_table.c create mode 100644 journal/v2_tests/jump_table.s create mode 100644 journal/v2_tests/jump_table_barrier.c create mode 100644 journal/v2_tests/jump_table_barrier.s create mode 100644 journal/v2_tests/makefile create mode 100644 journal/v2_tests/retpoline_defense/func_table.c create mode 100644 journal/v2_tests/retpoline_defense/func_table.s create mode 100644 journal/v2_tests/retpoline_defense/jump_table.c create mode 100644 journal/v2_tests/retpoline_defense/jump_table.s create mode 100644 journal/v2_tests/retpoline_defense/makefile create mode 100644 journal/v4_tests/README.md create mode 100644 journal/v4_tests/case2_working_barrier.s create mode 100644 journal/v4_tests/case2_working_offsets.s create mode 100644 journal/v4_tests/litmus_stl/case1.c create mode 100644 journal/v4_tests/litmus_stl/case1.s create mode 100644 journal/v4_tests/litmus_stl/case10.c create mode 100644 journal/v4_tests/litmus_stl/case10.s create mode 100644 journal/v4_tests/litmus_stl/case11.c create mode 100644 journal/v4_tests/litmus_stl/case11.s create mode 100644 journal/v4_tests/litmus_stl/case12.c create mode 100644 journal/v4_tests/litmus_stl/case12.s create mode 100644 journal/v4_tests/litmus_stl/case13.c create mode 100644 journal/v4_tests/litmus_stl/case13.s create mode 100644 journal/v4_tests/litmus_stl/case2.c create mode 100644 journal/v4_tests/litmus_stl/case2_working_offsets.s create mode 100644 journal/v4_tests/litmus_stl/case3.c create mode 100644 journal/v4_tests/litmus_stl/case3.s create mode 100644 journal/v4_tests/litmus_stl/case4.c create mode 100644 journal/v4_tests/litmus_stl/case4.s create mode 100644 journal/v4_tests/litmus_stl/case5_reg.c create mode 100644 journal/v4_tests/litmus_stl/case5_reg.s create mode 100644 journal/v4_tests/litmus_stl/case6.s create mode 100644 journal/v4_tests/litmus_stl/case6_reg.c create mode 100644 journal/v4_tests/litmus_stl/case6_reg.s create mode 100644 journal/v4_tests/litmus_stl/case7.c create mode 100644 journal/v4_tests/litmus_stl/case7.s create mode 100644 journal/v4_tests/litmus_stl/case8.c create mode 100644 journal/v4_tests/litmus_stl/case8.s create mode 100644 journal/v4_tests/litmus_stl/case9/case9.c create mode 100644 journal/v4_tests/litmus_stl/case9/case9.s create mode 100755 journal/v4_tests/litmus_stl/execute_spectector.sh create mode 100644 journal/v4_tests/litmus_stl/makefile create mode 100644 journal/v4_tests/litmus_stl_barrier/case1.c create mode 100644 journal/v4_tests/litmus_stl_barrier/case1.s create mode 100644 journal/v4_tests/litmus_stl_barrier/case10.c create mode 100644 journal/v4_tests/litmus_stl_barrier/case10.s create mode 100644 journal/v4_tests/litmus_stl_barrier/case11.c create mode 100644 journal/v4_tests/litmus_stl_barrier/case11.s create mode 100644 journal/v4_tests/litmus_stl_barrier/case13.c create mode 100644 journal/v4_tests/litmus_stl_barrier/case13.s create mode 100644 journal/v4_tests/litmus_stl_barrier/case2_working_barrier.s create mode 100644 journal/v4_tests/litmus_stl_barrier/case4.c create mode 100644 journal/v4_tests/litmus_stl_barrier/case4.s create mode 100644 journal/v4_tests/litmus_stl_barrier/case5_mod.c create mode 100644 journal/v4_tests/litmus_stl_barrier/case5_mod.s create mode 100644 journal/v4_tests/litmus_stl_barrier/case6_mod.c create mode 100644 journal/v4_tests/litmus_stl_barrier/case6_mod.s create mode 100644 journal/v4_tests/litmus_stl_barrier/case7.c create mode 100644 journal/v4_tests/litmus_stl_barrier/case7.s create mode 100644 journal/v4_tests/litmus_stl_barrier/case8.c create mode 100644 journal/v4_tests/litmus_stl_barrier/case8.s create mode 100644 journal/v4_tests/litmus_stl_barrier/config create mode 100755 journal/v4_tests/litmus_stl_barrier/execute_spectector.sh create mode 100644 journal/v4_tests/litmus_stl_barrier/makefile create mode 100644 journal/v5_tests/README.md create mode 100755 journal/v5_tests/execute_v5.sh create mode 100644 journal/v5_tests/makefile create mode 100644 journal/v5_tests/ret2spec_test/makefile create mode 100644 journal/v5_tests/ret2spec_test/ret2spec_call_ret.c create mode 100644 journal/v5_tests/ret2spec_test/ret2spec_call_ret.s create mode 100644 journal/v5_tests/ret2spec_test/ret2spec_call_ret_barr.c create mode 100644 journal/v5_tests/ret2spec_test/ret2spec_call_ret_barr.s create mode 100644 journal/v5_tests/ret2spec_test/ret2spec_call_ret_retpoline.c create mode 100644 journal/v5_tests/ret2spec_test/ret2spec_call_ret_retpoline.s create mode 100644 journal/v5_tests/ret2spec_test/ret2spec_call_ret_test_new.c create mode 100644 journal/v5_tests/ret2spec_test/ret2spec_call_ret_test_new.s create mode 100644 journal/v5_tests/transfail/ca_ip.c create mode 100644 journal/v5_tests/transfail/ca_ip.s create mode 100644 journal/v5_tests/transfail/ca_ip_barr.c create mode 100644 journal/v5_tests/transfail/ca_ip_barr.s create mode 100644 journal/v5_tests/transfail/ca_ip_retpoline.c create mode 100644 journal/v5_tests/transfail/ca_ip_retpoline.s create mode 100644 journal/v5_tests/transfail/ca_oop.c create mode 100644 journal/v5_tests/transfail/ca_oop.s create mode 100644 journal/v5_tests/transfail/ca_oop_barr.c create mode 100644 journal/v5_tests/transfail/ca_oop_barr.s create mode 100644 journal/v5_tests/transfail/ca_oop_retpoline.c create mode 100644 journal/v5_tests/transfail/ca_oop_retpoline.s create mode 100644 journal/v5_tests/transfail/makefile create mode 100644 journal/v5_tests/transfail/sa_ip.c create mode 100644 journal/v5_tests/transfail/sa_ip.s create mode 100644 journal/v5_tests/transfail/sa_ip_barr.c create mode 100644 journal/v5_tests/transfail/sa_ip_barr.s create mode 100644 journal/v5_tests/transfail/sa_ip_retpoline.c create mode 100644 journal/v5_tests/transfail/sa_ip_retpoline.s create mode 100644 journal/v5_tests/transfail/sa_oop.c create mode 100644 journal/v5_tests/transfail/sa_oop.s create mode 100644 journal/v5_tests/transfail/sa_oop_barr.c create mode 100644 journal/v5_tests/transfail/sa_oop_barr.s create mode 100644 journal/v5_tests/transfail/sa_oop_min.c create mode 100644 journal/v5_tests/transfail/sa_oop_min.s create mode 100644 journal/v5_tests/transfail/sa_oop_retpoline.c create mode 100644 journal/v5_tests/transfail/sa_oop_retpoline.c~ create mode 100644 journal/v5_tests/transfail/sa_oop_retpoline.muasm create mode 100644 journal/v5_tests/transfail/sa_oop_retpoline.s create mode 100644 journal/v5_tests/transfail/transfail_ca_oop.s diff --git a/README.md b/README.md index d62b517..3e3b6b3 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,16 @@ This repository contains the benchmarks from the papers "Spectector: Principled Detection of Speculative Information Flows" (available -[here](https://spectector.github.io/papers/spectector.pdf)) and +[here](https://spectector.github.io/papers/spectector.pdf)), "Hardware/software contracts for secure speculation" (available -[here](https://spectector.github.io/papers/hwsw-contracts.pdf)). +[here](https://spectector.github.io/papers/hwsw-contracts.pdf)) +and the journal version +"Detecting speculative leaks with compositional semantics" (available +[here](https://spectector.github.io/papers/journal.pdf)) Here we describe how to reproduce the experimental results from the Spectector's paper. For the hardware/software contracts paper, see the `hwsw-contracts` folder. +For the journal paper see the `journal` folder as well. ## Case Study: Compiler countermeasures (Section VIII) diff --git a/journal/README.md b/journal/README.md new file mode 100644 index 0000000..d70a9ab --- /dev/null +++ b/journal/README.md @@ -0,0 +1,25 @@ +# Tests + +These are the additonal tests for Spectre versions different from V1. +The V1 test cases can be found the sources folder. + +There are sub-folders v4_tests, v5_tests, v2_tests, sls_tests and combinations_tests containing examples. Each sub-folder provides its own script to execute all the tests inside it. They are also a pointer on how to use the tool. Some sub-folders have additional README files with more information. + + +The different versions can be selected using the --version flag. The different versions are: + +- 1 : V1 (original implementation of Spectector) +- 2 : Spectre V2 +- 4 : Spectre V4 +- 5 : Spectre V5 +- 6 : Spectre SLS + +and any combination of those versions that are allowed. Versions that are not allowed are combinations of 5 and 6, because they speculate on the same instructions. More details in the paper. For example: + +- 14 : Spectre V1 + Spectre V4 +- 45 : V4 + V5 +- 15 : V1 + V5 +- 145: V1 + V4 + V5 +- 1245 : V1 + V2 + V4 + V5 + +See the provided scripts to see examples for the usage. \ No newline at end of file diff --git a/journal/combinations_tests/README.md b/journal/combinations_tests/README.md new file mode 100644 index 0000000..84bd547 --- /dev/null +++ b/journal/combinations_tests/README.md @@ -0,0 +1,11 @@ +We sometimes added the construct +load f, secret % set up a secret +store f, 1 +spbarr + +to some test cases. This is done to set up a secret for Spectector and does not influence the vulnerability. For Spectector all memory regions are high values and all registers are low. +The problem is that we cannot specify the value secret to be high. There is no option for that. So we add this snippet which means that we have a high symbolic value stored at location 1. + +Use the script exec_all_combs.sh to see all the combinations in action. For each of the combinations, we created an +example showing the additional strength. +There is a version with a barrier inserted as well. diff --git a/journal/combinations_tests/combined12.muasm b/journal/combinations_tests/combined12.muasm new file mode 100644 index 0000000..793e90b --- /dev/null +++ b/journal/combinations_tests/combined12.muasm @@ -0,0 +1,12 @@ +main: + rax <- L2 + indirect_jump rax +spec: + endbr + x <- 0 + beqz x , L2 +L100: + load eax, secret_addr % Should never be executed + load edi, eax +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined124.muasm b/journal/combinations_tests/combined124.muasm new file mode 100644 index 0000000..9309b87 --- /dev/null +++ b/journal/combinations_tests/combined124.muasm @@ -0,0 +1,16 @@ +main: + load f, secret % prepare a secret + store f, 0 + spbarr + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + x <- 0 + beqz x, L2 + store 1, 0 % overwrite but V4 + load eax, 0 % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined1245.muasm b/journal/combinations_tests/combined1245.muasm new file mode 100644 index 0000000..99b510b --- /dev/null +++ b/journal/combinations_tests/combined1245.muasm @@ -0,0 +1,31 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + x <- 0 + beqz x, L2 + store 1, 0 % Overwrite secret, will be skipped + load eax, 0 % Should never be executed + load edi, eax + spbarr +main: + load f, secret % prepare a secret + store f, 0 + spbarr + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined1245_barrier.muasm b/journal/combinations_tests/combined1245_barrier.muasm new file mode 100644 index 0000000..b3e001d --- /dev/null +++ b/journal/combinations_tests/combined1245_barrier.muasm @@ -0,0 +1,32 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + spbarr + x <- 0 + beqz x, L2 + store 1, 0 % Overwrite secret, will be skipped + load eax, 0 % Should never be executed + load edi, eax + spbarr +main: + load f, secret % prepare a secret + store f, 0 + spbarr + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined1246.muasm b/journal/combinations_tests/combined1246.muasm new file mode 100644 index 0000000..996a0f5 --- /dev/null +++ b/journal/combinations_tests/combined1246.muasm @@ -0,0 +1,23 @@ +main: + load f, secret + store f, 0 + spbarr + store 1, 0 + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +L1: + rax <- L2 + indirect_jump rax +spec: + endbr + x <- 0 + beqz x , L2 +L100: + load eax, 1 % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined1246_barrier.muasm b/journal/combinations_tests/combined1246_barrier.muasm new file mode 100644 index 0000000..2780d97 --- /dev/null +++ b/journal/combinations_tests/combined1246_barrier.muasm @@ -0,0 +1,24 @@ +main: + load f, secret + store f, 0 + spbarr + store 1, 0 + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +L1: + rax <- L2 + indirect_jump rax +spec: + endbr + spbarr + x <- 0 + beqz x , L2 +L100: + load eax, 1 % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined124_barrier.muasm b/journal/combinations_tests/combined124_barrier.muasm new file mode 100644 index 0000000..f140c1a --- /dev/null +++ b/journal/combinations_tests/combined124_barrier.muasm @@ -0,0 +1,17 @@ +main: + load f, secret % prepare a secret + store f, 0 + spbarr + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + spbarr + x <- 0 + beqz x, L2 + store 1, 0 % overwrite but V4 + load eax, 0 % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined125.muasm b/journal/combinations_tests/combined125.muasm new file mode 100644 index 0000000..ba80dea --- /dev/null +++ b/journal/combinations_tests/combined125.muasm @@ -0,0 +1,27 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + x <- 0 + beqz x, L2 + load eax, secret_addr % Should never be executed + load edi, eax + spbarr +main: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined125_barrier.muasm b/journal/combinations_tests/combined125_barrier.muasm new file mode 100644 index 0000000..c70ab48 --- /dev/null +++ b/journal/combinations_tests/combined125_barrier.muasm @@ -0,0 +1,28 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + spbarr + x <- 0 + beqz x, L2 + load eax, secret_addr % Should never be executed + load edi, eax + spbarr +main: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined126.muasm b/journal/combinations_tests/combined126.muasm new file mode 100644 index 0000000..5fa5b4b --- /dev/null +++ b/journal/combinations_tests/combined126.muasm @@ -0,0 +1,17 @@ +main: + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +spec: + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + x <- 0 + beqz x, L2 + load eax, secret_addr % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined126_barrier.muasm b/journal/combinations_tests/combined126_barrier.muasm new file mode 100644 index 0000000..6a5281e --- /dev/null +++ b/journal/combinations_tests/combined126_barrier.muasm @@ -0,0 +1,18 @@ +main: + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +spec: + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + spbarr + x <- 0 + beqz x, L2 + load eax, secret_addr % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined12_barrier.muasm b/journal/combinations_tests/combined12_barrier.muasm new file mode 100644 index 0000000..4be04c5 --- /dev/null +++ b/journal/combinations_tests/combined12_barrier.muasm @@ -0,0 +1,13 @@ +main: + rax <- L2 + indirect_jump rax +spec: + endbr + x <- 0 + beqz x , L2 + spbarr +L100: + load eax, secret_addr % Should never be executed + load edi, eax +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined14.muasm b/journal/combinations_tests/combined14.muasm new file mode 100644 index 0000000..f4c3194 --- /dev/null +++ b/journal/combinations_tests/combined14.muasm @@ -0,0 +1,16 @@ + + + +main: + load f, secret % set up a secret for spectector + store f, 1 + spbarr + store 0, 1 % overwrite the secret in memory + x <- 0 + beqz x, L1 +L2: + load x, 1 + load eax, x % This should show us the secret value + spbarr +L1: + skip diff --git a/journal/combinations_tests/combined145.muasm b/journal/combinations_tests/combined145.muasm new file mode 100644 index 0000000..5b5599d --- /dev/null +++ b/journal/combinations_tests/combined145.muasm @@ -0,0 +1,31 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + x <- 0 + beqz x , L2 +L100: + load eax, 0 % leak secret + load edi, eax +L2: + spbarr + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +main: + load f, secret % prepare a secret + store f, 0 + spbarr + store 1, 0 % overwrites the secret but will be skipped speculatively + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate diff --git a/journal/combinations_tests/combined145_barrier.muasm b/journal/combinations_tests/combined145_barrier.muasm new file mode 100644 index 0000000..646a4da --- /dev/null +++ b/journal/combinations_tests/combined145_barrier.muasm @@ -0,0 +1,32 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + x <- 0 + beqz x , L2 +L100: + load eax, 0 % leak secret + load edi, eax +L2: + spbarr + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +main: + load f, secret % prepare a secret + store f, 0 + spbarr + store 1, 0 % overwrites the secret and will not be skipped speculatively because of abrrier adterwards + spbarr + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate \ No newline at end of file diff --git a/journal/combinations_tests/combined146.muasm b/journal/combinations_tests/combined146.muasm new file mode 100644 index 0000000..af012ed --- /dev/null +++ b/journal/combinations_tests/combined146.muasm @@ -0,0 +1,19 @@ +main: + load f, secret % set up a secret for spectector + store f, 1 + spbarr + store 0, 1 % overwrite the secret in memory + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +spec: + x <- 0 + beqz x , L2 +L100: + load eax, 1 % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined146_barrier.muasm b/journal/combinations_tests/combined146_barrier.muasm new file mode 100644 index 0000000..f811b44 --- /dev/null +++ b/journal/combinations_tests/combined146_barrier.muasm @@ -0,0 +1,20 @@ +main: + load f, secret % set up a secret for spectector + store f, 1 + spbarr + store 0, 1 % overwrite the secret in memory + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +spec: + x <- 0 + beqz x , L2 +L100: + spbarr + load eax, 1 % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined14_barrier.muasm b/journal/combinations_tests/combined14_barrier.muasm new file mode 100644 index 0000000..b546d92 --- /dev/null +++ b/journal/combinations_tests/combined14_barrier.muasm @@ -0,0 +1,17 @@ + + + +main: + load f, secret % set up a secret + store f, 1 + spbarr + store 0, 1 + x <- 0 + beqz x, L1 + spbarr +L2: + load x, 1 + load eax, x % This shou.d show us the secret value + spbarr +L1: + skip diff --git a/journal/combinations_tests/combined15.muasm b/journal/combinations_tests/combined15.muasm new file mode 100644 index 0000000..02bc924 --- /dev/null +++ b/journal/combinations_tests/combined15.muasm @@ -0,0 +1,26 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + x <- 0 + beqz x , L2 +L100: + load eax, secret_addr % Should never be executed + load edi, eax +L2: + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +main: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate \ No newline at end of file diff --git a/journal/combinations_tests/combined15_barrier.muasm b/journal/combinations_tests/combined15_barrier.muasm new file mode 100644 index 0000000..3c8b851 --- /dev/null +++ b/journal/combinations_tests/combined15_barrier.muasm @@ -0,0 +1,27 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + x <- 0 + beqz x , L2 + spbarr +L100: + load eax, secret_addr % Should never be executed + load edi, eax +L2: + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +main: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate \ No newline at end of file diff --git a/journal/combinations_tests/combined15_barrier_old.muasm b/journal/combinations_tests/combined15_barrier_old.muasm new file mode 100644 index 0000000..478c816 --- /dev/null +++ b/journal/combinations_tests/combined15_barrier_old.muasm @@ -0,0 +1,27 @@ +% See combined15_old.muasm for details +test: + spbarr + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +main: + dx <- 5 + skip + x <- 0 + beqz x , L2 % Since X is 0 this should misspeculate and should handle the call instruction to fill RSB after with return address after the call + spbarr + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp 0 +L100: + load eax, secret_addr % Should never be executed + load edi, eax + spbarr +L2: + skip + retstart + load tmp,sp/\140737488355327 % We just return and this should speculate under V5 semantics so we execute the function + sp<-sp+8 + jmp tmp diff --git a/journal/combinations_tests/combined16.muasm b/journal/combinations_tests/combined16.muasm new file mode 100644 index 0000000..7033a3d --- /dev/null +++ b/journal/combinations_tests/combined16.muasm @@ -0,0 +1,15 @@ + +main: + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +spec: + x <- 0 + beqz x , L2 +L100: + load eax, secret_addr % Should never be executed + load edi, eax +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined16_barrier.muasm b/journal/combinations_tests/combined16_barrier.muasm new file mode 100644 index 0000000..f5fc865 --- /dev/null +++ b/journal/combinations_tests/combined16_barrier.muasm @@ -0,0 +1,15 @@ +main: + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +spec: + x <- 0 + beqz x , L2 + spbarr +L100: + load eax, secret_addr % Should never be executed + load edi, eax +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined24.muasm b/journal/combinations_tests/combined24.muasm new file mode 100644 index 0000000..b2037ab --- /dev/null +++ b/journal/combinations_tests/combined24.muasm @@ -0,0 +1,15 @@ +spec: + endbr + store 1, 0 + load x, 1 + load eax, x % This shou.d show us the secret value + spbarr + +main: + load f, secret + store f, 0 + spbarr + rax <- L2 + indirect_jump rax +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined245.muasm b/journal/combinations_tests/combined245.muasm new file mode 100644 index 0000000..e63fef3 --- /dev/null +++ b/journal/combinations_tests/combined245.muasm @@ -0,0 +1,28 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + load eax, 0 % leak secret + load edi, eax +main: + load f, secret % prepare a secret + store f, 0 + spbarr + store 1, 0 % overwrites the secret but will be skipped speculatively + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined245_barrier.muasm b/journal/combinations_tests/combined245_barrier.muasm new file mode 100644 index 0000000..783c47a --- /dev/null +++ b/journal/combinations_tests/combined245_barrier.muasm @@ -0,0 +1,29 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + spbarr + load eax, 0 % leak secret + load edi, eax +main: + load f, secret % prepare a secret + store f, 0 + spbarr + store 1, 0 % overwrites the secret but will be skipped speculatively + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined246.muasm b/journal/combinations_tests/combined246.muasm new file mode 100644 index 0000000..ec4ab24 --- /dev/null +++ b/journal/combinations_tests/combined246.muasm @@ -0,0 +1,20 @@ +main: + load f, secret + store f, 0 + spbarr + store 1, 0 + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +L1: + rax <- L2 + indirect_jump rax +L100: + endbr + load eax, 1 % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined246_barrier.muasm b/journal/combinations_tests/combined246_barrier.muasm new file mode 100644 index 0000000..1eeb7b1 --- /dev/null +++ b/journal/combinations_tests/combined246_barrier.muasm @@ -0,0 +1,21 @@ +main: + load f, secret + store f, 0 + spbarr + store 1, 0 + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +L1: + rax <- L2 + indirect_jump rax +L100: + endbr + spbarr + load eax, 1 % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined24_barrier.muasm b/journal/combinations_tests/combined24_barrier.muasm new file mode 100644 index 0000000..d2f9a3d --- /dev/null +++ b/journal/combinations_tests/combined24_barrier.muasm @@ -0,0 +1,16 @@ +spec: + endbr + spbarr + store 1, 0 + load x, 1 + load eax, x % This shou.d show us the secret value + spbarr + +main: + load f, secret + store f, 0 + spbarr + rax <- L2 + indirect_jump rax +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined25.muasm b/journal/combinations_tests/combined25.muasm new file mode 100644 index 0000000..b7dc556 --- /dev/null +++ b/journal/combinations_tests/combined25.muasm @@ -0,0 +1,26 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + load eax, secret_addr % Should never be executed + load edi, eax + spbarr +main: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate +L2: + skip + diff --git a/journal/combinations_tests/combined25_barrier.muasm b/journal/combinations_tests/combined25_barrier.muasm new file mode 100644 index 0000000..40072a1 --- /dev/null +++ b/journal/combinations_tests/combined25_barrier.muasm @@ -0,0 +1,26 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + rax <- L2 % Spec v5 reaches here + indirect_jump rax +L100: + endbr + spbarr + load eax, secret_addr % Should never be executed + load edi, eax + spbarr +main: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined26.muasm b/journal/combinations_tests/combined26.muasm new file mode 100644 index 0000000..39c5d36 --- /dev/null +++ b/journal/combinations_tests/combined26.muasm @@ -0,0 +1,16 @@ +main: + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +L1: + rax <- L2 + indirect_jump rax +L100: + endbr + load eax, secret_addr % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined26_barrier.muasm b/journal/combinations_tests/combined26_barrier.muasm new file mode 100644 index 0000000..58d0ceb --- /dev/null +++ b/journal/combinations_tests/combined26_barrier.muasm @@ -0,0 +1,17 @@ +main: + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +L1: + rax <- L2 + indirect_jump rax +L100: + endbr + spbarr + load eax, secret_addr % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined45.muasm b/journal/combinations_tests/combined45.muasm new file mode 100644 index 0000000..cd9a0df --- /dev/null +++ b/journal/combinations_tests/combined45.muasm @@ -0,0 +1,27 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + load eax, 0 % Will never be executed + load edi, eax + spbarr + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +main: + load f, secret + store f, 0 + spbarr + store 1, 0 + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate diff --git a/journal/combinations_tests/combined45_barrier.muasm b/journal/combinations_tests/combined45_barrier.muasm new file mode 100644 index 0000000..26f7e3a --- /dev/null +++ b/journal/combinations_tests/combined45_barrier.muasm @@ -0,0 +1,28 @@ +manipStack: + sp <- sp + 8 % pop return address so we jumo back to main + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +speculate: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipStack + spbarr + load eax, 0 % Will never be executed + load edi, eax + spbarr + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +main: + load f, secret + store f, 0 + spbarr + store 1, 0 + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp speculate diff --git a/journal/combinations_tests/combined46.muasm b/journal/combinations_tests/combined46.muasm new file mode 100644 index 0000000..c230b8a --- /dev/null +++ b/journal/combinations_tests/combined46.muasm @@ -0,0 +1,16 @@ +main: + load f, secret % set up a secret for spectector + store f, 1 + spbarr + store 0, 1 % overwrite the secret in memory + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +spec: + load eax, 1 % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/combined46_barrier.muasm b/journal/combinations_tests/combined46_barrier.muasm new file mode 100644 index 0000000..7f73f1b --- /dev/null +++ b/journal/combinations_tests/combined46_barrier.muasm @@ -0,0 +1,17 @@ +main: + load f, secret % set up a secret for spectector + store f, 1 + spbarr + store 0, 1 % overwrite the secret in memory + eax <- 5 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp + spbarr +spec: + load eax, 1 % Should never be executed + load edi, eax + spbarr +L2: + skip \ No newline at end of file diff --git a/journal/combinations_tests/exec_all_combs.sh b/journal/combinations_tests/exec_all_combs.sh new file mode 100755 index 0000000..c417b9f --- /dev/null +++ b/journal/combinations_tests/exec_all_combs.sh @@ -0,0 +1,34 @@ +common_args=($SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' -w 200 --skip-uns -e [main] --parse-uns) +# First arg is program name without suffix and second arg is version executed under +exec_version() { + echo "--------------Execute $1 under Version $2--------------------" + spectector "$1.muasm" ${common_args[@]} --version $2 --stats "stats/$1_$2_stats.txt" | grep 'data leak\|program is' + +} +echo "---------------- Executes all the combinations on a snippet showing the combined vulenerability" + echo "--------------Executions of all 2 combinations--------------------" +exec_version "combined15" 15 +exec_version "combined14" 14 +exec_version "combined45" 45 +exec_version "combined16" 16 +exec_version "combined46" 46 +exec_version "combined12" 12 +exec_version "combined24" 24 +exec_version "combined25" 25 +exec_version "combined26" 26 +echo "--------------Executions of all 3 combinations --------------------" +exec_version "combined145" 145 +exec_version "combined146" 146 +exec_version "combined124" 124 +exec_version "combined125" 125 +exec_version "combined126" 126 +exec_version "combined245" 245 +exec_version "combined246" 246 +echo "--------------Executions of all 4 combinations--------------------" +exec_version "combined1245" 1245 +exec_version "combined1246" 1246 +for file in stats/* + do + truncate -s -1 $file + done +exit \ No newline at end of file diff --git a/journal/combinations_tests/exec_all_combs_barrier.sh b/journal/combinations_tests/exec_all_combs_barrier.sh new file mode 100755 index 0000000..1778f58 --- /dev/null +++ b/journal/combinations_tests/exec_all_combs_barrier.sh @@ -0,0 +1,33 @@ +common_args=($SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' -w 200 --skip-uns -e [main] --parse-uns) +# First arg is program name without suffix and second arg is version executed under +exec_version() { + echo "--------------Execute $1 under Version $2--------------------" + spectector "$1_barrier.muasm" ${common_args[@]} --version $2 --stats "stats/$1_$2_stats.txt" | grep 'data leak\|program is' +} +echo "---------------- Executes all the combinations on a snippet showing the combined vulenerability" + echo "--------------Executions of all 2 combinations--------------------" +exec_version "combined15" 15 +exec_version "combined14" 14 +exec_version "combined45" 45 +exec_version "combined16" 16 +exec_version "combined46" 46 +exec_version "combined12" 12 +exec_version "combined24" 24 +exec_version "combined25" 25 +exec_version "combined26" 26 +echo "--------------Executions of all 3 combinations --------------------" +exec_version "combined145" 145 +exec_version "combined146" 146 +exec_version "combined124" 124 +exec_version "combined125" 125 +exec_version "combined126" 126 +exec_version "combined245" 245 +exec_version "combined246" 246 +echo "--------------Executions of all 4 combinations--------------------" +exec_version "combined1245" 1245 +exec_version "combined1246" 1246 +for file in stats/* + do + truncate -s -1 $file + done +exit \ No newline at end of file diff --git a/journal/combinations_tests/policy b/journal/combinations_tests/policy new file mode 100644 index 0000000..bd95715 --- /dev/null +++ b/journal/combinations_tests/policy @@ -0,0 +1,3 @@ +c([],[]). +low([]). +ign([secret]). diff --git a/journal/sls_tests/README.md b/journal/sls_tests/README.md new file mode 100644 index 0000000..a5f5d0e --- /dev/null +++ b/journal/sls_tests/README.md @@ -0,0 +1,4 @@ +## SLS Examples + +Use the provided script execute_sls.sh to execute all examples. +To generate the .s files you can use make. diff --git a/journal/sls_tests/example_sls.muasm b/journal/sls_tests/example_sls.muasm new file mode 100644 index 0000000..18a264c --- /dev/null +++ b/journal/sls_tests/example_sls.muasm @@ -0,0 +1,8 @@ +main: + skip + retstart + load tmp,sp/\140737488355327 + sp <- sp+8 + jmp tmp + load eax, secret_addr % Should never be executed + load edi, eax diff --git a/journal/sls_tests/example_sls_barrier.muasm b/journal/sls_tests/example_sls_barrier.muasm new file mode 100644 index 0000000..78fa0ea --- /dev/null +++ b/journal/sls_tests/example_sls_barrier.muasm @@ -0,0 +1,9 @@ +main: + skip + retstart + load tmp,sp/\140737488355327 + sp <- sp+8 + jmp tmp + spbarr + load eax, secret_addr % Should never be executed + load edi, eax diff --git a/journal/sls_tests/execute_sls.sh b/journal/sls_tests/execute_sls.sh new file mode 100755 index 0000000..c68921f --- /dev/null +++ b/journal/sls_tests/execute_sls.sh @@ -0,0 +1,18 @@ + +echo "----------------------------------- Leaky Main compiled from C -----------------------------" +spectector "leaky_main.s" $SOLVER -s --steps 1000000 -w 200 --keep-sym [secretarray] -v 6 -e [main] --parse-uns --skip-uns | grep 'data leak\|program is' +echo "----------------------------------- with barrier -------------------------------------------" +spectector "leaky_main_barrier.s" $SOLVER -s --steps 1000000 -w 200 --keep-sym [secretarray] -v 6 -e [main] --parse-uns --skip-uns | grep 'data leak\|program is' + + + +echo "----------------------------------- Leaky Functions compiled from C -------------------------" +spectector "leaky_functions.s" $SOLVER -s --steps 1000000 -w 200 --keep-sym [secretarray] -v 6 -e [main] --parse-uns --skip-uns | grep 'data leak\|program is' +echo "----------------------------------- with barrier --------------------------------------------" +spectector "leaky_functions_barrier.s" $SOLVER -s --steps 1000000 -w 200 --keep-sym [secretarray] -v 6 -e [main] --parse-uns --skip-uns | grep 'data leak\|program is' + +echo "----------------------------------- simple muasm example ----------------------------------------" +spectector "example_sls.muasm" $SOLVER -s --steps 1000000 -w 200 -v 6 | grep 'data leak\|program is' + +echo "----------------------------------- simple muasm with barrier -----------------------------------" +spectector "example_sls_barrier.muasm" $SOLVER -s --steps 1000000 -w 200 -v 6 | grep 'data leak\|program is' diff --git a/journal/sls_tests/leaky_functions.c b/journal/sls_tests/leaky_functions.c new file mode 100644 index 0000000..e6db889 --- /dev/null +++ b/journal/sls_tests/leaky_functions.c @@ -0,0 +1,28 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; +int called(int idx) { + return 5; +} + +// This function is never called +void leaky(int idx) { + uint8_t val = secretarray[idx]; + temp &= publicarray[val]; +} +asm("lfence"); // stops additional speculation + + +void main(int idx) { + int res = called(idx); + int c = 2 + res; +} +asm("lfence"); diff --git a/journal/sls_tests/leaky_functions.s b/journal/sls_tests/leaky_functions.s new file mode 100644 index 0000000..3678fd0 --- /dev/null +++ b/journal/sls_tests/leaky_functions.s @@ -0,0 +1,134 @@ + .file "leaky_functions.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 16 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl called + .type called, @function +called: +.LFB0: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -4(%rbp) + movl $5, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size called, .-called + .globl leaky + .type leaky, @function +leaky: +.LFB1: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + movl -20(%rbp), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movb %al, -1(%rbp) + movzbl -1(%rbp), %eax + cltq + leaq publicarray(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size leaky, .-leaky +#APP + lfence +#NO_APP + .globl main + .type main, @function +main: +.LFB2: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $24, %rsp + movl %edi, -20(%rbp) + movl -20(%rbp), %eax + movl %eax, %edi + call called + movl %eax, -8(%rbp) + movl -8(%rbp), %eax + addl $2, %eax + movl %eax, -4(%rbp) + nop + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size main, .-main +#APP + lfence + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/journal/sls_tests/leaky_functions_barrier.c b/journal/sls_tests/leaky_functions_barrier.c new file mode 100644 index 0000000..f009c23 --- /dev/null +++ b/journal/sls_tests/leaky_functions_barrier.c @@ -0,0 +1,29 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; +int called(int idx) { + return 5; +} + +// This function is never called +void leaky(int idx) { + asm("lfence"); + uint8_t val = secretarray[idx]; + temp &= publicarray[val]; +} +asm("lfence"); // stops additional speculation + + +void main(int idx) { + int res = called(idx); + int c = 2 + res; +} +asm("lfence"); diff --git a/journal/sls_tests/leaky_functions_barrier.s b/journal/sls_tests/leaky_functions_barrier.s new file mode 100644 index 0000000..1c16d7d --- /dev/null +++ b/journal/sls_tests/leaky_functions_barrier.s @@ -0,0 +1,139 @@ + .file "leaky_functions_barrier.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 16 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl called + .type called, @function +called: +.LFB0: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -4(%rbp) + movl $5, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size called, .-called + .globl leaky + .type leaky, @function +leaky: +.LFB1: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) +#APP +# 18 "leaky_functions_barrier.c" 1 + lfence +# 0 "" 2 +#NO_APP + movl -20(%rbp), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movb %al, -1(%rbp) + movzbl -1(%rbp), %eax + cltq + leaq publicarray(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size leaky, .-leaky +#APP + lfence +#NO_APP + .globl main + .type main, @function +main: +.LFB2: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $24, %rsp + movl %edi, -20(%rbp) + movl -20(%rbp), %eax + movl %eax, %edi + call called + movl %eax, -8(%rbp) + movl -8(%rbp), %eax + addl $2, %eax + movl %eax, -4(%rbp) + nop + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size main, .-main +#APP + lfence + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/journal/sls_tests/leaky_main.c b/journal/sls_tests/leaky_main.c new file mode 100644 index 0000000..73199a6 --- /dev/null +++ b/journal/sls_tests/leaky_main.c @@ -0,0 +1,22 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + +void main(int idx) { + int c = 2 + idx; + return; +} +// This function is never called +void leaky(int idx) { + uint8_t val = secretarray[idx]; + temp &= publicarray[val]; +} +asm("lfence"); // stops additional speculation \ No newline at end of file diff --git a/journal/sls_tests/leaky_main.s b/journal/sls_tests/leaky_main.s new file mode 100644 index 0000000..511d7fd --- /dev/null +++ b/journal/sls_tests/leaky_main.s @@ -0,0 +1,107 @@ + .file "leaky_main.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 16 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + movl -20(%rbp), %eax + addl $2, %eax + movl %eax, -4(%rbp) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size main, .-main + .globl leaky + .type leaky, @function +leaky: +.LFB1: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + movl -20(%rbp), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movb %al, -1(%rbp) + movzbl -1(%rbp), %eax + cltq + leaq publicarray(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size leaky, .-leaky +#APP + lfence + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/journal/sls_tests/leaky_main_barrier.c b/journal/sls_tests/leaky_main_barrier.c new file mode 100644 index 0000000..bbbb979 --- /dev/null +++ b/journal/sls_tests/leaky_main_barrier.c @@ -0,0 +1,23 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + +void main(int idx) { + int c = 2 + idx; + return; +} +// This function is never called +void leaky(int idx) { + asm("lfence"); + uint8_t val = secretarray[idx]; + temp &= publicarray[val]; +} +asm("lfence"); // stops additional speculation diff --git a/journal/sls_tests/leaky_main_barrier.s b/journal/sls_tests/leaky_main_barrier.s new file mode 100644 index 0000000..c5d726e --- /dev/null +++ b/journal/sls_tests/leaky_main_barrier.s @@ -0,0 +1,112 @@ + .file "leaky_main_barrier.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 16 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + movl -20(%rbp), %eax + addl $2, %eax + movl %eax, -4(%rbp) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size main, .-main + .globl leaky + .type leaky, @function +leaky: +.LFB1: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) +#APP +# 19 "leaky_main_barrier.c" 1 + lfence +# 0 "" 2 +#NO_APP + movl -20(%rbp), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movb %al, -1(%rbp) + movzbl -1(%rbp), %eax + cltq + leaq publicarray(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size leaky, .-leaky +#APP + lfence + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/journal/sls_tests/makefile b/journal/sls_tests/makefile new file mode 100644 index 0000000..9a217c2 --- /dev/null +++ b/journal/sls_tests/makefile @@ -0,0 +1,8 @@ + +SOURCES = $(wildcard *.c) +ASM = $(patsubst %.c, %.s, $(SOURCES)) +$(info $$var is [${SOURCES}]) +$(ASM): $(SOURCES) + $(CC) -O0 -S -c $^ +clean: + rm -rf *.s diff --git a/journal/v2_tests/README.md b/journal/v2_tests/README.md new file mode 100644 index 0000000..2dbdee4 --- /dev/null +++ b/journal/v2_tests/README.md @@ -0,0 +1,8 @@ +## V2 Tests + +Note that no additional flags need to be given to the compiler for endbr64 instructions to be added to the assembly +program. + +You can use the provided makefile to recompile the programs yourself. + +Furthermore, the provided scripts executes all programs. diff --git a/journal/v2_tests/examplev2.muasm b/journal/v2_tests/examplev2.muasm new file mode 100644 index 0000000..0778ba6 --- /dev/null +++ b/journal/v2_tests/examplev2.muasm @@ -0,0 +1,13 @@ +spec: + endbr + load eax, secret_addr + load edi, eax + spbarr +main: + rax <- fin + skip + indirect_jump rax + endbr + +fin: + skip diff --git a/journal/v2_tests/examplev2_barrier.muasm b/journal/v2_tests/examplev2_barrier.muasm new file mode 100644 index 0000000..f5d5871 --- /dev/null +++ b/journal/v2_tests/examplev2_barrier.muasm @@ -0,0 +1,13 @@ +spec: + endbr + spbarr + load eax, secret_addr + load edi, eax +main: + rax <- fin + skip + indirect_jump rax + endbr + +fin: + skip diff --git a/journal/v2_tests/execute_v2.sh b/journal/v2_tests/execute_v2.sh new file mode 100755 index 0000000..b673457 --- /dev/null +++ b/journal/v2_tests/execute_v2.sh @@ -0,0 +1,19 @@ + +echo "--------------------------------------------- A jump table ---------------------------------------------------" +spectector "jump_table.s" $SOLVER --steps 1000000 -w 200 --keep-sym [secretarray] -e [main] -v 2 --skip-uns --parse-uns | grep 'data leak\|program is' +echo "--------------------------------------------- with barrier ---------------------------------------------------" +spectector "jump_table_barrier.s" $SOLVER --steps 1000000 -w 200 --keep-sym [secretarray] -e [main] -v 2 --skip-uns --parse-uns | grep 'data leak\|program is' +echo "--------------------------------------------- with retpoline --------------------------------------------------" +spectector "retpoline_defense/jump_table.s" $SOLVER --steps 1000000 -w 200 --keep-sym [secretarray] -e [main] -v 2 --skip-uns --parse-uns | grep 'data leak\|program is' + +echo "-------------------------------------------- Different function Pointer example -----------------------------" +spectector "func_table.s" $SOLVER --steps 1000000 -w 200 --keep-sym [secretarray] -e [main] -v 2 --skip-uns --parse-uns | grep 'data leak\|program is' +echo "-------------------------------------------- with barrier -----------------------------" +spectector "func_table_barrier.s" $SOLVER --steps 1000000 -w 200 --keep-sym [secretarray] -e [main] -v 2 --skip-uns --parse-uns | grep 'data leak\|program is' +echo "--------------------------------------------- with retpoline ------------------------------------------------" +spectector "retpoline_defense/func_table.s" $SOLVER --steps 1000000 -w 200 --keep-sym [secretarray] -e [main] -v 2 --skip-uns --parse-uns | grep 'data leak\|program is' + +echo "----------------------------------- simple muasm example ----------------------------------------" +spectector "examplev2.muasm" $SOLVER -s --steps 1000000 -w 200 -v 2 -e [main] | grep 'data leak\|program is' +echo "----------------------------------- simple muasm with barrier -----------------------------------" +spectector "examplev2_barrier.muasm" $SOLVER -s --steps 1000000 -w 200 -v 2 -e [main] | grep 'data leak\|program is' diff --git a/journal/v2_tests/func_table.c b/journal/v2_tests/func_table.c new file mode 100644 index 0000000..72dc8ff --- /dev/null +++ b/journal/v2_tests/func_table.c @@ -0,0 +1,32 @@ +#include +#include +#include + +typedef void (*Handler)(void); /* A pointer to a handler function */ + +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 18; +uint8_t secretarray[18] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165,176,187 }; + +volatile uint8_t temp = 0; +void leaky(int idx) { + uint8_t val = secretarray[idx]; + temp &= publicarray[val]; + asm("lfence"); +} + +void func3 (void) { printf( "Winter" ); asm("lfence");} +void func2 (void) { printf( "Fall" ); asm("lfence");} +void func1 (void) { printf( "Summer" ); asm("lfence");} +void func0 (void) { printf( "Spring" ); asm("lfence");} + + +Handler jump_table[4] = {func0, func1, func2, func3}; + + + +int main(int idx) { + asm("lfence"); + jump_table[1](); +} diff --git a/journal/v2_tests/func_table.s b/journal/v2_tests/func_table.s new file mode 100644 index 0000000..f9b978b --- /dev/null +++ b/journal/v2_tests/func_table.s @@ -0,0 +1,240 @@ + .file "func_table.c" + .text + .globl publicarray + .data + .align 16 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 18 + .globl secretarray + .align 16 + .type secretarray, @object + .size secretarray, 18 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245\260\273" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl leaky + .type leaky, @function +leaky: +.LFB6: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + movl -20(%rbp), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movb %al, -1(%rbp) + movzbl -1(%rbp), %eax + cltq + leaq publicarray(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) +#APP +# 16 "func_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size leaky, .-leaky + .section .rodata +.LC0: + .string "Winter" + .text + .globl func3 + .type func3, @function +func3: +.LFB7: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 19 "func_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size func3, .-func3 + .section .rodata +.LC1: + .string "Fall" + .text + .globl func2 + .type func2, @function +func2: +.LFB8: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC1(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 20 "func_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size func2, .-func2 + .section .rodata +.LC2: + .string "Summer" + .text + .globl func1 + .type func1, @function +func1: +.LFB9: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC2(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 21 "func_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size func1, .-func1 + .section .rodata +.LC3: + .string "Spring" + .text + .globl func0 + .type func0, @function +func0: +.LFB10: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC3(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 22 "func_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE10: + .size func0, .-func0 + .globl jump_table + .section .data.rel.local,"aw" + .align 32 + .type jump_table, @object + .size jump_table, 32 +jump_table: + .quad func0 + .quad func1 + .quad func2 + .quad func3 + .text + .globl main + .type main, @function +main: +.LFB11: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) +#APP +# 30 "func_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + movq 8+jump_table(%rip), %rax + call *%rax + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE11: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/journal/v2_tests/func_table_barrier.c b/journal/v2_tests/func_table_barrier.c new file mode 100644 index 0000000..817257a --- /dev/null +++ b/journal/v2_tests/func_table_barrier.c @@ -0,0 +1,32 @@ +#include +#include +#include + +typedef void (*Handler)(void); /* A pointer to a handler function */ + +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 18; +uint8_t secretarray[18] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165,176,187 }; + +volatile uint8_t temp = 0; +void leaky(int idx) { + asm("lfence"); + uint8_t val = secretarray[idx]; + temp &= publicarray[val]; + asm("lfence"); +} + +void func3 (void) { printf( "Winter" ); asm("lfence");} +void func2 (void) { printf( "Fall" ); asm("lfence");} +void func1 (void) { printf( "Summer" ); asm("lfence");} +void func0 (void) { printf( "Spring" ); asm("lfence");} + + +Handler jump_table[4] = {func0, func1, func2, func3}; + + + +int main(int idx) { + jump_table[1](); +} diff --git a/journal/v2_tests/func_table_barrier.s b/journal/v2_tests/func_table_barrier.s new file mode 100644 index 0000000..fbcaf54 --- /dev/null +++ b/journal/v2_tests/func_table_barrier.s @@ -0,0 +1,240 @@ + .file "func_table_barrier.c" + .text + .globl publicarray + .data + .align 16 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 18 + .globl secretarray + .align 16 + .type secretarray, @object + .size secretarray, 18 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245\260\273" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl leaky + .type leaky, @function +leaky: +.LFB6: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) +#APP +# 14 "func_table_barrier.c" 1 + lfence +# 0 "" 2 +#NO_APP + movl -20(%rbp), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movb %al, -1(%rbp) + movzbl -1(%rbp), %eax + cltq + leaq publicarray(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) +#APP +# 17 "func_table_barrier.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size leaky, .-leaky + .section .rodata +.LC0: + .string "Winter" + .text + .globl func3 + .type func3, @function +func3: +.LFB7: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 20 "func_table_barrier.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size func3, .-func3 + .section .rodata +.LC1: + .string "Fall" + .text + .globl func2 + .type func2, @function +func2: +.LFB8: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC1(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 21 "func_table_barrier.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size func2, .-func2 + .section .rodata +.LC2: + .string "Summer" + .text + .globl func1 + .type func1, @function +func1: +.LFB9: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC2(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 22 "func_table_barrier.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size func1, .-func1 + .section .rodata +.LC3: + .string "Spring" + .text + .globl func0 + .type func0, @function +func0: +.LFB10: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC3(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 23 "func_table_barrier.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE10: + .size func0, .-func0 + .globl jump_table + .section .data.rel.local,"aw" + .align 32 + .type jump_table, @object + .size jump_table, 32 +jump_table: + .quad func0 + .quad func1 + .quad func2 + .quad func3 + .text + .globl main + .type main, @function +main: +.LFB11: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq 8+jump_table(%rip), %rax + call *%rax + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE11: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/journal/v2_tests/jump_table.c b/journal/v2_tests/jump_table.c new file mode 100644 index 0000000..4d0f171 --- /dev/null +++ b/journal/v2_tests/jump_table.c @@ -0,0 +1,38 @@ +#include +#include +//int publicarray[16]; +//int secretarray[256 * 512]; + +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +volatile uint8_t temp = 0; +void leaky(int idx) { + uint8_t val = secretarray[idx]; + temp &= publicarray[val]; + asm("lfence"); +} + + +void main() { + asm("lfence"); + asm("movl $5, %eax"); + int season = 1; + static const void* table[] = {&&winter, &&spring, &&summer, &&fall}; + goto *table[season]; + + winter: + printf("Freezing\n"); + return; + spring: + printf("Dirty\n"); + return; + summer: + printf("Dry\n"); + return; + fall: + printf("Windy\n"); + return; +} diff --git a/journal/v2_tests/jump_table.s b/journal/v2_tests/jump_table.s new file mode 100644 index 0000000..b564fa7 --- /dev/null +++ b/journal/v2_tests/jump_table.s @@ -0,0 +1,156 @@ + .file "jump_table.c" + .text + .globl publicarray + .data + .align 16 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl leaky + .type leaky, @function +leaky: +.LFB0: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + movl -20(%rbp), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movb %al, -1(%rbp) + movzbl -1(%rbp), %eax + cltq + leaq publicarray(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) +#APP +# 15 "jump_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size leaky, .-leaky + .section .rodata +.LC0: + .string "Freezing" +.LC1: + .string "Dirty" +.LC2: + .string "Dry" +.LC3: + .string "Windy" + .text + .globl main + .type main, @function +main: +.LFB1: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp +#APP +# 20 "jump_table.c" 1 + lfence +# 0 "" 2 +# 21 "jump_table.c" 1 + movl $5, %eax +# 0 "" 2 +#NO_APP + movl $1, -4(%rbp) + movl -4(%rbp), %eax + cltq + leaq 0(,%rax,8), %rdx + leaq table.2352(%rip), %rax + movq (%rdx,%rax), %rax + nop + jmp *%rax +.L4: + endbr64 + leaq .LC0(%rip), %rdi + call puts@PLT + jmp .L2 +.L6: + endbr64 + leaq .LC1(%rip), %rdi + call puts@PLT + jmp .L2 +.L7: + endbr64 + leaq .LC2(%rip), %rdi + call puts@PLT + jmp .L2 +.L8: + endbr64 + leaq .LC3(%rip), %rdi + call puts@PLT + nop +.L2: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size main, .-main + .section .data.rel.local,"aw" + .align 32 + .type table.2352, @object + .size table.2352, 32 +table.2352: + .quad .L4 + .quad .L6 + .quad .L7 + .quad .L8 + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/journal/v2_tests/jump_table_barrier.c b/journal/v2_tests/jump_table_barrier.c new file mode 100644 index 0000000..b478cbe --- /dev/null +++ b/journal/v2_tests/jump_table_barrier.c @@ -0,0 +1,39 @@ +#include +#include +//int publicarray[16]; +//int secretarray[256 * 512]; + +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +volatile uint8_t temp = 0; +void leaky(int idx) { + asm("lfence"); + uint8_t val = secretarray[idx]; + temp &= publicarray[val]; + asm("lfence"); +} + + +void main() { + asm("lfence"); + asm("movl $5, %eax"); + int season = 1; + static const void* table[] = {&&winter, &&spring, &&summer, &&fall}; + goto *table[season]; + + winter: + printf("Freezing\n"); + return; + spring: + printf("Dirty\n"); + return; + summer: + printf("Dry\n"); + return; + fall: + printf("Windy\n"); + return; +} diff --git a/journal/v2_tests/jump_table_barrier.s b/journal/v2_tests/jump_table_barrier.s new file mode 100644 index 0000000..235844f --- /dev/null +++ b/journal/v2_tests/jump_table_barrier.s @@ -0,0 +1,161 @@ + .file "jump_table_barrier.c" + .text + .globl publicarray + .data + .align 16 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl leaky + .type leaky, @function +leaky: +.LFB0: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) +#APP +# 13 "jump_table_barrier.c" 1 + lfence +# 0 "" 2 +#NO_APP + movl -20(%rbp), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movb %al, -1(%rbp) + movzbl -1(%rbp), %eax + cltq + leaq publicarray(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) +#APP +# 16 "jump_table_barrier.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size leaky, .-leaky + .section .rodata +.LC0: + .string "Freezing" +.LC1: + .string "Dirty" +.LC2: + .string "Dry" +.LC3: + .string "Windy" + .text + .globl main + .type main, @function +main: +.LFB1: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp +#APP +# 21 "jump_table_barrier.c" 1 + lfence +# 0 "" 2 +# 22 "jump_table_barrier.c" 1 + movl $5, %eax +# 0 "" 2 +#NO_APP + movl $1, -4(%rbp) + movl -4(%rbp), %eax + cltq + leaq 0(,%rax,8), %rdx + leaq table.2352(%rip), %rax + movq (%rdx,%rax), %rax + nop + jmp *%rax +.L4: + endbr64 + leaq .LC0(%rip), %rdi + call puts@PLT + jmp .L2 +.L6: + endbr64 + leaq .LC1(%rip), %rdi + call puts@PLT + jmp .L2 +.L7: + endbr64 + leaq .LC2(%rip), %rdi + call puts@PLT + jmp .L2 +.L8: + endbr64 + leaq .LC3(%rip), %rdi + call puts@PLT + nop +.L2: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size main, .-main + .section .data.rel.local,"aw" + .align 32 + .type table.2352, @object + .size table.2352, 32 +table.2352: + .quad .L4 + .quad .L6 + .quad .L7 + .quad .L8 + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/journal/v2_tests/makefile b/journal/v2_tests/makefile new file mode 100644 index 0000000..57abbc0 --- /dev/null +++ b/journal/v2_tests/makefile @@ -0,0 +1,19 @@ + + +RET = retpoline_defense/ +SOURCES = $(wildcard *.c) +ASM = $(patsubst %.c, %.s, $(SOURCES)) +RETPO = $(patsubst %.c, retpo_%.s, $(SOURCES)) +$(info $$var is [${SOURCES2}]) + +all: $(ASM) retpo +$(ASM): $(SOURCES) + $(CC) -O0 -S -c $^ + +retpo : + cd $(RET) && $(MAKE) +clean: + rm -f *.s + rm -f $(RET)*.s +info : + $(info $$var is [${RETPO}]) diff --git a/journal/v2_tests/retpoline_defense/func_table.c b/journal/v2_tests/retpoline_defense/func_table.c new file mode 100644 index 0000000..9c0091a --- /dev/null +++ b/journal/v2_tests/retpoline_defense/func_table.c @@ -0,0 +1,31 @@ +#include +#include +#include + +typedef void (*Handler)(void); /* A pointer to a handler function */ + +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 18; +uint8_t secretarray[18] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165,176,187 }; + +volatile uint8_t temp = 0; +void leaky(int idx) { + uint8_t val = secretarray[idx]; + temp &= publicarray[val]; + asm("lfence"); +} + +void func3 (void) { printf( "Winter" ); asm("lfence");} +void func2 (void) { printf( "Fall" ); asm("lfence");} +void func1 (void) { printf( "Summer" ); asm("lfence");} +void func0 (void) { printf( "Spring" ); asm("lfence");} + + +Handler jump_table[4] = {func0, func1, func2, func3}; + + + +int main(int idx) { + jump_table[1](); +} diff --git a/journal/v2_tests/retpoline_defense/func_table.s b/journal/v2_tests/retpoline_defense/func_table.s new file mode 100644 index 0000000..17288ff --- /dev/null +++ b/journal/v2_tests/retpoline_defense/func_table.s @@ -0,0 +1,231 @@ + .file "func_table.c" + .text + .globl publicarray + .data + .align 16 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 18 + .globl secretarray + .align 16 + .type secretarray, @object + .size secretarray, 18 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245\260\273" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl leaky + .type leaky, @function +leaky: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + movl -20(%rbp), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movb %al, -1(%rbp) + movzbl -1(%rbp), %eax + cltq + leaq publicarray(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) +#APP +# 16 "func_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size leaky, .-leaky + .section .rodata +.LC0: + .string "Winter" + .text + .globl func3 + .type func3, @function +func3: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 19 "func_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size func3, .-func3 + .section .rodata +.LC1: + .string "Fall" + .text + .globl func2 + .type func2, @function +func2: +.LFB8: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC1(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 20 "func_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size func2, .-func2 + .section .rodata +.LC2: + .string "Summer" + .text + .globl func1 + .type func1, @function +func1: +.LFB9: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC2(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 21 "func_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size func1, .-func1 + .section .rodata +.LC3: + .string "Spring" + .text + .globl func0 + .type func0, @function +func0: +.LFB10: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC3(%rip), %rdi + movl $0, %eax + call printf@PLT +#APP +# 22 "func_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE10: + .size func0, .-func0 + .globl jump_table + .section .data.rel.local,"aw" + .align 32 + .type jump_table, @object + .size jump_table, 32 +jump_table: + .quad func0 + .quad func1 + .quad func2 + .quad func3 + .text + .globl main + .type main, @function +main: +.LFB11: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq 8+jump_table(%rip), %rax + call __x86_indirect_thunk_rax + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE11: + .size main, .-main + .section .text.__x86_indirect_thunk_rax,"axG",@progbits,__x86_indirect_thunk_rax,comdat + .globl __x86_indirect_thunk_rax + .hidden __x86_indirect_thunk_rax + .type __x86_indirect_thunk_rax, @function +__x86_indirect_thunk_rax: +.LFB12: + .cfi_startproc + call .LIND1 +.LIND0: + pause + lfence + jmp .LIND0 +.LIND1: + .cfi_def_cfa_offset 16 + mov %rax, (%rsp) + ret + .cfi_endproc +.LFE12: + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v2_tests/retpoline_defense/jump_table.c b/journal/v2_tests/retpoline_defense/jump_table.c new file mode 100644 index 0000000..4d0f171 --- /dev/null +++ b/journal/v2_tests/retpoline_defense/jump_table.c @@ -0,0 +1,38 @@ +#include +#include +//int publicarray[16]; +//int secretarray[256 * 512]; + +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +volatile uint8_t temp = 0; +void leaky(int idx) { + uint8_t val = secretarray[idx]; + temp &= publicarray[val]; + asm("lfence"); +} + + +void main() { + asm("lfence"); + asm("movl $5, %eax"); + int season = 1; + static const void* table[] = {&&winter, &&spring, &&summer, &&fall}; + goto *table[season]; + + winter: + printf("Freezing\n"); + return; + spring: + printf("Dirty\n"); + return; + summer: + printf("Dry\n"); + return; + fall: + printf("Windy\n"); + return; +} diff --git a/journal/v2_tests/retpoline_defense/jump_table.s b/journal/v2_tests/retpoline_defense/jump_table.s new file mode 100644 index 0000000..66d5902 --- /dev/null +++ b/journal/v2_tests/retpoline_defense/jump_table.s @@ -0,0 +1,153 @@ + .file "jump_table.c" + .text + .globl publicarray + .data + .align 16 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl leaky + .type leaky, @function +leaky: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -20(%rbp) + movl -20(%rbp), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movb %al, -1(%rbp) + movzbl -1(%rbp), %eax + cltq + leaq publicarray(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) +#APP +# 15 "jump_table.c" 1 + lfence +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size leaky, .-leaky + .section .rodata +.LC0: + .string "Freezing" +.LC1: + .string "Dirty" +.LC2: + .string "Dry" +.LC3: + .string "Windy" + .text + .globl main + .type main, @function +main: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp +#APP +# 20 "jump_table.c" 1 + lfence +# 0 "" 2 +# 21 "jump_table.c" 1 + movl $5, %eax +# 0 "" 2 +#NO_APP + movl $1, -4(%rbp) + movl -4(%rbp), %eax + cltq + leaq 0(,%rax,8), %rdx + leaq table.2352(%rip), %rax + movq (%rdx,%rax), %rax + nop + jmp __x86_indirect_thunk_rax +.L4: + leaq .LC0(%rip), %rdi + call puts@PLT + jmp .L2 +.L6: + leaq .LC1(%rip), %rdi + call puts@PLT + jmp .L2 +.L7: + leaq .LC2(%rip), %rdi + call puts@PLT + jmp .L2 +.L8: + leaq .LC3(%rip), %rdi + call puts@PLT + nop +.L2: + leave + .cfi_restore 6 + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size main, .-main + .section .data.rel.local,"aw" + .align 32 + .type table.2352, @object + .size table.2352, 32 +table.2352: + .quad .L4 + .quad .L6 + .quad .L7 + .quad .L8 + .section .text.__x86_indirect_thunk_rax,"axG",@progbits,__x86_indirect_thunk_rax,comdat + .globl __x86_indirect_thunk_rax + .hidden __x86_indirect_thunk_rax + .type __x86_indirect_thunk_rax, @function +__x86_indirect_thunk_rax: +.LFB2: + .cfi_startproc + call .LIND1 +.LIND0: + pause + lfence + jmp .LIND0 +.LIND1: + .cfi_def_cfa_offset 16 + mov %rax, (%rsp) + ret + .cfi_endproc +.LFE2: + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v2_tests/retpoline_defense/makefile b/journal/v2_tests/retpoline_defense/makefile new file mode 100644 index 0000000..27a2ab4 --- /dev/null +++ b/journal/v2_tests/retpoline_defense/makefile @@ -0,0 +1,14 @@ + + +SOURCES = $(wildcard *.c) +ASM = $(patsubst %.c, %.s, $(SOURCES)) + +all: $(ASM) + +$(ASM): $(SOURCES) + $(CC) -O0 -S -fcf-protection=none -mindirect-branch=thunk $^ + +clean: + rm -rf *.s +info : + $(info $$var is [${RETPO}]) diff --git a/journal/v4_tests/README.md b/journal/v4_tests/README.md new file mode 100644 index 0000000..4ac7335 --- /dev/null +++ b/journal/v4_tests/README.md @@ -0,0 +1,6 @@ +Each of the folders litmus_stl and litmus_stl_barrier contain an executable script that executes +the V4 test cases. + +If the cases were manually recompiled, change case2.s with case2_working_offset.s in litmus_stl/ and +case2_working_barrier.s in litmus_stl_barrier/. +This has to be done due to to incompability reasons of 32 bit mode. \ No newline at end of file diff --git a/journal/v4_tests/case2_working_barrier.s b/journal/v4_tests/case2_working_barrier.s new file mode 100644 index 0000000..690233c --- /dev/null +++ b/journal/v4_tests/case2_working_barrier.s @@ -0,0 +1,78 @@ + .file "case2.c" + .text + .globl array_size + .data + .align 4 + .type array_size, @object + .size array_size, 4 +array_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_2 + .type case_2, @function +case_2: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + movl array_size, %eax + decl %eax + andl %eax, 16(%ebp) +#APP +# 17 "case2.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl 16(%ebp), %eax + addl $secretarray, %eax + movb (%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_2, .-case_2 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/case2_working_offsets.s b/journal/v4_tests/case2_working_offsets.s new file mode 100644 index 0000000..2854168 --- /dev/null +++ b/journal/v4_tests/case2_working_offsets.s @@ -0,0 +1,73 @@ + .file "case2.c" + .text + .globl array_size + .data + .align 4 + .type array_size, @object + .size array_size, 4 +array_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_2 + .type case_2, @function +case_2: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + movl array_size, %eax + decl %eax + andl %eax, 16(%ebp) + movl 16(%ebp), %eax + addl $publicarray, %eax + movb (%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_2, .-case_2 + .ident "GCC: (GNU) 10.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case1.c b/journal/v4_tests/litmus_stl/case1.c new file mode 100644 index 0000000..3041486 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case1.c @@ -0,0 +1,39 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1]; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +// In all of these examples, the arguments to the functions are attacker-controlled + +/* Examples marked as INSECURE violate Speculative Constant-Time (SCT) + when compiled with gcc-10.2.0 -O0 -m32 -march=i386 + -fno-stack-protector -static -no-pie -fno-pic */ + + +/* Based on original POC for Spectre-v4 */ +/* https://github.com/IAIK/transientfail/blob/master/pocs/spectre/STL/main.c */ +void case_1(uint32_t idx) { /* INSECURE */ + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + + uint8_t* data = secretarray; + uint8_t** data_slowptr = &data; + uint8_t*** data_slowslowptr = &data_slowptr; + + /* Overwrite secret value */ + (*(*data_slowslowptr))[ridx] = 0; // Bypassed store + + /* Access overwritten secret */ + temp &= publicarray2[secretarray[ridx] * 512]; +} + diff --git a/journal/v4_tests/litmus_stl/case1.s b/journal/v4_tests/litmus_stl/case1.s new file mode 100644 index 0000000..1906d8b --- /dev/null +++ b/journal/v4_tests/litmus_stl/case1.s @@ -0,0 +1,85 @@ + .file "case1.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .bss + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .zero 512 + .globl secretarray_size + .data + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_1 + .type case_1, @function +case_1: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl $secretarray, -8(%ebp) + leal -8(%ebp), %eax + movl %eax, -12(%ebp) + leal -12(%ebp), %eax + movl %eax, -4(%ebp) + movl -4(%ebp), %eax + movl (%eax), %eax + movl (%eax), %eax + addl %edx, %eax + movb $0, (%eax) + movl %edx, %eax + movb secretarray(%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_1, .-case_1 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case10.c b/journal/v4_tests/litmus_stl/case10.c new file mode 100644 index 0000000..5344ce8 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case10.c @@ -0,0 +1,29 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +uint32_t case_10_mask(uint32_t idx); // implicit declaration +void case_10(uint32_t idx) { // INSECURE + uint32_t fidx = case_10_mask(idx); + + /* Access overwritten secret */ + temp &= publicarray2[publicarray[fidx] * 512]; +} + +/* Same as case 3 (secure) but masking is made by a function call */ +uint32_t case_10_mask(uint32_t idx) { + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + return ridx; +} diff --git a/journal/v4_tests/litmus_stl/case10.s b/journal/v4_tests/litmus_stl/case10.s new file mode 100644 index 0000000..46d2bdb --- /dev/null +++ b/journal/v4_tests/litmus_stl/case10.s @@ -0,0 +1,98 @@ + .file "case10.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_10 + .type case_10, @function +case_10: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $24, %esp + subl $12, %esp + pushl 8(%ebp) + call case_10_mask + addl $16, %esp + movl %eax, -12(%ebp) + movl -12(%ebp), %eax + addl $publicarray, %eax + movb (%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_10, .-case_10 + .globl case_10_mask + .type case_10_mask, @function +case_10_mask: +.LFB1: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl %edx, %eax + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE1: + .size case_10_mask, .-case_10_mask + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case11.c b/journal/v4_tests/litmus_stl/case11.c new file mode 100644 index 0000000..f60d367 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case11.c @@ -0,0 +1,30 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + + +uint8_t case_11_load_value(uint32_t idx); // for implicit +void case_11(uint32_t idx) { // INSECURE + uint8_t to_leak = case_11_load_value(idx); + + /* Access overwritten secret */ + temp &= publicarray2[to_leak * 512]; +} + +uint8_t case_11_load_value(uint32_t idx) { + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + uint8_t to_leak = publicarray[ridx]; + return to_leak; +} diff --git a/journal/v4_tests/litmus_stl/case11.s b/journal/v4_tests/litmus_stl/case11.s new file mode 100644 index 0000000..d5da437 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case11.s @@ -0,0 +1,99 @@ + .file "case11.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_11 + .type case_11, @function +case_11: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $24, %esp + subl $12, %esp + pushl 8(%ebp) + call case_11_load_value + addl $16, %esp + movb %al, -9(%ebp) + movzbl -9(%ebp), %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_11, .-case_11 + .globl case_11_load_value + .type case_11_load_value, @function +case_11_load_value: +.LFB1: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl %edx, %eax + movb publicarray(%eax), %al + movb %al, -1(%ebp) + movb -1(%ebp), %al + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE1: + .size case_11_load_value, .-case_11_load_value + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case12.c b/journal/v4_tests/litmus_stl/case12.c new file mode 100644 index 0000000..3b29f43 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case12.c @@ -0,0 +1,29 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +uint32_t case_12_mask(uint32_t idx); + +void case_12(uint32_t idx) { // SECURE + register uint32_t ridx asm ("edx"); + ridx = case_12_mask(idx); + + /* Access overwritten secret */ + temp &= publicarray2[publicarray[ridx] * 512]; +} +uint32_t case_12_mask(uint32_t idx) { + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + return ridx; +} diff --git a/journal/v4_tests/litmus_stl/case12.s b/journal/v4_tests/litmus_stl/case12.s new file mode 100644 index 0000000..b556045 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case12.s @@ -0,0 +1,97 @@ + .file "case12.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_12 + .type case_12, @function +case_12: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $8, %esp + subl $12, %esp + pushl 8(%ebp) + call case_12_mask + addl $16, %esp + movl %eax, %edx + movl %edx, %eax + movb publicarray(%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_12, .-case_12 + .globl case_12_mask + .type case_12_mask, @function +case_12_mask: +.LFB1: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl %edx, %eax + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE1: + .size case_12_mask, .-case_12_mask + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case13.c b/journal/v4_tests/litmus_stl/case13.c new file mode 100644 index 0000000..caa1650 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case13.c @@ -0,0 +1,33 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +/* Same as case 10 but result of function is in register */ + +uint8_t case_13_load_value(uint32_t idx); + +void case_13(uint32_t idx) { // SECURE + register uint8_t to_leak asm ("edx"); + to_leak = case_13_load_value(idx); + + /* Access overwritten secret */ + temp &= publicarray2[to_leak * 512]; +} + +uint8_t case_13_load_value(uint32_t idx) { + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + uint8_t to_leak = publicarray[ridx]; + return to_leak; +} diff --git a/journal/v4_tests/litmus_stl/case13.s b/journal/v4_tests/litmus_stl/case13.s new file mode 100644 index 0000000..290964b --- /dev/null +++ b/journal/v4_tests/litmus_stl/case13.s @@ -0,0 +1,100 @@ + .file "case13.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_13 + .type case_13, @function +case_13: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $8, %esp + subl $12, %esp + pushl 8(%ebp) + call case_13_load_value + addl $16, %esp + movb %al, %dl + movb %dl, %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_13, .-case_13 + .globl case_13_load_value + .type case_13_load_value, @function +case_13_load_value: +.LFB1: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl %edx, %eax + movb publicarray(%eax), %al + movb %al, -1(%ebp) + movb -1(%ebp), %al + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE1: + .size case_13_load_value, .-case_13_load_value + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case2.c b/journal/v4_tests/litmus_stl/case2.c new file mode 100644 index 0000000..3af64ed --- /dev/null +++ b/journal/v4_tests/litmus_stl/case2.c @@ -0,0 +1,20 @@ +#include +#include + +uint32_t array_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + +void case_2(uint32_t idx) { + idx = idx & (array_size - 1); + + /* Access overwritten secret */ + temp &= publicarray2[secretarray[idx] * 512]; +} diff --git a/journal/v4_tests/litmus_stl/case2_working_offsets.s b/journal/v4_tests/litmus_stl/case2_working_offsets.s new file mode 100644 index 0000000..2854168 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case2_working_offsets.s @@ -0,0 +1,73 @@ + .file "case2.c" + .text + .globl array_size + .data + .align 4 + .type array_size, @object + .size array_size, 4 +array_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_2 + .type case_2, @function +case_2: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + movl array_size, %eax + decl %eax + andl %eax, 16(%ebp) + movl 16(%ebp), %eax + addl $publicarray, %eax + movb (%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_2, .-case_2 + .ident "GCC: (GNU) 10.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case3.c b/journal/v4_tests/litmus_stl/case3.c new file mode 100644 index 0000000..c821a98 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case3.c @@ -0,0 +1,22 @@ +#include +#include + +uint32_t array_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[16] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +void case_3(uint32_t idx) { // SECURE + register uint32_t ridx asm ("edx"); + ridx = idx & (array_size - 1); + + /* Access overwritten secret */ + temp &= publicarray2[publicarray[ridx] * 512]; +} diff --git a/journal/v4_tests/litmus_stl/case3.s b/journal/v4_tests/litmus_stl/case3.s new file mode 100644 index 0000000..5578e22 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case3.s @@ -0,0 +1,73 @@ + .file "case3.c" + .text + .globl array_size + .data + .align 4 + .type array_size, @object + .size array_size, 4 +array_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 4 + .type publicarray2, @object + .size publicarray2, 16 +publicarray2: + .string "\024" + .zero 14 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_3 + .type case_3, @function +case_3: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + movl array_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl %edx, %eax + movb publicarray(%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_3, .-case_3 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case4.c b/journal/v4_tests/litmus_stl/case4.c new file mode 100644 index 0000000..6696b75 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case4.c @@ -0,0 +1,24 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 } ; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + +void case_4(uint32_t idx) { // INSECURE + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + + /* Overwrite secret value */ + secretarray[ridx] = 0; // Bypassed store + + /* Access overwritten secret */ + temp &= publicarray2[secretarray[ridx] * 512]; +} diff --git a/journal/v4_tests/litmus_stl/case4.s b/journal/v4_tests/litmus_stl/case4.s new file mode 100644 index 0000000..2cd9955 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case4.s @@ -0,0 +1,75 @@ + .file "case4.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_4 + .type case_4, @function +case_4: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl %edx, %eax + movb $0, secretarray(%eax) + movl %edx, %eax + movb secretarray(%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_4, .-case_4 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case5_reg.c b/journal/v4_tests/litmus_stl/case5_reg.c new file mode 100644 index 0000000..8f5c114 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case5_reg.c @@ -0,0 +1,28 @@ + +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +void case_5(uint32_t idx) { // INSECURE + uint8_t *case5_ptr = secretarray; + asm("mfence"); + register uint32_t ridx asm ("edx"); + register uint8_t toleak asm ("ecx"); + ridx = idx & (secretarray_size - 1); + + case5_ptr = publicarray; // Bypassed store + + toleak = case5_ptr[ridx]; + temp &= publicarray2[toleak * 512]; +} diff --git a/journal/v4_tests/litmus_stl/case5_reg.s b/journal/v4_tests/litmus_stl/case5_reg.s new file mode 100644 index 0000000..2724e8c --- /dev/null +++ b/journal/v4_tests/litmus_stl/case5_reg.s @@ -0,0 +1,85 @@ + .file "case5_reg.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_5 + .type case_5, @function +case_5: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl $secretarray, -4(%ebp) +#APP +# 19 "case5_reg.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl $publicarray, -4(%ebp) + movl %edx, %eax + movl -4(%ebp), %edx + addl %edx, %eax + movb (%eax), %al + movb %al, %cl + movb %cl, %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_5, .-case_5 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case6.s b/journal/v4_tests/litmus_stl/case6.s new file mode 100644 index 0000000..5367073 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case6.s @@ -0,0 +1,93 @@ + .file "case6.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .globl case6_idx + .align 4 + .type case6_idx, @object + .size case6_idx, 4 +case6_idx: + .zero 4 + .globl case6_array + .data + .align 4 + .type case6_array, @object + .size case6_array, 8 +case6_array: + .long secretarray + .long publicarray + .text + .globl case_6 + .type case_6, @function +case_6: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl $1, case6_idx + movl case6_idx, %eax + movl case6_array(,%eax,4), %ecx + movl %edx, %eax + addl %ecx, %eax + movb (%eax), %al + movb %al, -1(%ebp) + movzbl -1(%ebp), %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_6, .-case_6 + .ident "GCC: (GNU) 10.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case6_reg.c b/journal/v4_tests/litmus_stl/case6_reg.c new file mode 100644 index 0000000..5bb496c --- /dev/null +++ b/journal/v4_tests/litmus_stl/case6_reg.c @@ -0,0 +1,29 @@ + +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +uint32_t case6_idx = 0; +void case_6(uint32_t idx) { // INSECURE + uint8_t *case6_array[2] = { secretarray, publicarray }; + register uint32_t ridx asm ("edx"); + asm("mfence"); + register uint8_t toleak asm ("ecx"); + ridx = idx & (secretarray_size - 1); + + case6_idx = 1; // Bypassed store + + toleak = (case6_array[case6_idx])[ridx]; + temp &= publicarray2[toleak * 16]; +} diff --git a/journal/v4_tests/litmus_stl/case6_reg.s b/journal/v4_tests/litmus_stl/case6_reg.s new file mode 100644 index 0000000..9338f62 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case6_reg.s @@ -0,0 +1,93 @@ + .file "case6_reg.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .globl case6_idx + .align 4 + .type case6_idx, @object + .size case6_idx, 4 +case6_idx: + .zero 4 + .text + .globl case_6 + .type case_6, @function +case_6: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl $secretarray, -8(%ebp) + movl $publicarray, -4(%ebp) +#APP +# 21 "case6_reg.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl $1, case6_idx + movl case6_idx, %eax + movl -8(%ebp,%eax,4), %ecx + movl %edx, %eax + addl %ecx, %eax + movb (%eax), %al + movb %al, %cl + movb %cl, %al + movzbl %al, %eax + sall $4, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_6, .-case_6 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case7.c b/journal/v4_tests/litmus_stl/case7.c new file mode 100644 index 0000000..e1b6dcc --- /dev/null +++ b/journal/v4_tests/litmus_stl/case7.c @@ -0,0 +1,24 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + +uint32_t case7_mask = UINT32_MAX; +void case_7(uint32_t idx) { // INSECURE + case7_mask = (secretarray_size - 1); // Bypassed store + + uint8_t toleak = publicarray[idx & case7_mask]; + temp &= publicarray2[toleak * 512]; +} + + + diff --git a/journal/v4_tests/litmus_stl/case7.s b/journal/v4_tests/litmus_stl/case7.s new file mode 100644 index 0000000..8d2bbd4 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case7.s @@ -0,0 +1,82 @@ + .file "case7.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .globl case7_mask + .data + .align 4 + .type case7_mask, @object + .size case7_mask, 4 +case7_mask: + .long -1 + .text + .globl case_7 + .type case_7, @function +case_7: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl secretarray_size, %eax + decl %eax + movl %eax, case7_mask + movl case7_mask, %eax + andl 8(%ebp), %eax + movb publicarray(%eax), %al + movb %al, -1(%ebp) + movzbl -1(%ebp), %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_7, .-case_7 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case8.c b/journal/v4_tests/litmus_stl/case8.c new file mode 100644 index 0000000..a8de4c7 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case8.c @@ -0,0 +1,23 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +uint32_t case8_mult = 200; + +void case_8(uint32_t idx) { // INSECURE + case8_mult = 0; // Bypassed store + + uint8_t toleak = publicarray[idx * case8_mult]; + temp &= publicarray2[toleak * 512]; +} diff --git a/journal/v4_tests/litmus_stl/case8.s b/journal/v4_tests/litmus_stl/case8.s new file mode 100644 index 0000000..d3c01df --- /dev/null +++ b/journal/v4_tests/litmus_stl/case8.s @@ -0,0 +1,80 @@ + .file "case8.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .globl case8_mult + .data + .align 4 + .type case8_mult, @object + .size case8_mult, 4 +case8_mult: + .long 200 + .text + .globl case_8 + .type case_8, @function +case_8: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl $0, case8_mult + movl case8_mult, %eax + imull 8(%ebp), %eax + movb publicarray(%eax), %al + movb %al, -1(%ebp) + movzbl -1(%ebp), %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_8, .-case_8 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/case9/case9.c b/journal/v4_tests/litmus_stl/case9/case9.c new file mode 100644 index 0000000..2afc015 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case9/case9.c @@ -0,0 +1,32 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + + +/* This store should be secure assuming no speculation on conditionals + because when the programs fetches the last line, the store that + overwrites the secret should be retired. */ +void case_9(uint32_t idx) { // SECURE + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + + /* Overwrite secret value */ + secretarray[ridx] = 0; // Bypassed store + + register uint32_t i asm ("ecx"); + for (i = 0; i < 200; ++i) temp &= i; + + /* Access overwritten secret */ + temp &= publicarray2[secretarray[ridx] * 512]; +} diff --git a/journal/v4_tests/litmus_stl/case9/case9.s b/journal/v4_tests/litmus_stl/case9/case9.s new file mode 100644 index 0000000..8d4f332 --- /dev/null +++ b/journal/v4_tests/litmus_stl/case9/case9.s @@ -0,0 +1,94 @@ + .file "case9.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_9 + .type case_9, @function +case_9: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + .cfi_offset 3, -12 + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl %edx, %eax + movb $0, secretarray(%eax) + movl $0, %ecx + jmp .L2 +.L3: + movl %ecx, %eax + movb %al, %bl + movb temp, %al + andl %ebx, %eax + movb %al, temp + movl %ecx, %eax + incl %eax + movl %eax, %ecx +.L2: + movl %ecx, %eax + cmpl $199, %eax + jbe .L3 + movl %edx, %eax + movb secretarray(%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_9, .-case_9 + .ident "GCC: (GNU) 10.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl/execute_spectector.sh b/journal/v4_tests/litmus_stl/execute_spectector.sh new file mode 100755 index 0000000..f4b3b46 --- /dev/null +++ b/journal/v4_tests/litmus_stl/execute_spectector.sh @@ -0,0 +1,14 @@ +#!/bin/bash +rm -r stats/* +for file in *.s +do + echo "-------Executing $file ------------" + spectector "$file" $SOLVER -s -a noninter --steps 1000000 --version 4 -w 200 --stats "stats/stats_$file.txt" --keep-sym [secretarray] | grep 'data leak\|program is' +done + +echo "-------Executing case9.s ------------" + spectector "case9/case9.s" $SOLVER -s -a noninter --steps 1000000 --version 4 -w 10 --stats "stats/stats_case9.s.txt" --keep-sym [secretarray] | grep 'data leak\|program is' +for file in stats/* # Stats writes an extra comma that we delete + do + truncate -s -1 $file + done diff --git a/journal/v4_tests/litmus_stl/makefile b/journal/v4_tests/litmus_stl/makefile new file mode 100644 index 0000000..2dfcad8 --- /dev/null +++ b/journal/v4_tests/litmus_stl/makefile @@ -0,0 +1,9 @@ + +SOURCES = $(wildcard *.c) +ASM = $(patsubst %.c, %.s, $(SOURCES)) +$(info $$var is [${SOURCES}]) +$(ASM): $(SOURCES) + #$(CC) -S -c $^ + $(CC) -O0 -m32 -march=i386 -fno-stack-protector -static -no-pie -fno-pic -S -c $^ +clean: + rm -rf *.s diff --git a/journal/v4_tests/litmus_stl_barrier/case1.c b/journal/v4_tests/litmus_stl_barrier/case1.c new file mode 100644 index 0000000..492e833 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case1.c @@ -0,0 +1,38 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1]; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +// In all of these examples, the arguments to the functions are attacker-controlled + +/* Examples marked as INSECURE violate Speculative Constant-Time (SCT) + when compiled with gcc-10.2.0 -O0 -m32 -march=i386 + -fno-stack-protector -static -no-pie -fno-pic */ + + +/* Based on original POC for Spectre-v4 */ +/* https://github.com/IAIK/transientfail/blob/master/pocs/spectre/STL/main.c */ +void case_1(uint32_t idx) { /* INSECURE */ + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + + uint8_t* data = secretarray; + uint8_t** data_slowptr = &data; + uint8_t*** data_slowslowptr = &data_slowptr; + asm ("mfence"); // added similar to cats vs spectre + /* Overwrite secret value */ + (*(*data_slowslowptr))[ridx] = 0; // Bypassed store + asm ("mfence"); + /* Access overwritten secret */ + temp &= publicarray2[secretarray[ridx] * 512]; +} \ No newline at end of file diff --git a/journal/v4_tests/litmus_stl_barrier/case1.s b/journal/v4_tests/litmus_stl_barrier/case1.s new file mode 100644 index 0000000..b64183c --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case1.s @@ -0,0 +1,95 @@ + .file "case1.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .bss + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .zero 512 + .globl secretarray_size + .data + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_1 + .type case_1, @function +case_1: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl $secretarray, -8(%ebp) + leal -8(%ebp), %eax + movl %eax, -12(%ebp) + leal -12(%ebp), %eax + movl %eax, -4(%ebp) +#APP +# 32 "case1.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl -4(%ebp), %eax + movl (%eax), %eax + movl (%eax), %eax + addl %edx, %eax + movb $0, (%eax) +#APP +# 35 "case1.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl %edx, %eax + movb secretarray(%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_1, .-case_1 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl_barrier/case10.c b/journal/v4_tests/litmus_stl_barrier/case10.c new file mode 100644 index 0000000..c52f886 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case10.c @@ -0,0 +1,29 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +uint32_t case_10_mask(uint32_t idx); // implicit declaration +void case_10(uint32_t idx) { // INSECURE + uint32_t fidx = case_10_mask(idx); + asm ("mfence"); + /* Access overwritten secret */ + temp &= publicarray2[publicarray[fidx] * 512]; +} + +/* Same as case 3 (secure) but masking is made by a function call */ +uint32_t case_10_mask(uint32_t idx) { + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + return ridx; +} diff --git a/journal/v4_tests/litmus_stl_barrier/case10.s b/journal/v4_tests/litmus_stl_barrier/case10.s new file mode 100644 index 0000000..850b604 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case10.s @@ -0,0 +1,103 @@ + .file "case10.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_10 + .type case_10, @function +case_10: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $24, %esp + subl $12, %esp + pushl 8(%ebp) + call case_10_mask + addl $16, %esp + movl %eax, -12(%ebp) +#APP +# 19 "case10.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl -12(%ebp), %eax + addl $publicarray, %eax + movb (%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_10, .-case_10 + .globl case_10_mask + .type case_10_mask, @function +case_10_mask: +.LFB1: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl %edx, %eax + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE1: + .size case_10_mask, .-case_10_mask + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl_barrier/case11.c b/journal/v4_tests/litmus_stl_barrier/case11.c new file mode 100644 index 0000000..9f4b510 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case11.c @@ -0,0 +1,30 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + + +uint8_t case_11_load_value(uint32_t idx); // for implicit +void case_11(uint32_t idx) { // INSECURE + uint8_t to_leak = case_11_load_value(idx); + asm ("mfence"); + /* Access overwritten secret */ + temp &= publicarray2[to_leak * 512]; +} + +uint8_t case_11_load_value(uint32_t idx) { + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + uint8_t to_leak = publicarray[ridx]; + return to_leak; +} diff --git a/journal/v4_tests/litmus_stl_barrier/case11.s b/journal/v4_tests/litmus_stl_barrier/case11.s new file mode 100644 index 0000000..50d36c1 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case11.s @@ -0,0 +1,104 @@ + .file "case11.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_11 + .type case_11, @function +case_11: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $24, %esp + subl $12, %esp + pushl 8(%ebp) + call case_11_load_value + addl $16, %esp + movb %al, -9(%ebp) +#APP +# 20 "case11.c" 1 + mfence +# 0 "" 2 +#NO_APP + movzbl -9(%ebp), %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_11, .-case_11 + .globl case_11_load_value + .type case_11_load_value, @function +case_11_load_value: +.LFB1: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl %edx, %eax + movb publicarray(%eax), %al + movb %al, -1(%ebp) + movb -1(%ebp), %al + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE1: + .size case_11_load_value, .-case_11_load_value + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl_barrier/case13.c b/journal/v4_tests/litmus_stl_barrier/case13.c new file mode 100644 index 0000000..07c8e89 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case13.c @@ -0,0 +1,33 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +/* Same as case 10 but result of function is in register */ + +uint8_t case_13_load_value(uint32_t idx); + +void case_13(uint32_t idx) { // INSECURE (For binsec secure because of different threat model) + register uint8_t to_leak asm ("edx"); + to_leak = case_13_load_value(idx); + asm ("mfence"); + /* Access overwritten secret */ + temp &= publicarray2[to_leak * 512]; +} + +uint8_t case_13_load_value(uint32_t idx) { + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + uint8_t to_leak = publicarray[ridx]; + return to_leak; +} diff --git a/journal/v4_tests/litmus_stl_barrier/case13.s b/journal/v4_tests/litmus_stl_barrier/case13.s new file mode 100644 index 0000000..a8d875c --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case13.s @@ -0,0 +1,105 @@ + .file "case13.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_13 + .type case_13, @function +case_13: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $8, %esp + subl $12, %esp + pushl 8(%ebp) + call case_13_load_value + addl $16, %esp + movb %al, %dl +#APP +# 23 "case13.c" 1 + mfence +# 0 "" 2 +#NO_APP + movb %dl, %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_13, .-case_13 + .globl case_13_load_value + .type case_13_load_value, @function +case_13_load_value: +.LFB1: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl %edx, %eax + movb publicarray(%eax), %al + movb %al, -1(%ebp) + movb -1(%ebp), %al + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE1: + .size case_13_load_value, .-case_13_load_value + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl_barrier/case2_working_barrier.s b/journal/v4_tests/litmus_stl_barrier/case2_working_barrier.s new file mode 100644 index 0000000..690233c --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case2_working_barrier.s @@ -0,0 +1,78 @@ + .file "case2.c" + .text + .globl array_size + .data + .align 4 + .type array_size, @object + .size array_size, 4 +array_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_2 + .type case_2, @function +case_2: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + movl array_size, %eax + decl %eax + andl %eax, 16(%ebp) +#APP +# 17 "case2.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl 16(%ebp), %eax + addl $secretarray, %eax + movb (%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_2, .-case_2 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl_barrier/case4.c b/journal/v4_tests/litmus_stl_barrier/case4.c new file mode 100644 index 0000000..89429ba --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case4.c @@ -0,0 +1,24 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 } ; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + +void case_4(uint32_t idx) { // INSECURE + register uint32_t ridx asm ("edx"); + ridx = idx & (secretarray_size - 1); + + /* Overwrite secret value */ + secretarray[ridx] = 0; // Bypassed store + asm ("mfence"); + /* Access overwritten secret */ + temp &= publicarray2[secretarray[ridx] * 512]; +} diff --git a/journal/v4_tests/litmus_stl_barrier/case4.s b/journal/v4_tests/litmus_stl_barrier/case4.s new file mode 100644 index 0000000..4f29dfb --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case4.s @@ -0,0 +1,80 @@ + .file "case4.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_4 + .type case_4, @function +case_4: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl %edx, %eax + movb $0, secretarray(%eax) +#APP +# 21 "case4.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl %edx, %eax + movb secretarray(%eax), %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_4, .-case_4 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl_barrier/case5_mod.c b/journal/v4_tests/litmus_stl_barrier/case5_mod.c new file mode 100644 index 0000000..950f8cd --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case5_mod.c @@ -0,0 +1,28 @@ + +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +void case_5(uint32_t idx) { // INSECURE + uint8_t *case5_ptr = secretarray; + asm("mfence"); + register uint32_t ridx asm ("edx"); + register uint8_t toleak asm ("ecx"); + ridx = idx & (secretarray_size - 1); + + case5_ptr = publicarray; // Bypassed store + asm("mfence"); + toleak = case5_ptr[ridx]; + temp &= publicarray2[toleak * 512]; +} diff --git a/journal/v4_tests/litmus_stl_barrier/case5_mod.s b/journal/v4_tests/litmus_stl_barrier/case5_mod.s new file mode 100644 index 0000000..6223df0 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case5_mod.s @@ -0,0 +1,90 @@ + .file "case5_mod.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl case_5 + .type case_5, @function +case_5: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl $secretarray, -4(%ebp) +#APP +# 19 "case5_mod.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl $publicarray, -4(%ebp) +#APP +# 25 "case5_mod.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl %edx, %eax + movl -4(%ebp), %edx + addl %edx, %eax + movb (%eax), %al + movb %al, %cl + movb %cl, %al + movzbl %al, %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_5, .-case_5 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl_barrier/case6_mod.c b/journal/v4_tests/litmus_stl_barrier/case6_mod.c new file mode 100644 index 0000000..4ef2a89 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case6_mod.c @@ -0,0 +1,29 @@ + +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +uint32_t case6_idx = 0; +void case_6(uint32_t idx) { // INSECURE + uint8_t *case6_array[2] = { secretarray, publicarray }; + register uint32_t ridx asm ("edx"); + asm("mfence"); + register uint8_t toleak asm ("ecx"); + ridx = idx & (secretarray_size - 1); + + case6_idx = 1; // Bypassed store + asm("mfence"); + toleak = (case6_array[case6_idx])[ridx]; + temp &= publicarray2[toleak * 16]; +} diff --git a/journal/v4_tests/litmus_stl_barrier/case6_mod.s b/journal/v4_tests/litmus_stl_barrier/case6_mod.s new file mode 100644 index 0000000..f1efd01 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case6_mod.s @@ -0,0 +1,98 @@ + .file "case6_mod.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .globl case6_idx + .align 4 + .type case6_idx, @object + .size case6_idx, 4 +case6_idx: + .zero 4 + .text + .globl case_6 + .type case_6, @function +case_6: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl $secretarray, -8(%ebp) + movl $publicarray, -4(%ebp) +#APP +# 21 "case6_mod.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl secretarray_size, %eax + decl %eax + andl 8(%ebp), %eax + movl %eax, %edx + movl $1, case6_idx +#APP +# 26 "case6_mod.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl case6_idx, %eax + movl -8(%ebp,%eax,4), %ecx + movl %edx, %eax + addl %ecx, %eax + movb (%eax), %al + movb %al, %cl + movb %cl, %al + movzbl %al, %eax + sall $4, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_6, .-case_6 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl_barrier/case7.c b/journal/v4_tests/litmus_stl_barrier/case7.c new file mode 100644 index 0000000..e2b6613 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case7.c @@ -0,0 +1,24 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + +uint32_t case7_mask = UINT32_MAX; +void case_7(uint32_t idx) { // INSECURE + case7_mask = (secretarray_size - 1); // Bypassed store + uint8_t toleak = publicarray[idx & case7_mask]; + asm ("mfence"); + temp &= publicarray2[toleak * 512]; +} + + + diff --git a/journal/v4_tests/litmus_stl_barrier/case7.s b/journal/v4_tests/litmus_stl_barrier/case7.s new file mode 100644 index 0000000..141b19d --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case7.s @@ -0,0 +1,87 @@ + .file "case7.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .globl case7_mask + .data + .align 4 + .type case7_mask, @object + .size case7_mask, 4 +case7_mask: + .long -1 + .text + .globl case_7 + .type case_7, @function +case_7: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl secretarray_size, %eax + decl %eax + movl %eax, case7_mask + movl case7_mask, %eax + andl 8(%ebp), %eax + movb publicarray(%eax), %al + movb %al, -1(%ebp) +#APP +# 19 "case7.c" 1 + mfence +# 0 "" 2 +#NO_APP + movzbl -1(%ebp), %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_7, .-case_7 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl_barrier/case8.c b/journal/v4_tests/litmus_stl_barrier/case8.c new file mode 100644 index 0000000..68f807a --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case8.c @@ -0,0 +1,23 @@ +#include +#include + +uint32_t publicarray_size = 16; +uint8_t publicarray[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; +uint8_t publicarray2[512 * 1] = { 20 }; + +// The attacker's goal in all of these examples is to learn any of the secret data in secretarray +uint32_t secretarray_size = 16; +uint8_t secretarray[16] = { 10,21,32,43,54,65,76,87,98,109,110,121,132,143,154,165 }; + +// this is mostly used to prevent the compiler from optimizing out certain operations +volatile uint8_t temp = 0; + + +uint32_t case8_mult = 200; + +void case_8(uint32_t idx) { // INSECURE + case8_mult = 0; // Bypassed store + uint8_t toleak = publicarray[idx * case8_mult]; + asm ("mfence"); + temp &= publicarray2[toleak * 512]; +} diff --git a/journal/v4_tests/litmus_stl_barrier/case8.s b/journal/v4_tests/litmus_stl_barrier/case8.s new file mode 100644 index 0000000..28c5552 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/case8.s @@ -0,0 +1,85 @@ + .file "case8.c" + .text + .globl publicarray_size + .data + .align 4 + .type publicarray_size, @object + .size publicarray_size, 4 +publicarray_size: + .long 16 + .globl publicarray + .align 4 + .type publicarray, @object + .size publicarray, 16 +publicarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .string "\024" + .zero 510 + .globl secretarray_size + .align 4 + .type secretarray_size, @object + .size secretarray_size, 4 +secretarray_size: + .long 16 + .globl secretarray + .align 4 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\n\025 +6ALWbmny\204\217\232\245" + .globl temp + .bss + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .globl case8_mult + .data + .align 4 + .type case8_mult, @object + .size case8_mult, 4 +case8_mult: + .long 200 + .text + .globl case_8 + .type case_8, @function +case_8: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + subl $16, %esp + movl $0, case8_mult + movl case8_mult, %eax + imull 8(%ebp), %eax + movb publicarray(%eax), %al + movb %al, -1(%ebp) +#APP +# 21 "case8.c" 1 + mfence +# 0 "" 2 +#NO_APP + movzbl -1(%ebp), %eax + sall $9, %eax + movb publicarray2(%eax), %dl + movb temp, %al + andl %edx, %eax + movb %al, temp + nop + leave + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size case_8, .-case_8 + .ident "GCC: (GNU) 11.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/journal/v4_tests/litmus_stl_barrier/config b/journal/v4_tests/litmus_stl_barrier/config new file mode 100644 index 0000000..fce322e --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/config @@ -0,0 +1,4 @@ +c([],[]). +low([]). +keep_sym([symbolicarray, publicarray]). +ign([]). diff --git a/journal/v4_tests/litmus_stl_barrier/execute_spectector.sh b/journal/v4_tests/litmus_stl_barrier/execute_spectector.sh new file mode 100755 index 0000000..f2a211d --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/execute_spectector.sh @@ -0,0 +1,11 @@ +#!/bin/bash +rm -r stats/* +for file in *.s +do + echo "-------Executing $file ------------" + spectector "$file" $SOLVER -s -a noninter --steps 1000000 --parse-uns --skip-uns --version 4 -w 200 --stats "stats/stats_barrier_$file.txt" --keep-sym [secretarray] | grep 'data leak\|program is' +done +for file in stats/* # Stats writes an extra comma that we delete + do + truncate -s -1 $file + done diff --git a/journal/v4_tests/litmus_stl_barrier/makefile b/journal/v4_tests/litmus_stl_barrier/makefile new file mode 100644 index 0000000..2dfcad8 --- /dev/null +++ b/journal/v4_tests/litmus_stl_barrier/makefile @@ -0,0 +1,9 @@ + +SOURCES = $(wildcard *.c) +ASM = $(patsubst %.c, %.s, $(SOURCES)) +$(info $$var is [${SOURCES}]) +$(ASM): $(SOURCES) + #$(CC) -S -c $^ + $(CC) -O0 -m32 -march=i386 -fno-stack-protector -static -no-pie -fno-pic -S -c $^ +clean: + rm -rf *.s diff --git a/journal/v5_tests/README.md b/journal/v5_tests/README.md new file mode 100644 index 0000000..599fa79 --- /dev/null +++ b/journal/v5_tests/README.md @@ -0,0 +1,9 @@ +Contains the test cases for Spectre V5. + +We stripped the examples from the repositories (safeside, transientfail) of all library calls that are not necessary for the vulnerability, because of the +limitations of the translation in Spectector. These library calls were either deleted or inlined. +We replaced functions like ForceRead or cache_encode with a construct of a secretarray and an access to it. This simulates accessing secret data. + +# ret2spec_call_ret_disparity +Here we had to change the inline assembly that restores the correct stack frame (UnwindStackAndSlowlyReturnTo) to manually unwinding the stack. The reason is a limitation of the +translation of Spectector. diff --git a/journal/v5_tests/execute_v5.sh b/journal/v5_tests/execute_v5.sh new file mode 100755 index 0000000..c390e30 --- /dev/null +++ b/journal/v5_tests/execute_v5.sh @@ -0,0 +1,65 @@ +#!/bin/bash +rm -r stats/* + +echo "-------------- Executing safeside example ret2spec_call_ret --------------------" +spectector "ret2spec_test/ret2spec_call_ret.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns --keep-sym [secretarray] -e [main] --stats "stats/ret2spec_call_ret.txt" | grep 'data leak\|program is' + +echo "---- Now with barrier defense-----" +spectector "ret2spec_test/ret2spec_call_ret_barr.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns --keep-sym [secretarray] -e [main] --stats "stats/barrier_ret2spec_call_ret.txt" | grep 'data leak\|program is' + +echo "---- Now with retpoline defense-----" +spectector "ret2spec_test/ret2spec_call_ret_retpoline.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns --keep-sym [secretarray] -e [main] --stats "stats/retpo_ret2spec_call_ret.txt" | grep 'data leak\|program is' + + +echo "-------------- Executing transfail examples --------------------" + +echo "-------------- Executing ca_ip --------------------" +spectector "transfail/ca_ip.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns -e [main] --keep-sym [real_secret] --stats "stats/ca_ip.txt" | grep 'data leak\|program is' + + +echo "-------------- Executing ca_oop --------------------" +spectector "transfail/ca_oop.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns -e [main] --keep-sym [secret] --stats "stats/ca_oop.txt" | grep 'data leak\|program is' + +echo "-------------- Executing sa_ip --------------------" +spectector "transfail/sa_ip.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns -e [main] --keep-sym [real_secret] --stats "stats/sa_ip.txt" | grep 'data leak\|program is' + + +echo "-------------- Executing sa_oop --------------------" +spectector "transfail/sa_oop_min.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns --keep-sym [secretarray] -e [call_start] --stats "stats/sa_oop_min.txt" | grep 'data leak\|program is' + +echo "---- Now with barrier defense-----" + +echo "-------------- Executing ca_ip_barr --------------------" +spectector "transfail/ca_ip_barr.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns -e [main] --keep-sym [real_secret] --stats "stats/barrier_ca_ip.txt" | grep 'data leak\|program is' + + +echo "-------------- Executing ca_oop_barr --------------------" +spectector "transfail/ca_oop_barr.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns -e [main] --keep-sym [secret] --stats "stats/barrier_ca_oop.txt" | grep 'data leak\|program is' + +echo "-------------- Executing sa_ip_barr --------------------" +spectector "transfail/sa_ip_barr.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns -e [main] --keep-sym [real_secret] --stats "stats/barrier_sa_ip.txt"| grep 'data leak\|program is' + + +echo "-------------- Executing sa_oop_barr --------------------" +spectector "transfail/sa_oop_barr.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns --keep-sym [secretarray] -e [call_start] --stats "stats/barrier_sa_oop.txt" | grep 'data leak\|program is' + + +echo "---- Now with retpoline defense-----" + +echo "-------------- Executing ca_ip_retpoline --------------------" +spectector "transfail/ca_ip_retpoline.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns -e [main] --keep-sym [real_secret] --stats "stats/retpo_ca_ip.txt" | grep 'data leak\|program is' + + +echo "-------------- Executing ca_oop_retpoline --------------------" +spectector "transfail/ca_oop_retpoline.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns -e [main] --keep-sym [secret] --stats "stats/retpo_ca_oop.txt"| grep 'data leak\|program is' + +echo "-------------- Executing sa_ip_retpoline --------------------" +spectector "transfail/sa_ip_retpoline.s" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns -e [main] --keep-sym [real_secret] --stats "stats/retpo_sa_ip.txt" | grep 'data leak\|program is' + +echo "-------------- Executing sa_oop_retpoline --------------------" +spectector "transfail/sa_oop_retpoline.muasm" $SOLVER -s -a noninter --steps 1000000 -c 'c([],[])' --version 5 -w 200 --skip-uns --parse-uns --keep-sym [secretarray] -e [call_start] --stats "stats/retpo_sa_oop.txt" | grep 'data leak\|program is' + +for file in stats/* + do + truncate -s -1 $file + done diff --git a/journal/v5_tests/makefile b/journal/v5_tests/makefile new file mode 100644 index 0000000..3e217f5 --- /dev/null +++ b/journal/v5_tests/makefile @@ -0,0 +1,3 @@ +all: + $(MAKE) -C ret2spec_test + $(MAKE) -C transfail diff --git a/journal/v5_tests/ret2spec_test/makefile b/journal/v5_tests/ret2spec_test/makefile new file mode 100644 index 0000000..9da4ec2 --- /dev/null +++ b/journal/v5_tests/ret2spec_test/makefile @@ -0,0 +1,9 @@ +SOURCES = $(wildcard *.c) +ASM = $(patsubst %.c, %.s, $(SOURCES)) +$(info $$var is [${SOURCES}]) +$(ASM): $(SOURCES) + $(CC) -S -fcf-protection=branch -mmanual-endbr -c $^ +clean: + rm -rf *.s.* +# -fcf-protection=branch -mmanual-endbr disables CET feature of CPU for inidrect branches +# Since spectector does not parse endbr instructions and they look annoying diff --git a/journal/v5_tests/ret2spec_test/ret2spec_call_ret.c b/journal/v5_tests/ret2spec_test/ret2spec_call_ret.c new file mode 100644 index 0000000..ab728a2 --- /dev/null +++ b/journal/v5_tests/ret2spec_test/ret2spec_call_ret.c @@ -0,0 +1,32 @@ +#include +#include +extern char afterspeculation[]; + +uint8_t secretarray[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; +uint8_t publicarray2[256 * 2] = {0}; + +uint8_t idx = 0; +volatile uint8_t temp = 0; + +void UnwindStack() { +asm volatile( + "addq $8, %%rsp\n" + "addq $8, %%rsp\n" + "clflush (%%rsp)\n" + "mfence\n" + "lfence\n" + "ret\n":::); +} + +void speculation() { + UnwindStack(); + temp &= publicarray2[secretarray[idx]]; +} + + + +int main() { + speculation(); + asm volatile("afterspeculation:"); + return 0; +} diff --git a/journal/v5_tests/ret2spec_test/ret2spec_call_ret.s b/journal/v5_tests/ret2spec_test/ret2spec_call_ret.s new file mode 100644 index 0000000..00312ed --- /dev/null +++ b/journal/v5_tests/ret2spec_test/ret2spec_call_ret.s @@ -0,0 +1,128 @@ + .file "ret2spec_call_ret.c" + .text + .globl secretarray + .data + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .bss + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .zero 512 + .globl idx + .type idx, @object + .size idx, 1 +idx: + .zero 1 + .globl temp + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl UnwindStack + .type UnwindStack, @function +UnwindStack: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 12 "ret2spec_call_ret.c" 1 + addq $8, %rsp +addq $8, %rsp +clflush (%rsp) +mfence +lfence +ret + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size UnwindStack, .-UnwindStack + .globl speculation + .type speculation, @function +speculation: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call UnwindStack + movzbl idx(%rip), %eax + movzbl %al, %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movzbl %al, %eax + cltq + leaq publicarray2(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size speculation, .-speculation + .globl main + .type main, @function +main: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call speculation +#APP +# 30 "ret2spec_call_ret.c" 1 + afterspeculation: +# 0 "" 2 +#NO_APP + movl $0, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/ret2spec_test/ret2spec_call_ret_barr.c b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_barr.c new file mode 100644 index 0000000..bb1482e --- /dev/null +++ b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_barr.c @@ -0,0 +1,33 @@ +#include +#include +extern char afterspeculation[]; + +uint8_t secretarray[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; +uint8_t publicarray2[256 * 2] = {0}; + +uint8_t idx = 0; +volatile uint8_t temp = 0; + +void UnwindStack() { +asm volatile( + "addq $8, %%rsp\n" + "addq $8, %%rsp\n" + "clflush (%%rsp)\n" + "mfence\n" + "lfence\n" + "ret\n":::); +} + +void speculation() { + UnwindStack(); + asm("mfence"); + temp &= publicarray2[secretarray[idx]]; +} + + + +int main() { + speculation(); + asm volatile("afterspeculation:"); + return 0; +} diff --git a/journal/v5_tests/ret2spec_test/ret2spec_call_ret_barr.s b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_barr.s new file mode 100644 index 0000000..67933c9 --- /dev/null +++ b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_barr.s @@ -0,0 +1,133 @@ + .file "ret2spec_call_ret_barr.c" + .text + .globl secretarray + .data + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .bss + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .zero 512 + .globl idx + .type idx, @object + .size idx, 1 +idx: + .zero 1 + .globl temp + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl UnwindStack + .type UnwindStack, @function +UnwindStack: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 12 "ret2spec_call_ret_barr.c" 1 + addq $8, %rsp +addq $8, %rsp +clflush (%rsp) +mfence +lfence +ret + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size UnwindStack, .-UnwindStack + .globl speculation + .type speculation, @function +speculation: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call UnwindStack +#APP +# 23 "ret2spec_call_ret_barr.c" 1 + mfence +# 0 "" 2 +#NO_APP + movzbl idx(%rip), %eax + movzbl %al, %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movzbl %al, %eax + cltq + leaq publicarray2(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size speculation, .-speculation + .globl main + .type main, @function +main: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call speculation +#APP +# 31 "ret2spec_call_ret_barr.c" 1 + afterspeculation: +# 0 "" 2 +#NO_APP + movl $0, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/ret2spec_test/ret2spec_call_ret_retpoline.c b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_retpoline.c new file mode 100644 index 0000000..ecfc6ef --- /dev/null +++ b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_retpoline.c @@ -0,0 +1,38 @@ +#include +#include +extern char afterspeculation[]; + +uint8_t secretarray[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; +uint8_t publicarray2[256 * 2] = {0}; + +uint8_t idx = 0; +volatile uint8_t temp = 0; + +void UnwindStack() { +asm volatile( + "addq $8, %%rsp\n" + "addq $8, %%rsp\n" + "clflush (%%rsp)\n" + "mfence\n" + "lfence\n":::); +asm("call return_new"); // The modified retpoline defense in retspec trapping speculation in infinte loop +asm volatile("speculate:"); +asm volatile("nop"); +asm volatile ("jmp speculate"); +asm volatile("return_new:"); +asm volatile ("add $8, %rsp\t\n"); +asm volatile ("ret"); +} + +void speculation() { + UnwindStack(); + temp &= publicarray2[secretarray[idx]]; +} + + + +int main() { + speculation(); + asm volatile("afterspeculation:"); + return 0; +} diff --git a/journal/v5_tests/ret2spec_test/ret2spec_call_ret_retpoline.s b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_retpoline.s new file mode 100644 index 0000000..9d0f4fc --- /dev/null +++ b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_retpoline.s @@ -0,0 +1,149 @@ + .file "ret2spec_call_ret_retpoline.c" + .text + .globl secretarray + .data + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .globl publicarray2 + .bss + .align 32 + .type publicarray2, @object + .size publicarray2, 512 +publicarray2: + .zero 512 + .globl idx + .type idx, @object + .size idx, 1 +idx: + .zero 1 + .globl temp + .type temp, @object + .size temp, 1 +temp: + .zero 1 + .text + .globl UnwindStack + .type UnwindStack, @function +UnwindStack: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 12 "ret2spec_call_ret_retpoline.c" 1 + addq $8, %rsp +addq $8, %rsp +clflush (%rsp) +mfence +lfence + +# 0 "" 2 +# 18 "ret2spec_call_ret_retpoline.c" 1 + call return_new +# 0 "" 2 +# 19 "ret2spec_call_ret_retpoline.c" 1 + speculate: +# 0 "" 2 +# 20 "ret2spec_call_ret_retpoline.c" 1 + nop +# 0 "" 2 +# 21 "ret2spec_call_ret_retpoline.c" 1 + jmp speculate +# 0 "" 2 +# 22 "ret2spec_call_ret_retpoline.c" 1 + return_new: +# 0 "" 2 +# 23 "ret2spec_call_ret_retpoline.c" 1 + add $8, %rsp + +# 0 "" 2 +# 24 "ret2spec_call_ret_retpoline.c" 1 + ret +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size UnwindStack, .-UnwindStack + .globl speculation + .type speculation, @function +speculation: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call UnwindStack + movzbl idx(%rip), %eax + movzbl %al, %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movzbl %al, %eax + cltq + leaq publicarray2(%rip), %rdx + movzbl (%rax,%rdx), %edx + movzbl temp(%rip), %eax + andl %edx, %eax + movb %al, temp(%rip) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size speculation, .-speculation + .globl main + .type main, @function +main: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call speculation +#APP +# 36 "ret2spec_call_ret_retpoline.c" 1 + afterspeculation: +# 0 "" 2 +#NO_APP + movl $0, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/ret2spec_test/ret2spec_call_ret_test_new.c b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_test_new.c new file mode 100644 index 0000000..acb25b6 --- /dev/null +++ b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_test_new.c @@ -0,0 +1,52 @@ +#include +// Call a "UnwindStackAndSlowlyReturnTo" function which unwinds the stack +// jumping back to the "afterspeculation" label in the "LeakByte" function +// never executing the code that follows. +extern char afterspeculation[]; +int secretarray[16] = {}; +int publicarray2[256 * 2] = {0}; +int temp = 0; +int idx = 0; + +void UnwindStackAndSlowlyReturnTo(const void *address) { + + asm volatile( + "addq $8, %%rsp\n" + "popstack:\n" + "addq $8, %%rsp\n" + "cmpq %0, (%%rsp)\n" + "jne popstack\n" + "clflush (%%rsp)\n" + "mfence\n" + "lfence\n" + "ret\n"::"r"(address)); +} +static void Speculation() { + + const void *return_address = afterspeculation; + + + UnwindStackAndSlowlyReturnTo(return_address); // Never returns back here. + + // Everything that follows this is architecturally dead code. Never reached. + // However, the first two statements are executed speculatively. + temp &= publicarray2[secretarray[idx]]; + printf("Should not be printed"); +} + +static char LeakByte() { + + // Yields two "call" instructions, one "ret" instruction, speculatively + // accesses the oracle and ends up on the afterspeculation label below. + Speculation(); + + // Return target for the UnwindStackAndSlowlyReturnTo function. + asm volatile( + "_afterspeculation:\n" // For MacOS. + "afterspeculation:\n"); // For Linux. + printf("After afterspeculation"); +} + +void main() { + LeakByte(); +} diff --git a/journal/v5_tests/ret2spec_test/ret2spec_call_ret_test_new.s b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_test_new.s new file mode 100644 index 0000000..a688470 --- /dev/null +++ b/journal/v5_tests/ret2spec_test/ret2spec_call_ret_test_new.s @@ -0,0 +1,171 @@ + .file "ret2spec_call_ret_test_new.c" + .text + .globl secretarray + .bss + .align 32 + .type secretarray, @object + .size secretarray, 64 +secretarray: + .zero 64 + .globl publicarray2 + .align 32 + .type publicarray2, @object + .size publicarray2, 2048 +publicarray2: + .zero 2048 + .globl temp + .align 4 + .type temp, @object + .size temp, 4 +temp: + .zero 4 + .globl idx + .align 4 + .type idx, @object + .size idx, 4 +idx: + .zero 4 + .text + .globl UnwindStackAndSlowlyReturnTo + .type UnwindStackAndSlowlyReturnTo, @function +UnwindStackAndSlowlyReturnTo: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movq %rdi, -8(%rbp) + movq -8(%rbp), %rax +#APP +# 13 "ret2spec_call_ret_test_new.c" 1 + addq $8, %rsp +popstack: +addq $8, %rsp +cmpq %rax, (%rsp) +jne popstack +clflush (%rsp) +mfence +lfence +ret + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size UnwindStackAndSlowlyReturnTo, .-UnwindStackAndSlowlyReturnTo + .section .rodata +.LC0: + .string "Should not be printed" + .text + .type Speculation, @function +Speculation: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + leaq afterspeculation(%rip), %rax + movq %rax, -8(%rbp) + movq -8(%rbp), %rax + movq %rax, %rdi + call UnwindStackAndSlowlyReturnTo + movl idx(%rip), %eax + cltq + leaq 0(,%rax,4), %rdx + leaq secretarray(%rip), %rax + movl (%rdx,%rax), %eax + cltq + leaq 0(,%rax,4), %rdx + leaq publicarray2(%rip), %rax + movl (%rdx,%rax), %edx + movl temp(%rip), %eax + andl %edx, %eax + movl %eax, temp(%rip) + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + nop + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size Speculation, .-Speculation + .section .rodata +.LC1: + .string "After afterspeculation" + .text + .type LeakByte, @function +LeakByte: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call Speculation +#APP +# 44 "ret2spec_call_ret_test_new.c" 1 + _afterspeculation: +afterspeculation: + +# 0 "" 2 +#NO_APP + leaq .LC1(%rip), %rdi + movl $0, %eax + call printf@PLT + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size LeakByte, .-LeakByte + .globl main + .type main, @function +main: +.LFB3: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call LeakByte + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE3: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/ca_ip.c b/journal/v5_tests/transfail/ca_ip.c new file mode 100644 index 0000000..aa91245 --- /dev/null +++ b/journal/v5_tests/transfail/ca_ip.c @@ -0,0 +1,31 @@ +#include +#include +#include + + +size_t secret = 0; // we put the variable globally so spectector finds them correctly. +int real_secret = 83; // similar to original but now this secret is used by the victim Instead of assuming that 83 is a secret. + +void __attribute__((noinline)) in_place() { + asm volatile("pop %%rax\n" : : : "rax"); + asm("jmp return_label"); +} + + +void __attribute__((noinline)) attacker() { + while(1) { + in_place(); + asm volatile("movq (%0), %%rax\n" : : "c"(secret) : "rax"); + } +} + +void __attribute__((noinline)) victim() { + asm("return_label:"); + secret = real_secret; // Real secret only know to victim. We delayed the assignment of secret + return; // This return is mispredicted to attacker + +} + +int main(int argc, char **argv) { + attacker(); +} diff --git a/journal/v5_tests/transfail/ca_ip.s b/journal/v5_tests/transfail/ca_ip.s new file mode 100644 index 0000000..cdb845a --- /dev/null +++ b/journal/v5_tests/transfail/ca_ip.s @@ -0,0 +1,133 @@ + .file "ca_ip.c" + .text + .globl secret + .bss + .align 8 + .type secret, @object + .size secret, 8 +secret: + .zero 8 + .globl real_secret + .data + .align 4 + .type real_secret, @object + .size real_secret, 4 +real_secret: + .long 83 + .text + .globl in_place + .type in_place, @function +in_place: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 10 "ca_ip.c" 1 + pop %rax + +# 0 "" 2 +# 11 "ca_ip.c" 1 + jmp return_label +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size in_place, .-in_place + .globl attacker + .type attacker, @function +attacker: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +.L3: + movl $0, %eax + call in_place + movq secret(%rip), %rdx + movq %rdx, %rcx +#APP +# 18 "ca_ip.c" 1 + movq (%rcx), %rax + +# 0 "" 2 +#NO_APP + jmp .L3 + .cfi_endproc +.LFE1: + .size attacker, .-attacker + .globl victim + .type victim, @function +victim: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 23 "ca_ip.c" 1 + return_label: +# 0 "" 2 +#NO_APP + movl real_secret(%rip), %eax + cltq + movq %rax, secret(%rip) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size victim, .-victim + .globl main + .type main, @function +main: +.LFB3: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) + movl $0, %eax + call attacker + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE3: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/ca_ip_barr.c b/journal/v5_tests/transfail/ca_ip_barr.c new file mode 100644 index 0000000..c275579 --- /dev/null +++ b/journal/v5_tests/transfail/ca_ip_barr.c @@ -0,0 +1,32 @@ +#include +#include +#include + + +size_t secret = 0; // we put the variable globally so spectector finds them correctly. +int real_secret = 83; // similar to original but now this secret is used by the victim Instead of assuming that 83 is a secret. + +void __attribute__((noinline)) in_place() { + asm volatile("pop %%rax\n" : : : "rax"); + asm("jmp return_label"); +} + + +void __attribute__((noinline)) attacker() { + while(1) { + in_place(); + asm("mfence"); // fence defense as described in retpoline + asm volatile("movq (%0), %%rax\n" : : "c"(secret) : "rax"); + } +} + +void __attribute__((noinline)) victim() { + asm("return_label:"); + secret = real_secret; // Real secret only know to victim. We delayed the assignment of secret + return; // This return is mispredicted to attacker + +} + +int main(int argc, char **argv) { + attacker(); +} diff --git a/journal/v5_tests/transfail/ca_ip_barr.s b/journal/v5_tests/transfail/ca_ip_barr.s new file mode 100644 index 0000000..ca9265e --- /dev/null +++ b/journal/v5_tests/transfail/ca_ip_barr.s @@ -0,0 +1,138 @@ + .file "ca_ip_barr.c" + .text + .globl secret + .bss + .align 8 + .type secret, @object + .size secret, 8 +secret: + .zero 8 + .globl real_secret + .data + .align 4 + .type real_secret, @object + .size real_secret, 4 +real_secret: + .long 83 + .text + .globl in_place + .type in_place, @function +in_place: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 10 "ca_ip_barr.c" 1 + pop %rax + +# 0 "" 2 +# 11 "ca_ip_barr.c" 1 + jmp return_label +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size in_place, .-in_place + .globl attacker + .type attacker, @function +attacker: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +.L3: + movl $0, %eax + call in_place +#APP +# 18 "ca_ip_barr.c" 1 + mfence +# 0 "" 2 +#NO_APP + movq secret(%rip), %rdx + movq %rdx, %rcx +#APP +# 19 "ca_ip_barr.c" 1 + movq (%rcx), %rax + +# 0 "" 2 +#NO_APP + jmp .L3 + .cfi_endproc +.LFE1: + .size attacker, .-attacker + .globl victim + .type victim, @function +victim: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 24 "ca_ip_barr.c" 1 + return_label: +# 0 "" 2 +#NO_APP + movl real_secret(%rip), %eax + cltq + movq %rax, secret(%rip) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size victim, .-victim + .globl main + .type main, @function +main: +.LFB3: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) + movl $0, %eax + call attacker + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE3: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/ca_ip_retpoline.c b/journal/v5_tests/transfail/ca_ip_retpoline.c new file mode 100644 index 0000000..f130090 --- /dev/null +++ b/journal/v5_tests/transfail/ca_ip_retpoline.c @@ -0,0 +1,38 @@ +#include +#include +#include + + +size_t secret = 0; // we put the variable globally so spectector finds them correctly. +int real_secret = 83; // similar to original but now this secret is used by the victim Instead of assuming that 83 is a secret. + +void __attribute__((noinline)) in_place() { + asm volatile("pop %%rax\n" : : : "rax"); + asm("jmp return_label"); +} + + +void __attribute__((noinline)) attacker() { + while(1) { + in_place(); + asm volatile("movq (%0), %%rax\n" : : "c"(secret) : "rax"); + } +} + +void __attribute__((noinline)) victim() { + asm("return_label:"); + secret = real_secret; // Real secret only know to victim. We delayed the assignment of secret + asm ("popq %rbp"); // only ret instruction is replaced by retpoline, we need to correctly pop the stack frame before + asm("call return_new"); // The modified retpoline defense in retspec trapping speculation in infinte loop + asm volatile("speculate:"); + asm volatile("nop"); + asm volatile ("jmp speculate"); + asm volatile("return_new:"); + asm volatile ("add $8, %rsp\t\n"); + asm volatile ("ret"); + +} + +int main(int argc, char **argv) { + attacker(); +} diff --git a/journal/v5_tests/transfail/ca_ip_retpoline.s b/journal/v5_tests/transfail/ca_ip_retpoline.s new file mode 100644 index 0000000..08af9cb --- /dev/null +++ b/journal/v5_tests/transfail/ca_ip_retpoline.s @@ -0,0 +1,160 @@ + .file "ca_ip_retpoline.c" + .text + .globl secret + .bss + .align 8 + .type secret, @object + .size secret, 8 +secret: + .zero 8 + .globl real_secret + .data + .align 4 + .type real_secret, @object + .size real_secret, 4 +real_secret: + .long 83 + .text + .globl in_place + .type in_place, @function +in_place: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 10 "ca_ip_retpoline.c" 1 + pop %rax + +# 0 "" 2 +# 11 "ca_ip_retpoline.c" 1 + jmp return_label +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size in_place, .-in_place + .globl attacker + .type attacker, @function +attacker: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +.L3: + movl $0, %eax + call in_place + movq secret(%rip), %rdx + movq %rdx, %rcx +#APP +# 18 "ca_ip_retpoline.c" 1 + movq (%rcx), %rax + +# 0 "" 2 +#NO_APP + jmp .L3 + .cfi_endproc +.LFE1: + .size attacker, .-attacker + .globl victim + .type victim, @function +victim: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 23 "ca_ip_retpoline.c" 1 + return_label: +# 0 "" 2 +#NO_APP + movl real_secret(%rip), %eax + cltq + movq %rax, secret(%rip) +#APP +# 25 "ca_ip_retpoline.c" 1 + popq %rbp +# 0 "" 2 +# 26 "ca_ip_retpoline.c" 1 + call return_new +# 0 "" 2 +# 27 "ca_ip_retpoline.c" 1 + speculate: +# 0 "" 2 +# 28 "ca_ip_retpoline.c" 1 + nop +# 0 "" 2 +# 29 "ca_ip_retpoline.c" 1 + jmp speculate +# 0 "" 2 +# 30 "ca_ip_retpoline.c" 1 + return_new: +# 0 "" 2 +# 31 "ca_ip_retpoline.c" 1 + add $8, %rsp + +# 0 "" 2 +# 32 "ca_ip_retpoline.c" 1 + ret +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size victim, .-victim + .globl main + .type main, @function +main: +.LFB3: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) + movl $0, %eax + call attacker + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE3: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/ca_oop.c b/journal/v5_tests/transfail/ca_oop.c new file mode 100644 index 0000000..8966dea --- /dev/null +++ b/journal/v5_tests/transfail/ca_oop.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include + +int secret = 83; // Again secret will be kept symbolic so that there is a difference and not just 83 or S as output. +void __attribute__((noinline)) pollute_rsb() { + asm volatile("pop %%rax\n" : : : "rax"); // For our case actually not necessary but also not wrong + asm("jmp return_label"); // jmp to victim +} + +void __attribute ((noinline)) attacker() { + pollute_rsb(); // call function never return below + //architecturally never executed + asm volatile("movq (%0), %%rax\n" : : "c"(secret) : "rax"); //cache_encode function of transfail + //temp &= data[secretarray[idx]]; +} + +void __attribute__((noinline)) victim() { + asm("return_label:"); + return; // This return mispredicts to return in attacker +} + +int main (int argc, char **argv) { + attacker(); +} diff --git a/journal/v5_tests/transfail/ca_oop.s b/journal/v5_tests/transfail/ca_oop.s new file mode 100644 index 0000000..8a64742 --- /dev/null +++ b/journal/v5_tests/transfail/ca_oop.s @@ -0,0 +1,125 @@ + .file "ca_oop.c" + .text + .globl secret + .data + .align 4 + .type secret, @object + .size secret, 4 +secret: + .long 83 + .text + .globl pollute_rsb + .type pollute_rsb, @function +pollute_rsb: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 9 "ca_oop.c" 1 + pop %rax + +# 0 "" 2 +# 10 "ca_oop.c" 1 + jmp return_label +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size pollute_rsb, .-pollute_rsb + .globl attacker + .type attacker, @function +attacker: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call pollute_rsb + movl secret(%rip), %edx + movl %edx, %ecx +#APP +# 16 "ca_oop.c" 1 + movq (%ecx), %rax + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size attacker, .-attacker + .globl victim + .type victim, @function +victim: +.LFB8: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 21 "ca_oop.c" 1 + return_label: +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size victim, .-victim + .globl main + .type main, @function +main: +.LFB9: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) + movl $0, %eax + call attacker + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/ca_oop_barr.c b/journal/v5_tests/transfail/ca_oop_barr.c new file mode 100644 index 0000000..efca339 --- /dev/null +++ b/journal/v5_tests/transfail/ca_oop_barr.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include + +int secret = 83; // Again secret will be kept symbolic so that there is a difference and not just 83 or S as output. +void __attribute__((noinline)) pollute_rsb() { + asm volatile("pop %%rax\n" : : : "rax"); // For our case actually not necessary but also not wrong + asm("jmp return_label"); // jmp to victim +} + +void __attribute ((noinline)) attacker() { + pollute_rsb(); // call function never return below + asm volatile("mfence");// barrier stopping speculation + //architecturally never executed + asm volatile("movq (%0), %%rax\n" : : "c"(secret) : "rax"); //cache_encode function of transfail +} + +void __attribute__((noinline)) victim() { + asm("return_label:"); + return; // This return mispredicts to return in attacker +} + +int main (int argc, char **argv) { + attacker(); +} diff --git a/journal/v5_tests/transfail/ca_oop_barr.s b/journal/v5_tests/transfail/ca_oop_barr.s new file mode 100644 index 0000000..81d5e2f --- /dev/null +++ b/journal/v5_tests/transfail/ca_oop_barr.s @@ -0,0 +1,130 @@ + .file "ca_oop_barr.c" + .text + .globl secret + .data + .align 4 + .type secret, @object + .size secret, 4 +secret: + .long 83 + .text + .globl pollute_rsb + .type pollute_rsb, @function +pollute_rsb: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 9 "ca_oop_barr.c" 1 + pop %rax + +# 0 "" 2 +# 10 "ca_oop_barr.c" 1 + jmp return_label +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size pollute_rsb, .-pollute_rsb + .globl attacker + .type attacker, @function +attacker: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call pollute_rsb +#APP +# 15 "ca_oop_barr.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl secret(%rip), %edx + movl %edx, %ecx +#APP +# 17 "ca_oop_barr.c" 1 + movq (%ecx), %rax + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size attacker, .-attacker + .globl victim + .type victim, @function +victim: +.LFB8: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 21 "ca_oop_barr.c" 1 + return_label: +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size victim, .-victim + .globl main + .type main, @function +main: +.LFB9: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) + movl $0, %eax + call attacker + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/ca_oop_retpoline.c b/journal/v5_tests/transfail/ca_oop_retpoline.c new file mode 100644 index 0000000..c1666ca --- /dev/null +++ b/journal/v5_tests/transfail/ca_oop_retpoline.c @@ -0,0 +1,41 @@ + + + + +#include +#include +#include +#include +#include + +int secret = 83; // Again secret will be kept symbolic so that there is a difference and not just 83 or S as output. +void __attribute__((noinline)) pollute_rsb() { + asm volatile("pop %%rax\n" : : : "rax"); // For our case actually not necessary but also not wrong + asm("jmp return_label"); // jmp to victim +} + +void __attribute ((noinline)) attacker() { + pollute_rsb(); // call function never return below + //architecturally never executed + asm volatile("movq (%0), %%rax\n" : : "c"(secret) : "rax"); //cache_encode function of transfail +} + +void __attribute__((noinline)) victim() { + asm("return_label:"); + asm ("popq %rbp"); // only ret instruction is replaced by retpoline, we need to correctly pop the stack frame before + asm("call return_new"); // The modified retpoline defense in retspec trapping speculation in infinte loop + asm volatile("speculate:"); + asm volatile("nop"); + asm volatile ("jmp speculate"); + asm volatile("return_new:"); + asm volatile ("add $8, %rsp\t\n"); + asm volatile ("ret"); +} + +int main (int argc, char **argv) { + attacker(); +} + + + + diff --git a/journal/v5_tests/transfail/ca_oop_retpoline.s b/journal/v5_tests/transfail/ca_oop_retpoline.s new file mode 100644 index 0000000..b8ed686 --- /dev/null +++ b/journal/v5_tests/transfail/ca_oop_retpoline.s @@ -0,0 +1,150 @@ + .file "ca_oop_retpoline.c" + .text + .globl secret + .data + .align 4 + .type secret, @object + .size secret, 4 +secret: + .long 83 + .text + .globl pollute_rsb + .type pollute_rsb, @function +pollute_rsb: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 13 "ca_oop_retpoline.c" 1 + pop %rax + +# 0 "" 2 +# 14 "ca_oop_retpoline.c" 1 + jmp return_label +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size pollute_rsb, .-pollute_rsb + .globl attacker + .type attacker, @function +attacker: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call pollute_rsb + movl secret(%rip), %edx + movl %edx, %ecx +#APP +# 20 "ca_oop_retpoline.c" 1 + movq (%ecx), %rax + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size attacker, .-attacker + .globl victim + .type victim, @function +victim: +.LFB8: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 24 "ca_oop_retpoline.c" 1 + return_label: +# 0 "" 2 +# 25 "ca_oop_retpoline.c" 1 + popq %rbp +# 0 "" 2 +# 26 "ca_oop_retpoline.c" 1 + call return_new +# 0 "" 2 +# 27 "ca_oop_retpoline.c" 1 + speculate: +# 0 "" 2 +# 28 "ca_oop_retpoline.c" 1 + nop +# 0 "" 2 +# 29 "ca_oop_retpoline.c" 1 + jmp speculate +# 0 "" 2 +# 30 "ca_oop_retpoline.c" 1 + return_new: +# 0 "" 2 +# 31 "ca_oop_retpoline.c" 1 + add $8, %rsp + +# 0 "" 2 +# 32 "ca_oop_retpoline.c" 1 + ret +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size victim, .-victim + .globl main + .type main, @function +main: +.LFB9: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) + movl $0, %eax + call attacker + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/makefile b/journal/v5_tests/transfail/makefile new file mode 100644 index 0000000..9da4ec2 --- /dev/null +++ b/journal/v5_tests/transfail/makefile @@ -0,0 +1,9 @@ +SOURCES = $(wildcard *.c) +ASM = $(patsubst %.c, %.s, $(SOURCES)) +$(info $$var is [${SOURCES}]) +$(ASM): $(SOURCES) + $(CC) -S -fcf-protection=branch -mmanual-endbr -c $^ +clean: + rm -rf *.s.* +# -fcf-protection=branch -mmanual-endbr disables CET feature of CPU for inidrect branches +# Since spectector does not parse endbr instructions and they look annoying diff --git a/journal/v5_tests/transfail/sa_ip.c b/journal/v5_tests/transfail/sa_ip.c new file mode 100644 index 0000000..1368923 --- /dev/null +++ b/journal/v5_tests/transfail/sa_ip.c @@ -0,0 +1,37 @@ +#include +#include +#include + + +size_t secret = 0; // we put the variable globally so spectecto finds them correctly. Otherwise just defintion makes the program insecure + +int real_secret = 83; // similar to original but now this secret is used by the victim Instead of assuming that 83 is a secret. + +void __attribute__((noinline)) in_place() { + asm volatile("pop %%rax\n" : : : "rax"); + asm("jmp return_label"); +} + +void cache_encode(void *p) { + asm volatile("movq (%0), %%rax\n" : : "c"(p) : "rax"); // Defintion of cache_encode without offsets and defintion of maccess +} + +void __attribute__((noinline)) attacker() { + asm volatile("movq $65, %r14\t\n"); + in_place(); + //size_t secret = 0; // just this assignment makes the program unsafe. Because secret is speculatively accessed, since it is never executed normally. + asm volatile("movq %%r14, %0\n\t": "=r"(secret)); + asm volatile("movq (%0), %%rax\n" : : "c"(secret) : "rax"); +} + +void __attribute__((noinline)) victim() { + asm("return_label:"); + //asm volatile("movq $83, %r14\t\n") old thing + asm volatile("movq %0, %%r14\t\n" : : "c"(real_secret)); + return; // This return is mispredicted to attacker + +} + +int main(int argc, char **argv) { + attacker(); +} diff --git a/journal/v5_tests/transfail/sa_ip.s b/journal/v5_tests/transfail/sa_ip.s new file mode 100644 index 0000000..519364e --- /dev/null +++ b/journal/v5_tests/transfail/sa_ip.s @@ -0,0 +1,179 @@ + .file "sa_ip.c" + .text + .globl secret + .bss + .align 8 + .type secret, @object + .size secret, 8 +secret: + .zero 8 + .globl real_secret + .data + .align 4 + .type real_secret, @object + .size real_secret, 4 +real_secret: + .long 83 + .text + .globl in_place + .type in_place, @function +in_place: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 11 "sa_ip.c" 1 + pop %rax + +# 0 "" 2 +# 12 "sa_ip.c" 1 + jmp return_label +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size in_place, .-in_place + .globl cache_encode + .type cache_encode, @function +cache_encode: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movq %rdi, -8(%rbp) + movq -8(%rbp), %rdx + movq %rdx, %rcx +#APP +# 16 "sa_ip.c" 1 + movq (%rcx), %rax + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size cache_encode, .-cache_encode + .globl attacker + .type attacker, @function +attacker: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 20 "sa_ip.c" 1 + movq $65, %r14 + +# 0 "" 2 +#NO_APP + movl $0, %eax + call in_place +#APP +# 23 "sa_ip.c" 1 + movq %r14, %rax + +# 0 "" 2 +#NO_APP + movq %rax, secret(%rip) + movq secret(%rip), %rdx + movq %rdx, %rcx +#APP +# 24 "sa_ip.c" 1 + movq (%rcx), %rax + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size attacker, .-attacker + .globl victim + .type victim, @function +victim: +.LFB3: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 28 "sa_ip.c" 1 + return_label: +# 0 "" 2 +#NO_APP + movl real_secret(%rip), %eax + movl %eax, %ecx +#APP +# 30 "sa_ip.c" 1 + movq %ecx, %r14 + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE3: + .size victim, .-victim + .globl main + .type main, @function +main: +.LFB4: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) + movl $0, %eax + call attacker + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE4: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/sa_ip_barr.c b/journal/v5_tests/transfail/sa_ip_barr.c new file mode 100644 index 0000000..6b45485 --- /dev/null +++ b/journal/v5_tests/transfail/sa_ip_barr.c @@ -0,0 +1,38 @@ +#include +#include +#include + + +size_t secret = 0; // we put the variable globally so spectecto finds them correctly. Otherwise just defintion makes the program insecure + +int real_secret = 83; // similar to original but now this secret is used by the victim Instead of assuming that 83 is a secret. + +void __attribute__((noinline)) in_place() { + asm volatile("pop %%rax\n" : : : "rax"); + asm("jmp return_label"); +} + +void cache_encode(void *p) { + asm volatile("movq (%0), %%rax\n" : : "c"(p) : "rax"); // Defintion of cache_encode without offsets and defintion of maccess +} + +void __attribute__((noinline)) attacker() { + asm volatile("movq $65, %r14\t\n"); + in_place(); + asm ("mfence"); // added fence after call as described in ret2spec paper + //size_t secret = 0; // just this assignment makes the program unsafe. Because secret is speculatively accessed, since it is never executed normally. + asm volatile("movq %%r14, %0\n\t": "=r"(secret)); + asm volatile("movq (%0), %%rax\n" : : "c"(secret) : "rax"); +} + +void __attribute__((noinline)) victim() { + asm("return_label:"); + //asm volatile("movq $83, %r14\t\n") old thing + asm volatile("movq %0, %%r14\t\n" : : "c"(real_secret)); + return; // This return is mispredicted to attacker + +} + +int main(int argc, char **argv) { + attacker(); +} diff --git a/journal/v5_tests/transfail/sa_ip_barr.s b/journal/v5_tests/transfail/sa_ip_barr.s new file mode 100644 index 0000000..fc117ba --- /dev/null +++ b/journal/v5_tests/transfail/sa_ip_barr.s @@ -0,0 +1,182 @@ + .file "sa_ip_barr.c" + .text + .globl secret + .bss + .align 8 + .type secret, @object + .size secret, 8 +secret: + .zero 8 + .globl real_secret + .data + .align 4 + .type real_secret, @object + .size real_secret, 4 +real_secret: + .long 83 + .text + .globl in_place + .type in_place, @function +in_place: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 11 "sa_ip_barr.c" 1 + pop %rax + +# 0 "" 2 +# 12 "sa_ip_barr.c" 1 + jmp return_label +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size in_place, .-in_place + .globl cache_encode + .type cache_encode, @function +cache_encode: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movq %rdi, -8(%rbp) + movq -8(%rbp), %rdx + movq %rdx, %rcx +#APP +# 16 "sa_ip_barr.c" 1 + movq (%rcx), %rax + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size cache_encode, .-cache_encode + .globl attacker + .type attacker, @function +attacker: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 20 "sa_ip_barr.c" 1 + movq $65, %r14 + +# 0 "" 2 +#NO_APP + movl $0, %eax + call in_place +#APP +# 22 "sa_ip_barr.c" 1 + mfence +# 0 "" 2 +# 24 "sa_ip_barr.c" 1 + movq %r14, %rax + +# 0 "" 2 +#NO_APP + movq %rax, secret(%rip) + movq secret(%rip), %rdx + movq %rdx, %rcx +#APP +# 25 "sa_ip_barr.c" 1 + movq (%rcx), %rax + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size attacker, .-attacker + .globl victim + .type victim, @function +victim: +.LFB3: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 29 "sa_ip_barr.c" 1 + return_label: +# 0 "" 2 +#NO_APP + movl real_secret(%rip), %eax + movl %eax, %ecx +#APP +# 31 "sa_ip_barr.c" 1 + movq %ecx, %r14 + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE3: + .size victim, .-victim + .globl main + .type main, @function +main: +.LFB4: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) + movl $0, %eax + call attacker + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE4: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/sa_ip_retpoline.c b/journal/v5_tests/transfail/sa_ip_retpoline.c new file mode 100644 index 0000000..4cc2673 --- /dev/null +++ b/journal/v5_tests/transfail/sa_ip_retpoline.c @@ -0,0 +1,44 @@ +#include +#include +#include + + +size_t secret = 0; // we put the variable globally so spectecto finds them correctly. Otherwise just defintion makes the program insecure + +int real_secret = 83; // similar to original but now this secret is used by the victim Instead of assuming that 83 is a secret. + +void __attribute__((noinline)) in_place() { + asm volatile("pop %%rax\n" : : : "rax"); + asm("jmp return_label"); +} + +void cache_encode(void *p) { + asm volatile("movq (%0), %%rax\n" : : "c"(p) : "rax"); // Defintion of cache_encode without offsets and defintion of maccess +} + +void __attribute__((noinline)) attacker() { + asm volatile("movq $65, %r14\t\n"); + in_place(); + //size_t secret = 0; // just this assignment makes the program unsafe. Because secret is speculatively accessed, since it is never executed normally. + asm volatile("movq %%r14, %0\n\t": "=r"(secret)); + asm volatile("movq (%0), %%rax\n" : : "c"(secret) : "rax"); +} + +void __attribute__((noinline)) victim() { + asm("return_label:"); + //asm volatile("movq $83, %r14\t\n") old thing + asm volatile("movq %0, %%r14\t\n" : : "c"(real_secret)); + + asm ("popq %rbp"); // only ret instruction is replaced by retpoline, we need to correctly pop the stack frame before + asm("call return_new"); // The modified retpoline defense in retspec trapping speculation in infinte loop + asm volatile("speculate:"); + asm volatile("nop"); + asm volatile ("jmp speculate"); + asm volatile("return_new:"); + asm volatile ("add $8, %rsp\t\n"); + asm volatile ("ret"); +} + +int main(int argc, char **argv) { + attacker(); +} diff --git a/journal/v5_tests/transfail/sa_ip_retpoline.s b/journal/v5_tests/transfail/sa_ip_retpoline.s new file mode 100644 index 0000000..9f31d82 --- /dev/null +++ b/journal/v5_tests/transfail/sa_ip_retpoline.s @@ -0,0 +1,204 @@ + .file "sa_ip_retpoline.c" + .text + .globl secret + .bss + .align 8 + .type secret, @object + .size secret, 8 +secret: + .zero 8 + .globl real_secret + .data + .align 4 + .type real_secret, @object + .size real_secret, 4 +real_secret: + .long 83 + .text + .globl in_place + .type in_place, @function +in_place: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 11 "sa_ip_retpoline.c" 1 + pop %rax + +# 0 "" 2 +# 12 "sa_ip_retpoline.c" 1 + jmp return_label +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size in_place, .-in_place + .globl cache_encode + .type cache_encode, @function +cache_encode: +.LFB1: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movq %rdi, -8(%rbp) + movq -8(%rbp), %rdx + movq %rdx, %rcx +#APP +# 16 "sa_ip_retpoline.c" 1 + movq (%rcx), %rax + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE1: + .size cache_encode, .-cache_encode + .globl attacker + .type attacker, @function +attacker: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 20 "sa_ip_retpoline.c" 1 + movq $65, %r14 + +# 0 "" 2 +#NO_APP + movl $0, %eax + call in_place +#APP +# 23 "sa_ip_retpoline.c" 1 + movq %r14, %rax + +# 0 "" 2 +#NO_APP + movq %rax, secret(%rip) + movq secret(%rip), %rdx + movq %rdx, %rcx +#APP +# 24 "sa_ip_retpoline.c" 1 + movq (%rcx), %rax + +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size attacker, .-attacker + .globl victim + .type victim, @function +victim: +.LFB3: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 28 "sa_ip_retpoline.c" 1 + return_label: +# 0 "" 2 +#NO_APP + movl real_secret(%rip), %eax + movl %eax, %ecx +#APP +# 30 "sa_ip_retpoline.c" 1 + movq %ecx, %r14 + +# 0 "" 2 +# 32 "sa_ip_retpoline.c" 1 + popq %rbp +# 0 "" 2 +# 33 "sa_ip_retpoline.c" 1 + call return_new +# 0 "" 2 +# 34 "sa_ip_retpoline.c" 1 + speculate: +# 0 "" 2 +# 35 "sa_ip_retpoline.c" 1 + nop +# 0 "" 2 +# 36 "sa_ip_retpoline.c" 1 + jmp speculate +# 0 "" 2 +# 37 "sa_ip_retpoline.c" 1 + return_new: +# 0 "" 2 +# 38 "sa_ip_retpoline.c" 1 + add $8, %rsp + +# 0 "" 2 +# 39 "sa_ip_retpoline.c" 1 + ret +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE3: + .size victim, .-victim + .globl main + .type main, @function +main: +.LFB4: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) + movl $0, %eax + call attacker + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE4: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/sa_oop.c b/journal/v5_tests/transfail/sa_oop.c new file mode 100644 index 0000000..48c25b1 --- /dev/null +++ b/journal/v5_tests/transfail/sa_oop.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include + + +// inaccessible secret +char SECRET[] = "INACCESSIBLE SECRET"; // no define here + +unsigned char data[128]; +int idx; + +// Pop return address from the software stack, causing misspeculation when hitting the return +int __attribute__ ((noinline)) call_manipulate_stack() { + asm volatile("pop %%rax\n" : : : "rax"); + return 0; +} + +int __attribute__ ((noinline)) call_leak() { + // Manipulate the stack so that we don't return here, but to call_start + call_manipulate_stack(); + // architecturally, this is never executed + // Encode data in covert channel + asm volatile("movq (%0), %%rax\n" : : "c"(SECRET[idx]) : "rax"); + return 2; +} + +int __attribute__ ((noinline)) call_start() { + call_leak(); + return 1; +} + +void confuse_compiler() { + // this function -- although never called -- is required + // otherwise, the compiler replaces the calls with jumps + call_start(); + call_leak(); + call_manipulate_stack(); +} + +int main(int argc, const char **argv) { + + // nothing leaked so far + char leaked[sizeof(SECRET) + 1]; + leaked[sizeof(SECRET)] = 0; + + idx = 0; + while(1) { + // for every byte in the string + idx = (idx + 1) % sizeof(SECRET); + + + call_start(); + + } + + + return (0); +} diff --git a/journal/v5_tests/transfail/sa_oop.s b/journal/v5_tests/transfail/sa_oop.s new file mode 100644 index 0000000..33eb953 --- /dev/null +++ b/journal/v5_tests/transfail/sa_oop.s @@ -0,0 +1,165 @@ + .file "sa_oop.c" + .text + .globl SECRET + .data + .align 16 + .type SECRET, @object + .size SECRET, 20 +SECRET: + .string "INACCESSIBLE SECRET" + .comm data,128,32 + .comm idx,4,4 + .text + .globl call_manipulate_stack + .type call_manipulate_stack, @function +call_manipulate_stack: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 16 "sa_oop.c" 1 + pop %rax + +# 0 "" 2 +#NO_APP + movl $0, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size call_manipulate_stack, .-call_manipulate_stack + .globl call_leak + .type call_leak, @function +call_leak: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_manipulate_stack + movl idx(%rip), %eax + cltq + leaq SECRET(%rip), %rdx + movzbl (%rax,%rdx), %edx + movl %edx, %ecx +#APP +# 25 "sa_oop.c" 1 + movq (%cl), %rax + +# 0 "" 2 +#NO_APP + movl $2, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size call_leak, .-call_leak + .globl call_start + .type call_start, @function +call_start: +.LFB8: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_leak + movl $1, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size call_start, .-call_start + .globl confuse_compiler + .type confuse_compiler, @function +confuse_compiler: +.LFB9: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_start + movl $0, %eax + call call_leak + movl $0, %eax + call call_manipulate_stack + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size confuse_compiler, .-confuse_compiler + .globl main + .type main, @function +main: +.LFB10: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $48, %rsp + movl %edi, -36(%rbp) + movq %rsi, -48(%rbp) + movq %fs:40, %rax + movq %rax, -8(%rbp) + xorl %eax, %eax + movb $0, -12(%rbp) + movl $0, idx(%rip) +.L9: + movl idx(%rip), %eax + addl $1, %eax + movslq %eax, %rcx + movabsq $-3689348814741910323, %rdx + movq %rcx, %rax + mulq %rdx + shrq $4, %rdx + movq %rdx, %rax + salq $2, %rax + addq %rdx, %rax + salq $2, %rax + subq %rax, %rcx + movq %rcx, %rdx + movl %edx, %eax + movl %eax, idx(%rip) + movl $0, %eax + call call_start + jmp .L9 + .cfi_endproc +.LFE10: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/sa_oop_barr.c b/journal/v5_tests/transfail/sa_oop_barr.c new file mode 100644 index 0000000..40f9be6 --- /dev/null +++ b/journal/v5_tests/transfail/sa_oop_barr.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include + + +// inaccessible secret +char SECRET[] = "INACCESSIBLE SECRET"; // no define here + +unsigned char data[128]; +int idx; + +// Pop return address from the software stack, causing misspeculation when hitting the return +int __attribute__ ((noinline)) call_manipulate_stack() { + asm volatile("pop %%rax\n" : : : "rax"); + return 0; +} + +int __attribute__ ((noinline)) call_leak() { + // Manipulate the stack so that we don't return here, but to call_start + call_manipulate_stack(); + asm volatile("mfence"); + // architecturally, this is never executed + // Encode data in covert channel + asm volatile("movq (%0), %%rax\n" : : "c"(SECRET[idx]) : "rax"); + return 2; +} + +int __attribute__ ((noinline)) call_start() { + call_leak(); + return 1; +} + +void confuse_compiler() { + // this function -- although never called -- is required + // otherwise, the compiler replaces the calls with jumps + call_start(); + call_leak(); + call_manipulate_stack(); +} + +int main(int argc, const char **argv) { + + // nothing leaked so far + char leaked[sizeof(SECRET) + 1]; + leaked[sizeof(SECRET)] = 0; + + idx = 0; + while(1) { + // for every byte in the string + idx = (idx + 1) % sizeof(SECRET); + + + call_start(); + + } + + + return (0); +} diff --git a/journal/v5_tests/transfail/sa_oop_barr.s b/journal/v5_tests/transfail/sa_oop_barr.s new file mode 100644 index 0000000..9ccd739 --- /dev/null +++ b/journal/v5_tests/transfail/sa_oop_barr.s @@ -0,0 +1,170 @@ + .file "sa_oop_barr.c" + .text + .globl SECRET + .data + .align 16 + .type SECRET, @object + .size SECRET, 20 +SECRET: + .string "INACCESSIBLE SECRET" + .comm data,128,32 + .comm idx,4,4 + .text + .globl call_manipulate_stack + .type call_manipulate_stack, @function +call_manipulate_stack: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 16 "sa_oop_barr.c" 1 + pop %rax + +# 0 "" 2 +#NO_APP + movl $0, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size call_manipulate_stack, .-call_manipulate_stack + .globl call_leak + .type call_leak, @function +call_leak: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_manipulate_stack +#APP +# 23 "sa_oop_barr.c" 1 + mfence +# 0 "" 2 +#NO_APP + movl idx(%rip), %eax + cltq + leaq SECRET(%rip), %rdx + movzbl (%rax,%rdx), %edx + movl %edx, %ecx +#APP +# 26 "sa_oop_barr.c" 1 + movq (%cl), %rax + +# 0 "" 2 +#NO_APP + movl $2, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size call_leak, .-call_leak + .globl call_start + .type call_start, @function +call_start: +.LFB8: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_leak + movl $1, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size call_start, .-call_start + .globl confuse_compiler + .type confuse_compiler, @function +confuse_compiler: +.LFB9: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_start + movl $0, %eax + call call_leak + movl $0, %eax + call call_manipulate_stack + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size confuse_compiler, .-confuse_compiler + .globl main + .type main, @function +main: +.LFB10: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $48, %rsp + movl %edi, -36(%rbp) + movq %rsi, -48(%rbp) + movq %fs:40, %rax + movq %rax, -8(%rbp) + xorl %eax, %eax + movb $0, -12(%rbp) + movl $0, idx(%rip) +.L9: + movl idx(%rip), %eax + addl $1, %eax + movslq %eax, %rcx + movabsq $-3689348814741910323, %rdx + movq %rcx, %rax + mulq %rdx + shrq $4, %rdx + movq %rdx, %rax + salq $2, %rax + addq %rdx, %rax + salq $2, %rax + subq %rax, %rcx + movq %rcx, %rdx + movl %edx, %eax + movl %eax, idx(%rip) + movl $0, %eax + call call_start + jmp .L9 + .cfi_endproc +.LFE10: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/sa_oop_min.c b/journal/v5_tests/transfail/sa_oop_min.c new file mode 100644 index 0000000..cf0cebb --- /dev/null +++ b/journal/v5_tests/transfail/sa_oop_min.c @@ -0,0 +1,42 @@ + +#include +#include +#include +#include +#include + + +// inaccessible secret +#define SECRET "INACCESSIBLE SECRET" + +unsigned char data[128]; +uint8_t secretarray[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; +int idx; +int temp = 0; +// Pop return address from the software stack, causing misspeculation when hitting the return +int __attribute__ ((noinline)) call_manipulate_stack() { + asm volatile("pop %%rax\n" : : : "rax"); + return 0; +} + +int __attribute__ ((noinline)) call_leak() { + // Manipulate the stack so that we don't return here, but to call_start + call_manipulate_stack(); + // architecturally, this is never executed + // Encode data in covert channel + temp &= data[secretarray[idx]]; + return 2; +} + +int __attribute__ ((noinline)) call_start() { + call_leak(); + return 1; +} + +void confuse_compiler() { + // this function -- although never called -- is required + // otherwise, the compiler replaces the calls with jumps + call_start(); + call_leak(); + call_manipulate_stack(); +} diff --git a/journal/v5_tests/transfail/sa_oop_min.s b/journal/v5_tests/transfail/sa_oop_min.s new file mode 100644 index 0000000..f513040 --- /dev/null +++ b/journal/v5_tests/transfail/sa_oop_min.s @@ -0,0 +1,133 @@ + .file "sa_oop_min.c" + .text + .comm data,128,32 + .globl secretarray + .data + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .comm idx,4,4 + .globl temp + .bss + .align 4 + .type temp, @object + .size temp, 4 +temp: + .zero 4 + .text + .globl call_manipulate_stack + .type call_manipulate_stack, @function +call_manipulate_stack: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 18 "sa_oop_min.c" 1 + pop %rax + +# 0 "" 2 +#NO_APP + movl $0, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size call_manipulate_stack, .-call_manipulate_stack + .globl call_leak + .type call_leak, @function +call_leak: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_manipulate_stack + movl idx(%rip), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movzbl %al, %eax + cltq + leaq data(%rip), %rdx + movzbl (%rax,%rdx), %eax + movzbl %al, %edx + movl temp(%rip), %eax + andl %edx, %eax + movl %eax, temp(%rip) + movl $2, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size call_leak, .-call_leak + .globl call_start + .type call_start, @function +call_start: +.LFB8: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_leak + movl $1, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size call_start, .-call_start + .globl confuse_compiler + .type confuse_compiler, @function +confuse_compiler: +.LFB9: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_start + movl $0, %eax + call call_leak + movl $0, %eax + call call_manipulate_stack + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size confuse_compiler, .-confuse_compiler + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/sa_oop_retpoline.c b/journal/v5_tests/transfail/sa_oop_retpoline.c new file mode 100644 index 0000000..83967f0 --- /dev/null +++ b/journal/v5_tests/transfail/sa_oop_retpoline.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include + + +// inaccessible secret +char SECRET[] = "INACCESSIBLE SECRET"; // no define here + +unsigned char data[128]; +int idx; + +// Pop return address from the software stack, causing misspeculation when hitting the return +int __attribute__ ((noinline)) call_manipulate_stack() { + asm volatile("pop %%rax\n" : : : "rax"); + asm ("popq %rbp"); // only ret instruction is replaced by retpoline, we need to correctly pop the stack frame before + asm("call return_new"); // The modified retpoline defense in retspec trapping speculation in infinte loop + asm volatile("speculate:"); + asm volatile("nop"); + asm volatile ("jmp speculate"); + asm volatile("return_new:"); + asm volatile ("add $8, %rsp\t\n"); + asm volatile ("ret"); +} + +int __attribute__ ((noinline)) call_leak() { + // Manipulate the stack so that we don't return here, but to call_start + call_manipulate_stack(); + // architecturally, this is never executed + // Encode data in covert channel + asm volatile("movq (%0), %%rax\n" : : "c"(SECRET[idx]) : "rax"); + return 2; +} + +int __attribute__ ((noinline)) call_start() { + call_leak(); + return 1; +} + +void confuse_compiler() { + // this function -- although never called -- is required + // otherwise, the compiler replaces the calls with jumps + call_start(); + call_leak(); + call_manipulate_stack(); +} + +int main(int argc, const char **argv) { + + // nothing leaked so far + char leaked[sizeof(SECRET) + 1]; + leaked[sizeof(SECRET)] = 0; + + idx = 0; + while(1) { + // for every byte in the string + idx = (idx + 1) % sizeof(SECRET); + + + call_start(); + + } + + + return (0); +} diff --git a/journal/v5_tests/transfail/sa_oop_retpoline.c~ b/journal/v5_tests/transfail/sa_oop_retpoline.c~ new file mode 100644 index 0000000..8f1725c --- /dev/null +++ b/journal/v5_tests/transfail/sa_oop_retpoline.c~ @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include + + +// inaccessible secret +char SECRET[] = "INACCESSIBLE SECRET"; // no define here + +unsigned char data[128]; +int idx; + +// Pop return address from the software stack, causing misspeculation when hitting the return +int __attribute__ ((noinline)) call_manipulate_stack() { + asm volatile("pop %%rax\n" : : : "rax"); + asm("call return_new"); // The modified retpoline defense in retspec trapping speculation in infinte loop + asm volatile("speculate:"); + asm volatile("nop"); + asm volatile ("jmp speculate"); + asm volatile("return_new:"); + asm volatile ("add $8, %rsp\t\n"); + asm volatile ("ret"); +} + +int __attribute__ ((noinline)) call_leak() { + // Manipulate the stack so that we don't return here, but to call_start + call_manipulate_stack(); + // architecturally, this is never executed + // Encode data in covert channel + asm volatile("movq (%0), %%rax\n" : : "c"(SECRET[idx]) : "rax"); + return 2; +} + +int __attribute__ ((noinline)) call_start() { + call_leak(); + return 1; +} + +void confuse_compiler() { + // this function -- although never called -- is required + // otherwise, the compiler replaces the calls with jumps + call_start(); + call_leak(); + call_manipulate_stack(); +} + +int main(int argc, const char **argv) { + + // nothing leaked so far + char leaked[sizeof(SECRET) + 1]; + leaked[sizeof(SECRET)] = 0; + + idx = 0; + while(1) { + // for every byte in the string + idx = (idx + 1) % sizeof(SECRET); + + + call_start(); + + } + + + return (0); +} diff --git a/journal/v5_tests/transfail/sa_oop_retpoline.muasm b/journal/v5_tests/transfail/sa_oop_retpoline.muasm new file mode 100644 index 0000000..18850a4 --- /dev/null +++ b/journal/v5_tests/transfail/sa_oop_retpoline.muasm @@ -0,0 +1,34 @@ +manipulate_return_address: + sp <- sp + 8 + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp return_new +speculate: + skip + jmp speculate +return_new: + sp <- sp + 8 + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +call_leak: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp manipulate_return_address + load eax, secret + load edx, eax + spbarr + retstart + load tmp,sp/\140737488355327 + sp<-sp+8 + jmp tmp +call_start: + callstart + sp<-sp-8 + store pc+2, sp/\140737488355327 + jmp call_leak +call_end: + skip diff --git a/journal/v5_tests/transfail/sa_oop_retpoline.s b/journal/v5_tests/transfail/sa_oop_retpoline.s new file mode 100644 index 0000000..5bd3893 --- /dev/null +++ b/journal/v5_tests/transfail/sa_oop_retpoline.s @@ -0,0 +1,190 @@ + .file "sa_oop_retpoline.c" + .text + .globl SECRET + .data + .align 16 + .type SECRET, @object + .size SECRET, 20 +SECRET: + .string "INACCESSIBLE SECRET" + .comm data,128,32 + .comm idx,4,4 + .text + .globl call_manipulate_stack + .type call_manipulate_stack, @function +call_manipulate_stack: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 16 "sa_oop_retpoline.c" 1 + pop %rax + +# 0 "" 2 +# 17 "sa_oop_retpoline.c" 1 + popq %rbp +# 0 "" 2 +# 18 "sa_oop_retpoline.c" 1 + call return_new +# 0 "" 2 +# 19 "sa_oop_retpoline.c" 1 + speculate: +# 0 "" 2 +# 20 "sa_oop_retpoline.c" 1 + nop +# 0 "" 2 +# 21 "sa_oop_retpoline.c" 1 + jmp speculate +# 0 "" 2 +# 22 "sa_oop_retpoline.c" 1 + return_new: +# 0 "" 2 +# 23 "sa_oop_retpoline.c" 1 + add $8, %rsp + +# 0 "" 2 +# 24 "sa_oop_retpoline.c" 1 + ret +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size call_manipulate_stack, .-call_manipulate_stack + .globl call_leak + .type call_leak, @function +call_leak: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_manipulate_stack + movl idx(%rip), %eax + cltq + leaq SECRET(%rip), %rdx + movzbl (%rax,%rdx), %edx + movl %edx, %ecx +#APP +# 32 "sa_oop_retpoline.c" 1 + movq (%cl), %rax + +# 0 "" 2 +#NO_APP + movl $2, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size call_leak, .-call_leak + .globl call_start + .type call_start, @function +call_start: +.LFB8: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_leak + movl $1, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size call_start, .-call_start + .globl confuse_compiler + .type confuse_compiler, @function +confuse_compiler: +.LFB9: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call call_start + movl $0, %eax + call call_leak + movl $0, %eax + call call_manipulate_stack + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size confuse_compiler, .-confuse_compiler + .globl main + .type main, @function +main: +.LFB10: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $48, %rsp + movl %edi, -36(%rbp) + movq %rsi, -48(%rbp) + movq %fs:40, %rax + movq %rax, -8(%rbp) + xorl %eax, %eax + movb $0, -12(%rbp) + movl $0, idx(%rip) +.L8: + movl idx(%rip), %eax + addl $1, %eax + movslq %eax, %rcx + movabsq $-3689348814741910323, %rdx + movq %rcx, %rax + mulq %rdx + shrq $4, %rdx + movq %rdx, %rax + salq $2, %rax + addq %rdx, %rax + salq $2, %rax + subq %rax, %rcx + movq %rcx, %rdx + movl %edx, %eax + movl %eax, idx(%rip) + movl $0, %eax + call call_start + jmp .L8 + .cfi_endproc +.LFE10: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x1 +3: + .align 8 +4: diff --git a/journal/v5_tests/transfail/transfail_ca_oop.s b/journal/v5_tests/transfail/transfail_ca_oop.s new file mode 100644 index 0000000..c8636cf --- /dev/null +++ b/journal/v5_tests/transfail/transfail_ca_oop.s @@ -0,0 +1,142 @@ + .file "transfail_ca_oop.c" + .text + .comm data,128,32 + .globl secretarray + .data + .align 16 + .type secretarray, @object + .size secretarray, 16 +secretarray: + .ascii "\001\002\003\004\005\006\007\b\t\n\013\f\r\016\017\020" + .comm idx,4,4 + .globl temp + .bss + .align 4 + .type temp, @object + .size temp, 4 +temp: + .zero 4 + .text + .globl pollute_rsb + .type pollute_rsb, @function +pollute_rsb: +.LFB6: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 14 "transfail_ca_oop.c" 1 + pop %rax + +# 0 "" 2 +# 15 "transfail_ca_oop.c" 1 + jmp return_label +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size pollute_rsb, .-pollute_rsb + .globl attacker + .type attacker, @function +attacker: +.LFB7: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl $0, %eax + call pollute_rsb + movl idx(%rip), %eax + cltq + leaq secretarray(%rip), %rdx + movzbl (%rax,%rdx), %eax + movzbl %al, %eax + cltq + leaq data(%rip), %rdx + movzbl (%rax,%rdx), %eax + movzbl %al, %edx + movl temp(%rip), %eax + andl %edx, %eax + movl %eax, temp(%rip) + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size attacker, .-attacker + .globl victim + .type victim, @function +victim: +.LFB8: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 +#APP +# 25 "transfail_ca_oop.c" 1 + return_label: +# 0 "" 2 +#NO_APP + nop + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size victim, .-victim + .globl main + .type main, @function +main: +.LFB9: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movq %rsi, -16(%rbp) + movl $0, %eax + call attacker + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size main, .-main + .ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: