diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2023-04-03 07:45:09 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2023-04-03 10:29:09 +0200 |
| commit | d04ac3a54895a36998e3f1da27c2ce33f7a80c5a (patch) | |
| tree | e79bc6b62402f2b9e1b4cf91bc38b2a6c404e7b1 /executor | |
| parent | 7c00f48c0c766f7abd4601bd9848527dd1e4be77 (diff) | |
sys/linux: add syz_pkey_set syscalls
The syscall sets PKRU register which is part of protection keys (pkey).
Diffstat (limited to 'executor')
| -rw-r--r-- | executor/common_linux.h | 24 |
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 |
