Add a test that locks the shadow stack write bit and then attempts to
disable write. The disable should fail with EPERM since it's in a locked
state. This also preserves the write bit being set for the whole test
suite as well as preserving the ability to unlock at the end.
---
 .../testing/selftests/x86/test_shadow_stack.c | 39 +++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/tools/testing/selftests/x86/test_shadow_stack.c 
b/tools/testing/selftests/x86/test_shadow_stack.c
index b52c5420c137..72e7329d89d7 100644
--- a/tools/testing/selftests/x86/test_shadow_stack.c
+++ b/tools/testing/selftests/x86/test_shadow_stack.c
@@ -1060,6 +1060,24 @@ int test_ptrace(void)
        return 1;
 }
 
+static int test_locking(void)
+{
+
+       if (ARCH_PRCTL(ARCH_SHSTK_LOCK, ARCH_SHSTK_WRSS)) {
+               printf("[FAIL]\tCould not lock Shadow stack write\n");
+               return 1;
+       }
+
+       if (ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_WRSS) != -EPERM) {
+               printf("[FAIL]\tCould change Shadow stack write after lock\n");
+               return 1;
+       }
+
+       printf("[OK]\tShadow stack locking\n");
+
+       return 0;
+}
+
 int main(int argc, char *argv[])
 {
        int ret = 0;
@@ -1079,12 +1097,33 @@ int main(int argc, char *argv[])
                return 1;
        }
 
+       /* Note: test_shadow_stack_lock() needs write enabled */
        if (ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_WRSS)) {
                printf("[SKIP]\tCould not enable WRSS\n");
                ret = 1;
                goto out;
        }
 
+       unsigned long status = 0;
+
+       if (ARCH_PRCTL(ARCH_SHSTK_STATUS, &status)) {
+               printf("[FAIL]\tCould not get Shadow stack status\n");
+               ret = 1;
+               goto out;
+       }
+
+       if (status != (ARCH_SHSTK_WRSS|ARCH_SHSTK_SHSTK)) {
+               printf("[FAIL]\tStatus not as expected, got 0x%lx status, 
wanted: 0x%llx\n",
+                       status, (ARCH_SHSTK_WRSS|ARCH_SHSTK_SHSTK));
+               ret = 1;
+               goto out;
+       }
+
+       if (test_locking()) {
+               ret = 1;
+               goto out;
+       }
+
        /* Should have succeeded if here, but this is a test, so double check. 
*/
        if (!get_ssp()) {
                printf("[FAIL]\tShadow stack disabled\n");
-- 
2.55.0


Reply via email to