| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
|---|
| 1 | 2 | /* Authentication token and access key management internal defs |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2003-5, 2007 Red Hat, Inc. All Rights Reserved. |
|---|
| 4 | 5 | * Written by David Howells (dhowells@redhat.com) |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of the GNU General Public License |
|---|
| 8 | | - * as published by the Free Software Foundation; either version |
|---|
| 9 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 10 | 6 | */ |
|---|
| 11 | 7 | |
|---|
| 12 | 8 | #ifndef _INTERNAL_H |
|---|
| .. | .. |
|---|
| 19 | 15 | #include <linux/task_work.h> |
|---|
| 20 | 16 | #include <linux/keyctl.h> |
|---|
| 21 | 17 | #include <linux/refcount.h> |
|---|
| 18 | +#include <linux/watch_queue.h> |
|---|
| 22 | 19 | #include <linux/compat.h> |
|---|
| 23 | 20 | #include <linux/mm.h> |
|---|
| 24 | 21 | #include <linux/vmalloc.h> |
|---|
| .. | .. |
|---|
| 91 | 88 | extern struct mutex key_construction_mutex; |
|---|
| 92 | 89 | extern wait_queue_head_t request_key_conswq; |
|---|
| 93 | 90 | |
|---|
| 94 | | - |
|---|
| 91 | +extern void key_set_index_key(struct keyring_index_key *index_key); |
|---|
| 95 | 92 | extern struct key_type *key_type_lookup(const char *type); |
|---|
| 96 | 93 | extern void key_type_put(struct key_type *ktype); |
|---|
| 97 | 94 | |
|---|
| 95 | +extern int __key_link_lock(struct key *keyring, |
|---|
| 96 | + const struct keyring_index_key *index_key); |
|---|
| 97 | +extern int __key_move_lock(struct key *l_keyring, struct key *u_keyring, |
|---|
| 98 | + const struct keyring_index_key *index_key); |
|---|
| 98 | 99 | extern int __key_link_begin(struct key *keyring, |
|---|
| 99 | 100 | const struct keyring_index_key *index_key, |
|---|
| 100 | 101 | struct assoc_array_edit **_edit); |
|---|
| 101 | 102 | extern int __key_link_check_live_key(struct key *keyring, struct key *key); |
|---|
| 102 | | -extern void __key_link(struct key *key, struct assoc_array_edit **_edit); |
|---|
| 103 | +extern void __key_link(struct key *keyring, struct key *key, |
|---|
| 104 | + struct assoc_array_edit **_edit); |
|---|
| 103 | 105 | extern void __key_link_end(struct key *keyring, |
|---|
| 104 | 106 | const struct keyring_index_key *index_key, |
|---|
| 105 | 107 | struct assoc_array_edit *edit); |
|---|
| .. | .. |
|---|
| 125 | 127 | #define KEYRING_SEARCH_NO_CHECK_PERM 0x0008 /* Don't check permissions */ |
|---|
| 126 | 128 | #define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0010 /* Give an error on excessive depth */ |
|---|
| 127 | 129 | #define KEYRING_SEARCH_SKIP_EXPIRED 0x0020 /* Ignore expired keys (intention to replace) */ |
|---|
| 130 | +#define KEYRING_SEARCH_RECURSE 0x0040 /* Search child keyrings also */ |
|---|
| 128 | 131 | |
|---|
| 129 | 132 | int (*iterator)(const void *object, void *iterator_data); |
|---|
| 130 | 133 | |
|---|
| .. | .. |
|---|
| 137 | 140 | |
|---|
| 138 | 141 | extern bool key_default_cmp(const struct key *key, |
|---|
| 139 | 142 | const struct key_match_data *match_data); |
|---|
| 140 | | -extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, |
|---|
| 143 | +extern key_ref_t keyring_search_rcu(key_ref_t keyring_ref, |
|---|
| 141 | 144 | struct keyring_search_context *ctx); |
|---|
| 142 | 145 | |
|---|
| 143 | | -extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx); |
|---|
| 144 | | -extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx); |
|---|
| 146 | +extern key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx); |
|---|
| 147 | +extern key_ref_t search_process_keyrings_rcu(struct keyring_search_context *ctx); |
|---|
| 145 | 148 | |
|---|
| 146 | 149 | extern struct key *find_keyring_by_name(const char *name, bool uid_keyring); |
|---|
| 147 | 150 | |
|---|
| 148 | | -extern int install_user_keyrings(void); |
|---|
| 151 | +extern int look_up_user_keyrings(struct key **, struct key **); |
|---|
| 152 | +extern struct key *get_user_session_keyring_rcu(const struct cred *); |
|---|
| 149 | 153 | extern int install_thread_keyring_to_cred(struct cred *); |
|---|
| 150 | 154 | extern int install_process_keyring_to_cred(struct cred *); |
|---|
| 151 | 155 | extern int install_session_keyring_to_cred(struct cred *, struct key *); |
|---|
| 152 | 156 | |
|---|
| 153 | 157 | extern struct key *request_key_and_link(struct key_type *type, |
|---|
| 154 | 158 | const char *description, |
|---|
| 159 | + struct key_tag *domain_tag, |
|---|
| 155 | 160 | const void *callout_info, |
|---|
| 156 | 161 | size_t callout_len, |
|---|
| 157 | 162 | void *aux, |
|---|
| .. | .. |
|---|
| 162 | 167 | const struct key_match_data *match_data); |
|---|
| 163 | 168 | #define KEY_LOOKUP_CREATE 0x01 |
|---|
| 164 | 169 | #define KEY_LOOKUP_PARTIAL 0x02 |
|---|
| 165 | | -#define KEY_LOOKUP_FOR_UNLINK 0x04 |
|---|
| 166 | 170 | |
|---|
| 167 | 171 | extern long join_session_keyring(const char *name); |
|---|
| 168 | 172 | extern void key_change_session_keyring(struct callback_head *twork); |
|---|
| .. | .. |
|---|
| 178 | 182 | |
|---|
| 179 | 183 | extern int key_task_permission(const key_ref_t key_ref, |
|---|
| 180 | 184 | const struct cred *cred, |
|---|
| 181 | | - key_perm_t perm); |
|---|
| 185 | + enum key_need_perm need_perm); |
|---|
| 186 | + |
|---|
| 187 | +static inline void notify_key(struct key *key, |
|---|
| 188 | + enum key_notification_subtype subtype, u32 aux) |
|---|
| 189 | +{ |
|---|
| 190 | +#ifdef CONFIG_KEY_NOTIFICATIONS |
|---|
| 191 | + struct key_notification n = { |
|---|
| 192 | + .watch.type = WATCH_TYPE_KEY_NOTIFY, |
|---|
| 193 | + .watch.subtype = subtype, |
|---|
| 194 | + .watch.info = watch_sizeof(n), |
|---|
| 195 | + .key_id = key_serial(key), |
|---|
| 196 | + .aux = aux, |
|---|
| 197 | + }; |
|---|
| 198 | + |
|---|
| 199 | + post_watch_notification(key->watchers, &n.watch, current_cred(), |
|---|
| 200 | + n.key_id); |
|---|
| 201 | +#endif |
|---|
| 202 | +} |
|---|
| 182 | 203 | |
|---|
| 183 | 204 | /* |
|---|
| 184 | 205 | * Check to see whether permission is granted to use a key in the desired way. |
|---|
| 185 | 206 | */ |
|---|
| 186 | | -static inline int key_permission(const key_ref_t key_ref, unsigned perm) |
|---|
| 207 | +static inline int key_permission(const key_ref_t key_ref, |
|---|
| 208 | + enum key_need_perm need_perm) |
|---|
| 187 | 209 | { |
|---|
| 188 | | - return key_task_permission(key_ref, current_cred(), perm); |
|---|
| 210 | + return key_task_permission(key_ref, current_cred(), need_perm); |
|---|
| 189 | 211 | } |
|---|
| 190 | 212 | |
|---|
| 191 | 213 | extern struct key_type key_type_request_key_auth; |
|---|
| .. | .. |
|---|
| 205 | 227 | return |
|---|
| 206 | 228 | key->flags & ((1 << KEY_FLAG_DEAD) | |
|---|
| 207 | 229 | (1 << KEY_FLAG_INVALIDATED)) || |
|---|
| 208 | | - (key->expiry > 0 && key->expiry <= limit); |
|---|
| 230 | + (key->expiry > 0 && key->expiry <= limit) || |
|---|
| 231 | + key->domain_tag->removed; |
|---|
| 209 | 232 | } |
|---|
| 210 | 233 | |
|---|
| 211 | 234 | /* |
|---|
| .. | .. |
|---|
| 217 | 240 | extern long keyctl_revoke_key(key_serial_t); |
|---|
| 218 | 241 | extern long keyctl_keyring_clear(key_serial_t); |
|---|
| 219 | 242 | extern long keyctl_keyring_link(key_serial_t, key_serial_t); |
|---|
| 243 | +extern long keyctl_keyring_move(key_serial_t, key_serial_t, key_serial_t, unsigned int); |
|---|
| 220 | 244 | extern long keyctl_keyring_unlink(key_serial_t, key_serial_t); |
|---|
| 221 | 245 | extern long keyctl_describe_key(key_serial_t, char __user *, size_t); |
|---|
| 222 | 246 | extern long keyctl_keyring_search(key_serial_t, const char __user *, |
|---|
| .. | .. |
|---|
| 238 | 262 | const struct iovec __user *, |
|---|
| 239 | 263 | unsigned, key_serial_t); |
|---|
| 240 | 264 | extern long keyctl_invalidate_key(key_serial_t); |
|---|
| 241 | | - |
|---|
| 242 | | -struct iov_iter; |
|---|
| 243 | | -extern long keyctl_instantiate_key_common(key_serial_t, |
|---|
| 244 | | - struct iov_iter *, |
|---|
| 245 | | - key_serial_t); |
|---|
| 246 | 265 | extern long keyctl_restrict_keyring(key_serial_t id, |
|---|
| 247 | 266 | const char __user *_type, |
|---|
| 248 | 267 | const char __user *_restriction); |
|---|
| .. | .. |
|---|
| 261 | 280 | size_t, struct keyctl_kdf_params __user *); |
|---|
| 262 | 281 | extern long __keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *, |
|---|
| 263 | 282 | size_t, struct keyctl_kdf_params *); |
|---|
| 264 | | -#ifdef CONFIG_KEYS_COMPAT |
|---|
| 283 | +#ifdef CONFIG_COMPAT |
|---|
| 265 | 284 | extern long compat_keyctl_dh_compute(struct keyctl_dh_params __user *params, |
|---|
| 266 | 285 | char __user *buffer, size_t buflen, |
|---|
| 267 | 286 | struct compat_keyctl_kdf_params __user *kdf); |
|---|
| .. | .. |
|---|
| 276 | 295 | return -EOPNOTSUPP; |
|---|
| 277 | 296 | } |
|---|
| 278 | 297 | |
|---|
| 279 | | -#ifdef CONFIG_KEYS_COMPAT |
|---|
| 298 | +#ifdef CONFIG_COMPAT |
|---|
| 280 | 299 | static inline long compat_keyctl_dh_compute( |
|---|
| 281 | 300 | struct keyctl_dh_params __user *params, |
|---|
| 282 | 301 | char __user *buffer, size_t buflen, |
|---|
| .. | .. |
|---|
| 287 | 306 | #endif |
|---|
| 288 | 307 | #endif |
|---|
| 289 | 308 | |
|---|
| 309 | +#ifdef CONFIG_ASYMMETRIC_KEY_TYPE |
|---|
| 310 | +extern long keyctl_pkey_query(key_serial_t, |
|---|
| 311 | + const char __user *, |
|---|
| 312 | + struct keyctl_pkey_query __user *); |
|---|
| 313 | + |
|---|
| 314 | +extern long keyctl_pkey_verify(const struct keyctl_pkey_params __user *, |
|---|
| 315 | + const char __user *, |
|---|
| 316 | + const void __user *, const void __user *); |
|---|
| 317 | + |
|---|
| 318 | +extern long keyctl_pkey_e_d_s(int, |
|---|
| 319 | + const struct keyctl_pkey_params __user *, |
|---|
| 320 | + const char __user *, |
|---|
| 321 | + const void __user *, void __user *); |
|---|
| 322 | +#else |
|---|
| 323 | +static inline long keyctl_pkey_query(key_serial_t id, |
|---|
| 324 | + const char __user *_info, |
|---|
| 325 | + struct keyctl_pkey_query __user *_res) |
|---|
| 326 | +{ |
|---|
| 327 | + return -EOPNOTSUPP; |
|---|
| 328 | +} |
|---|
| 329 | + |
|---|
| 330 | +static inline long keyctl_pkey_verify(const struct keyctl_pkey_params __user *params, |
|---|
| 331 | + const char __user *_info, |
|---|
| 332 | + const void __user *_in, |
|---|
| 333 | + const void __user *_in2) |
|---|
| 334 | +{ |
|---|
| 335 | + return -EOPNOTSUPP; |
|---|
| 336 | +} |
|---|
| 337 | + |
|---|
| 338 | +static inline long keyctl_pkey_e_d_s(int op, |
|---|
| 339 | + const struct keyctl_pkey_params __user *params, |
|---|
| 340 | + const char __user *_info, |
|---|
| 341 | + const void __user *_in, |
|---|
| 342 | + void __user *_out) |
|---|
| 343 | +{ |
|---|
| 344 | + return -EOPNOTSUPP; |
|---|
| 345 | +} |
|---|
| 346 | +#endif |
|---|
| 347 | + |
|---|
| 348 | +extern long keyctl_capabilities(unsigned char __user *_buffer, size_t buflen); |
|---|
| 349 | + |
|---|
| 350 | +#ifdef CONFIG_KEY_NOTIFICATIONS |
|---|
| 351 | +extern long keyctl_watch_key(key_serial_t, int, int); |
|---|
| 352 | +#else |
|---|
| 353 | +static inline long keyctl_watch_key(key_serial_t key_id, int watch_fd, int watch_id) |
|---|
| 354 | +{ |
|---|
| 355 | + return -EOPNOTSUPP; |
|---|
| 356 | +} |
|---|
| 357 | +#endif |
|---|
| 358 | + |
|---|
| 290 | 359 | /* |
|---|
| 291 | 360 | * Debugging key validation |
|---|
| 292 | 361 | */ |
|---|