PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/arm64/include/asm/pointer_auth.h

https://gitlab.com/pachecof/centos-stream-9
C Header | 152 lines | 116 code | 27 blank | 9 comment | 10 complexity | 3f748ef54f2bdce31fb8b01c97cc9843 MD5 | raw file
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __ASM_POINTER_AUTH_H
  3. #define __ASM_POINTER_AUTH_H
  4. #include <linux/bitops.h>
  5. #include <linux/prctl.h>
  6. #include <linux/random.h>
  7. #include <asm/cpufeature.h>
  8. #include <asm/memory.h>
  9. #include <asm/sysreg.h>
  10. #ifdef CONFIG_ARM64_PTR_AUTH
  11. /*
  12. * Each key is a 128-bit quantity which is split across a pair of 64-bit
  13. * registers (Lo and Hi).
  14. */
  15. struct ptrauth_key {
  16. unsigned long lo, hi;
  17. };
  18. /*
  19. * We give each process its own keys, which are shared by all threads. The keys
  20. * are inherited upon fork(), and reinitialised upon exec*().
  21. */
  22. struct ptrauth_keys_user {
  23. struct ptrauth_key apia;
  24. struct ptrauth_key apib;
  25. struct ptrauth_key apda;
  26. struct ptrauth_key apdb;
  27. struct ptrauth_key apga;
  28. };
  29. #define __ptrauth_key_install_nosync(k, v) \
  30. do { \
  31. struct ptrauth_key __pki_v = (v); \
  32. write_sysreg_s(__pki_v.lo, SYS_ ## k ## KEYLO_EL1); \
  33. write_sysreg_s(__pki_v.hi, SYS_ ## k ## KEYHI_EL1); \
  34. } while (0)
  35. #ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
  36. struct ptrauth_keys_kernel {
  37. struct ptrauth_key apia;
  38. };
  39. static __always_inline void ptrauth_keys_init_kernel(struct ptrauth_keys_kernel *keys)
  40. {
  41. if (system_supports_address_auth())
  42. get_random_bytes(&keys->apia, sizeof(keys->apia));
  43. }
  44. static __always_inline void ptrauth_keys_switch_kernel(struct ptrauth_keys_kernel *keys)
  45. {
  46. if (!system_supports_address_auth())
  47. return;
  48. __ptrauth_key_install_nosync(APIA, keys->apia);
  49. isb();
  50. }
  51. #endif /* CONFIG_ARM64_PTR_AUTH_KERNEL */
  52. static inline void ptrauth_keys_install_user(struct ptrauth_keys_user *keys)
  53. {
  54. if (system_supports_address_auth()) {
  55. __ptrauth_key_install_nosync(APIB, keys->apib);
  56. __ptrauth_key_install_nosync(APDA, keys->apda);
  57. __ptrauth_key_install_nosync(APDB, keys->apdb);
  58. }
  59. if (system_supports_generic_auth())
  60. __ptrauth_key_install_nosync(APGA, keys->apga);
  61. }
  62. static inline void ptrauth_keys_init_user(struct ptrauth_keys_user *keys)
  63. {
  64. if (system_supports_address_auth()) {
  65. get_random_bytes(&keys->apia, sizeof(keys->apia));
  66. get_random_bytes(&keys->apib, sizeof(keys->apib));
  67. get_random_bytes(&keys->apda, sizeof(keys->apda));
  68. get_random_bytes(&keys->apdb, sizeof(keys->apdb));
  69. }
  70. if (system_supports_generic_auth())
  71. get_random_bytes(&keys->apga, sizeof(keys->apga));
  72. ptrauth_keys_install_user(keys);
  73. }
  74. extern int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg);
  75. extern int ptrauth_set_enabled_keys(struct task_struct *tsk, unsigned long keys,
  76. unsigned long enabled);
  77. extern int ptrauth_get_enabled_keys(struct task_struct *tsk);
  78. static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr)
  79. {
  80. return ptrauth_clear_pac(ptr);
  81. }
  82. static __always_inline void ptrauth_enable(void)
  83. {
  84. if (!system_supports_address_auth())
  85. return;
  86. sysreg_clear_set(sctlr_el1, 0, (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB |
  87. SCTLR_ELx_ENDA | SCTLR_ELx_ENDB));
  88. isb();
  89. }
  90. #define ptrauth_suspend_exit() \
  91. ptrauth_keys_install_user(&current->thread.keys_user)
  92. #define ptrauth_thread_init_user() \
  93. do { \
  94. ptrauth_keys_init_user(&current->thread.keys_user); \
  95. \
  96. /* enable all keys */ \
  97. if (system_supports_address_auth()) \
  98. set_task_sctlr_el1(current->thread.sctlr_user | \
  99. SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
  100. SCTLR_ELx_ENDA | SCTLR_ELx_ENDB); \
  101. } while (0)
  102. #define ptrauth_thread_switch_user(tsk) \
  103. ptrauth_keys_install_user(&(tsk)->thread.keys_user)
  104. #else /* CONFIG_ARM64_PTR_AUTH */
  105. #define ptrauth_enable()
  106. #define ptrauth_prctl_reset_keys(tsk, arg) (-EINVAL)
  107. #define ptrauth_set_enabled_keys(tsk, keys, enabled) (-EINVAL)
  108. #define ptrauth_get_enabled_keys(tsk) (-EINVAL)
  109. #define ptrauth_strip_insn_pac(lr) (lr)
  110. #define ptrauth_suspend_exit()
  111. #define ptrauth_thread_init_user()
  112. #define ptrauth_thread_switch_user(tsk)
  113. #endif /* CONFIG_ARM64_PTR_AUTH */
  114. #ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
  115. #define ptrauth_thread_init_kernel(tsk) \
  116. ptrauth_keys_init_kernel(&(tsk)->thread.keys_kernel)
  117. #define ptrauth_thread_switch_kernel(tsk) \
  118. ptrauth_keys_switch_kernel(&(tsk)->thread.keys_kernel)
  119. #else
  120. #define ptrauth_thread_init_kernel(tsk)
  121. #define ptrauth_thread_switch_kernel(tsk)
  122. #endif /* CONFIG_ARM64_PTR_AUTH_KERNEL */
  123. #define PR_PAC_ENABLED_KEYS_MASK \
  124. (PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY)
  125. #endif /* __ASM_POINTER_AUTH_H */