aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_linux.h
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2023-04-03 07:45:09 +0200
committerDmitry Vyukov <dvyukov@google.com>2023-04-03 10:29:09 +0200
commitd04ac3a54895a36998e3f1da27c2ce33f7a80c5a (patch)
treee79bc6b62402f2b9e1b4cf91bc38b2a6c404e7b1 /executor/common_linux.h
parent7c00f48c0c766f7abd4601bd9848527dd1e4be77 (diff)
sys/linux: add syz_pkey_set syscalls
The syscall sets PKRU register which is part of protection keys (pkey).
Diffstat (limited to 'executor/common_linux.h')
-rw-r--r--executor/common_linux.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h
index e53a908ab..a2736624a 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -5547,3 +5547,27 @@ static long syz_clone3(volatile long a0, volatile long a1)
}
#endif
+
+#if SYZ_EXECUTOR || __NR_syz_pkey_set
+// syz_pkey_set(key pkey, val flags[pkey_flags])
+static long syz_pkey_set(volatile long pkey, volatile long val)
+{
+#if GOARCH_amd64 || GOARCH_386
+ uint32 eax = 0;
+ uint32 ecx = 0;
+ asm volatile("rdpkru"
+ : "=a"(eax)
+ : "c"(ecx)
+ : "edx");
+ // PKRU register contains 2 bits per key.
+ // Max number of keys is 16.
+ // Clear old bits for the key:
+ eax &= ~(3 << ((pkey % 16) * 2));
+ // Set new bits for the key:
+ eax |= (val & 3) << ((pkey % 16) * 2);
+ uint32 edx = 0;
+ asm volatile("wrpkru" ::"a"(eax), "c"(ecx), "d"(edx));
+#endif
+ return 0;
+}
+#endif