| @@ -979,6 +979,131 @@ static int pac_mask_get(struct task_struct *target, · 978 unmodified lines |
| 979 | | 979 | |
| 980 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &uregs, 0, -1); | 980 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &uregs, 0, -1); |
| 981 | } | 981 | } |
| | 982 | |
| | 983 | #ifdef CONFIG_CHECKPOINT_RESTORE |
| | 984 | static __uint128_t pac_key_to_user(const struct ptrauth_key *key) |
| | 985 | { |
| | 986 | return (__uint128_t)key->hi << 64 | key->lo; |
| | 987 | } |
| | 988 | |
| | 989 | static struct ptrauth_key pac_key_from_user(__uint128_t ukey) |
| | 990 | { |
| | 991 | struct ptrauth_key key = { |
| | 992 | .lo = (unsigned long)ukey, |
| | 993 | .hi = (unsigned long)(ukey >> 64), |
| | 994 | }; |
| | 995 | |
| | 996 | return key; |
| | 997 | } |
| | 998 | |
| | 999 | static void pac_address_keys_to_user(struct user_pac_address_keys *ukeys, |
| | 1000 | const struct ptrauth_keys *keys) |
| | 1001 | { |
| | 1002 | ukeys->apiakey = pac_key_to_user(&keys->apia); |
| | 1003 | ukeys->apibkey = pac_key_to_user(&keys->apib); |
| | 1004 | ukeys->apdakey = pac_key_to_user(&keys->apda); |
| | 1005 | ukeys->apdbkey = pac_key_to_user(&keys->apdb); |
| | 1006 | } |
| | 1007 | |
| | 1008 | static void pac_address_keys_from_user(struct ptrauth_keys *keys, |
| | 1009 | const struct user_pac_address_keys *ukeys) |
| | 1010 | { |
| | 1011 | keys->apia = pac_key_from_user(ukeys->apiakey); |
| | 1012 | keys->apib = pac_key_from_user(ukeys->apibkey); |
| | 1013 | keys->apda = pac_key_from_user(ukeys->apdakey); |
| | 1014 | keys->apdb = pac_key_from_user(ukeys->apdbkey); |
| | 1015 | } |
| | 1016 | |
| | 1017 | static int pac_address_keys_get(struct task_struct *target, |
| | 1018 | const struct user_regset *regset, |
| | 1019 | unsigned int pos, unsigned int count, |
| | 1020 | void *kbuf, void __user *ubuf) |
| | 1021 | { |
| | 1022 | struct ptrauth_keys *keys = &target->thread.keys_user; |
| | 1023 | struct user_pac_address_keys user_keys; |
| | 1024 | |
| | 1025 | if (!system_supports_address_auth()) |
| | 1026 | return -EINVAL; |
| | 1027 | |
| | 1028 | pac_address_keys_to_user(&user_keys, keys); |
| | 1029 | |
| | 1030 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
| | 1031 | &user_keys, 0, -1); |
| | 1032 | } |
| | 1033 | |
| | 1034 | static int pac_address_keys_set(struct task_struct *target, |
| | 1035 | const struct user_regset *regset, |
| | 1036 | unsigned int pos, unsigned int count, |
| | 1037 | const void *kbuf, const void __user *ubuf) |
| | 1038 | { |
| | 1039 | struct ptrauth_keys *keys = &target->thread.keys_user; |
| | 1040 | struct user_pac_address_keys user_keys; |
| | 1041 | int ret; |
| | 1042 | |
| | 1043 | if (!system_supports_address_auth()) |
| | 1044 | return -EINVAL; |
| | 1045 | |
| | 1046 | pac_address_keys_to_user(&user_keys, keys); |
| | 1047 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
| | 1048 | &user_keys, 0, -1); |
| | 1049 | if (ret) |
| | 1050 | return ret; |
| | 1051 | pac_address_keys_from_user(keys, &user_keys); |
| | 1052 | |
| | 1053 | return 0; |
| | 1054 | } |
| | 1055 | |
| | 1056 | static void pac_generic_keys_to_user(struct user_pac_generic_keys *ukeys, |
| | 1057 | const struct ptrauth_keys *keys) |
| | 1058 | { |
| | 1059 | ukeys->apgakey = pac_key_to_user(&keys->apga); |
| | 1060 | } |
| | 1061 | |
| | 1062 | static void pac_generic_keys_from_user(struct ptrauth_keys *keys, |
| | 1063 | const struct user_pac_generic_keys *ukeys) |
| | 1064 | { |
| | 1065 | keys->apga = pac_key_from_user(ukeys->apgakey); |
| | 1066 | } |
| | 1067 | |
| | 1068 | static int pac_generic_keys_get(struct task_struct *target, |
| | 1069 | const struct user_regset *regset, |
| | 1070 | unsigned int pos, unsigned int count, |
| | 1071 | void *kbuf, void __user *ubuf) |
| | 1072 | { |
| | 1073 | struct ptrauth_keys *keys = &target->thread.keys_user; |
| | 1074 | struct user_pac_generic_keys user_keys; |
| | 1075 | |
| | 1076 | if (!system_supports_generic_auth()) |
| | 1077 | return -EINVAL; |
| | 1078 | |
| | 1079 | pac_generic_keys_to_user(&user_keys, keys); |
| | 1080 | |
| | 1081 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
| | 1082 | &user_keys, 0, -1); |
| | 1083 | } |
| | 1084 | |
| | 1085 | static int pac_generic_keys_set(struct task_struct *target, |
| | 1086 | const struct user_regset *regset, |
| | 1087 | unsigned int pos, unsigned int count, |
| | 1088 | const void *kbuf, const void __user *ubuf) |
| | 1089 | { |
| | 1090 | struct ptrauth_keys *keys = &target->thread.keys_user; |
| | 1091 | struct user_pac_generic_keys user_keys; |
| | 1092 | int ret; |
| | 1093 | |
| | 1094 | if (!system_supports_generic_auth()) |
| | 1095 | return -EINVAL; |
| | 1096 | |
| | 1097 | pac_generic_keys_to_user(&user_keys, keys); |
| | 1098 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
| | 1099 | &user_keys, 0, -1); |
| | 1100 | if (ret) |
| | 1101 | return ret; |
| | 1102 | pac_generic_keys_from_user(keys, &user_keys); |
| | 1103 | |
| | 1104 | return 0; |
| | 1105 | } |
| | 1106 | #endif /* CONFIG_CHECKPOINT_RESTORE */ |
| 982 | #endif /* CONFIG_ARM64_PTR_AUTH */ | 1107 | #endif /* CONFIG_ARM64_PTR_AUTH */ |
| 983 | | 1108 | |
| 984 | enum aarch64_regset { | 1109 | enum aarch64_regset { |
| @@ -995,6 +1120,10 @@ enum aarch64_regset { · 10 unmodified lines |
| 995 | #endif | 1120 | #endif |
| 996 | #ifdef CONFIG_ARM64_PTR_AUTH | 1121 | #ifdef CONFIG_ARM64_PTR_AUTH |
| 997 | REGSET_PAC_MASK, | 1122 | REGSET_PAC_MASK, |
| | 1123 | #ifdef CONFIG_CHECKPOINT_RESTORE |
| | 1124 | REGSET_PACA_KEYS, |
| | 1125 | REGSET_PACG_KEYS, |
| | 1126 | #endif |
| 998 | #endif | 1127 | #endif |
| 999 | }; | 1128 | }; |
| 1000 | | 1129 | |
| @@ -1074,6 +1203,24 @@ static const struct user_regset aarch64_regsets[] = { · 73 unmodified lines |
| 1074 | .get = pac_mask_get, | 1203 | .get = pac_mask_get, |
| 1075 | /* this cannot be set dynamically */ | 1204 | /* this cannot be set dynamically */ |
| 1076 | }, | 1205 | }, |
| | 1206 | #ifdef CONFIG_CHECKPOINT_RESTORE |
| | 1207 | [REGSET_PACA_KEYS] = { |
| | 1208 | .core_note_type = NT_ARM_PACA_KEYS, |
| | 1209 | .n = sizeof(struct user_pac_address_keys) / sizeof(__uint128_t), |
| | 1210 | .size = sizeof(__uint128_t), |
| | 1211 | .align = sizeof(__uint128_t), |
| | 1212 | .get = pac_address_keys_get, |
| | 1213 | .set = pac_address_keys_set, |
| | 1214 | }, |
| | 1215 | [REGSET_PACG_KEYS] = { |
| | 1216 | .core_note_type = NT_ARM_PACG_KEYS, |
| | 1217 | .n = sizeof(struct user_pac_generic_keys) / sizeof(__uint128_t), |
| | 1218 | .size = sizeof(__uint128_t), |
| | 1219 | .align = sizeof(__uint128_t), |
| | 1220 | .get = pac_generic_keys_get, |
| | 1221 | .set = pac_generic_keys_set, |
| | 1222 | }, |
| | 1223 | #endif |
| 1077 | #endif | 1224 | #endif |
| 1078 | }; | 1225 | }; |
| 1079 | | 1226 | |