Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fscrypt: allow unprivileged users to add/remove keys for v2 policies

Allow the FS_IOC_ADD_ENCRYPTION_KEY and FS_IOC_REMOVE_ENCRYPTION_KEY
ioctls to be used by non-root users to add and remove encryption keys
from the filesystem-level crypto keyrings, subject to limitations.

Motivation: while privileged fscrypt key management is sufficient for
some users (e.g. Android and Chromium OS, where a privileged process
manages all keys), the old API by design also allows non-root users to
set up and use encrypted directories, and we don't want to regress on
that. Especially, we don't want to force users to continue using the
old API, running into the visibility mismatch between files and keyrings
and being unable to "lock" encrypted directories.

Intuitively, the ioctls have to be privileged since they manipulate
filesystem-level state. However, it's actually safe to make them
unprivileged if we very carefully enforce some specific limitations.

First, each key must be identified by a cryptographic hash so that a
user can't add the wrong key for another user's files. For v2
encryption policies, we use the key_identifier for this. v1 policies
don't have this, so managing keys for them remains privileged.

Second, each key a user adds is charged to their quota for the keyrings
service. Thus, a user can't exhaust memory by adding a huge number of
keys. By default each non-root user is allowed up to 200 keys; this can
be changed using the existing sysctl 'kernel.keys.maxkeys'.

Third, if multiple users add the same key, we keep track of those users
of the key (of which there remains a single copy), and won't really
remove the key, i.e. "lock" the encrypted files, until all those users
have removed it. This prevents denial of service attacks that would be
possible under simpler schemes, such allowing the first user who added a
key to remove it -- since that could be a malicious user who has
compromised the key. Of course, encryption keys should be kept secret,
but the idea is that using encryption should never be *less* secure than
not using encryption, even if your key was compromised.

We tolerate that a user will be unable to really remove a key, i.e.
unable to "lock" their encrypted files, if another user has added the
same key. But in a sense, this is actually a good thing because it will
avoid providing a false notion of security where a key appears to have
been removed when actually it's still in memory, available to any
attacker who compromises the operating system kernel.

Reviewed-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Eric Biggers <ebiggers@google.com>

+341 -34
+27 -4
fs/crypto/fscrypt_private.h
··· 335 335 * FS_IOC_REMOVE_ENCRYPTION_KEY can be retried, or 336 336 * FS_IOC_ADD_ENCRYPTION_KEY can add the secret again. 337 337 * 338 - * Locking: protected by key->sem. 338 + * Locking: protected by key->sem (outer) and mk_secret_sem (inner). 339 + * The reason for two locks is that key->sem also protects modifying 340 + * mk_users, which ranks it above the semaphore for the keyring key 341 + * type, which is in turn above page faults (via keyring_read). But 342 + * sometimes filesystems call fscrypt_get_encryption_info() from within 343 + * a transaction, which ranks it below page faults. So we need a 344 + * separate lock which protects mk_secret but not also mk_users. 339 345 */ 340 346 struct fscrypt_master_key_secret mk_secret; 347 + struct rw_semaphore mk_secret_sem; 341 348 342 349 /* 343 350 * For v1 policy keys: an arbitrary key descriptor which was assigned by ··· 353 346 * For v2 policy keys: a cryptographic hash of this key (->identifier). 354 347 */ 355 348 struct fscrypt_key_specifier mk_spec; 349 + 350 + /* 351 + * Keyring which contains a key of type 'key_type_fscrypt_user' for each 352 + * user who has added this key. Normally each key will be added by just 353 + * one user, but it's possible that multiple users share a key, and in 354 + * that case we need to keep track of those users so that one user can't 355 + * remove the key before the others want it removed too. 356 + * 357 + * This is NULL for v1 policy keys; those can only be added by root. 358 + * 359 + * Locking: in addition to this keyrings own semaphore, this is 360 + * protected by the master key's key->sem, so we can do atomic 361 + * search+insert. It can also be searched without taking any locks, but 362 + * in that case the returned key may have already been removed. 363 + */ 364 + struct key *mk_users; 356 365 357 366 /* 358 367 * Length of ->mk_decrypted_inodes, plus one if mk_secret is present. ··· 397 374 /* 398 375 * The READ_ONCE() is only necessary for fscrypt_drop_inode() and 399 376 * fscrypt_key_describe(). These run in atomic context, so they can't 400 - * take key->sem and thus 'secret' can change concurrently which would 401 - * be a data race. But they only need to know whether the secret *was* 402 - * present at the time of check, so READ_ONCE() suffices. 377 + * take ->mk_secret_sem and thus 'secret' can change concurrently which 378 + * would be a data race. But they only need to know whether the secret 379 + * *was* present at the time of check, so READ_ONCE() suffices. 403 380 */ 404 381 return READ_ONCE(secret->size) != 0; 405 382 }
+299 -21
fs/crypto/keyring.c
··· 45 45 for (i = 0; i < ARRAY_SIZE(mk->mk_mode_keys); i++) 46 46 crypto_free_skcipher(mk->mk_mode_keys[i]); 47 47 48 + key_put(mk->mk_users); 48 49 kzfree(mk); 49 50 } 50 51 ··· 94 93 .describe = fscrypt_key_describe, 95 94 }; 96 95 97 - /* Search ->s_master_keys */ 96 + static int fscrypt_user_key_instantiate(struct key *key, 97 + struct key_preparsed_payload *prep) 98 + { 99 + /* 100 + * We just charge FSCRYPT_MAX_KEY_SIZE bytes to the user's key quota for 101 + * each key, regardless of the exact key size. The amount of memory 102 + * actually used is greater than the size of the raw key anyway. 103 + */ 104 + return key_payload_reserve(key, FSCRYPT_MAX_KEY_SIZE); 105 + } 106 + 107 + static void fscrypt_user_key_describe(const struct key *key, struct seq_file *m) 108 + { 109 + seq_puts(m, key->description); 110 + } 111 + 112 + /* 113 + * Type of key in ->mk_users. Each key of this type represents a particular 114 + * user who has added a particular master key. 115 + * 116 + * Note that the name of this key type really should be something like 117 + * ".fscrypt-user" instead of simply ".fscrypt". But the shorter name is chosen 118 + * mainly for simplicity of presentation in /proc/keys when read by a non-root 119 + * user. And it is expected to be rare that a key is actually added by multiple 120 + * users, since users should keep their encryption keys confidential. 121 + */ 122 + static struct key_type key_type_fscrypt_user = { 123 + .name = ".fscrypt", 124 + .instantiate = fscrypt_user_key_instantiate, 125 + .describe = fscrypt_user_key_describe, 126 + }; 127 + 128 + /* Search ->s_master_keys or ->mk_users */ 98 129 static struct key *search_fscrypt_keyring(struct key *keyring, 99 130 struct key_type *type, 100 131 const char *description) ··· 152 119 153 120 #define FSCRYPT_MK_DESCRIPTION_SIZE (2 * FSCRYPT_KEY_IDENTIFIER_SIZE + 1) 154 121 122 + #define FSCRYPT_MK_USERS_DESCRIPTION_SIZE \ 123 + (CONST_STRLEN("fscrypt-") + 2 * FSCRYPT_KEY_IDENTIFIER_SIZE + \ 124 + CONST_STRLEN("-users") + 1) 125 + 126 + #define FSCRYPT_MK_USER_DESCRIPTION_SIZE \ 127 + (2 * FSCRYPT_KEY_IDENTIFIER_SIZE + CONST_STRLEN(".uid.") + 10 + 1) 128 + 155 129 static void format_fs_keyring_description( 156 130 char description[FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE], 157 131 const struct super_block *sb) ··· 172 132 { 173 133 sprintf(description, "%*phN", 174 134 master_key_spec_len(mk_spec), (u8 *)&mk_spec->u); 135 + } 136 + 137 + static void format_mk_users_keyring_description( 138 + char description[FSCRYPT_MK_USERS_DESCRIPTION_SIZE], 139 + const u8 mk_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) 140 + { 141 + sprintf(description, "fscrypt-%*phN-users", 142 + FSCRYPT_KEY_IDENTIFIER_SIZE, mk_identifier); 143 + } 144 + 145 + static void format_mk_user_description( 146 + char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE], 147 + const u8 mk_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE]) 148 + { 149 + 150 + sprintf(description, "%*phN.uid.%u", FSCRYPT_KEY_IDENTIFIER_SIZE, 151 + mk_identifier, __kuid_val(current_fsuid())); 175 152 } 176 153 177 154 /* Create ->s_master_keys if needed. Synchronized by fscrypt_add_key_mutex. */ ··· 238 181 return search_fscrypt_keyring(keyring, &key_type_fscrypt, description); 239 182 } 240 183 184 + static int allocate_master_key_users_keyring(struct fscrypt_master_key *mk) 185 + { 186 + char description[FSCRYPT_MK_USERS_DESCRIPTION_SIZE]; 187 + struct key *keyring; 188 + 189 + format_mk_users_keyring_description(description, 190 + mk->mk_spec.u.identifier); 191 + keyring = keyring_alloc(description, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, 192 + current_cred(), KEY_POS_SEARCH | 193 + KEY_USR_SEARCH | KEY_USR_READ | KEY_USR_VIEW, 194 + KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); 195 + if (IS_ERR(keyring)) 196 + return PTR_ERR(keyring); 197 + 198 + mk->mk_users = keyring; 199 + return 0; 200 + } 201 + 202 + /* 203 + * Find the current user's "key" in the master key's ->mk_users. 204 + * Returns ERR_PTR(-ENOKEY) if not found. 205 + */ 206 + static struct key *find_master_key_user(struct fscrypt_master_key *mk) 207 + { 208 + char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE]; 209 + 210 + format_mk_user_description(description, mk->mk_spec.u.identifier); 211 + return search_fscrypt_keyring(mk->mk_users, &key_type_fscrypt_user, 212 + description); 213 + } 214 + 215 + /* 216 + * Give the current user a "key" in ->mk_users. This charges the user's quota 217 + * and marks the master key as added by the current user, so that it cannot be 218 + * removed by another user with the key. Either the master key's key->sem must 219 + * be held for write, or the master key must be still undergoing initialization. 220 + */ 221 + static int add_master_key_user(struct fscrypt_master_key *mk) 222 + { 223 + char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE]; 224 + struct key *mk_user; 225 + int err; 226 + 227 + format_mk_user_description(description, mk->mk_spec.u.identifier); 228 + mk_user = key_alloc(&key_type_fscrypt_user, description, 229 + current_fsuid(), current_gid(), current_cred(), 230 + KEY_POS_SEARCH | KEY_USR_VIEW, 0, NULL); 231 + if (IS_ERR(mk_user)) 232 + return PTR_ERR(mk_user); 233 + 234 + err = key_instantiate_and_link(mk_user, NULL, 0, mk->mk_users, NULL); 235 + key_put(mk_user); 236 + return err; 237 + } 238 + 239 + /* 240 + * Remove the current user's "key" from ->mk_users. 241 + * The master key's key->sem must be held for write. 242 + * 243 + * Returns 0 if removed, -ENOKEY if not found, or another -errno code. 244 + */ 245 + static int remove_master_key_user(struct fscrypt_master_key *mk) 246 + { 247 + struct key *mk_user; 248 + int err; 249 + 250 + mk_user = find_master_key_user(mk); 251 + if (IS_ERR(mk_user)) 252 + return PTR_ERR(mk_user); 253 + err = key_unlink(mk->mk_users, mk_user); 254 + key_put(mk_user); 255 + return err; 256 + } 257 + 241 258 /* 242 259 * Allocate a new fscrypt_master_key which contains the given secret, set it as 243 260 * the payload of a new 'struct key' of type fscrypt, and link the 'struct key' ··· 333 202 mk->mk_spec = *mk_spec; 334 203 335 204 move_master_key_secret(&mk->mk_secret, secret); 205 + init_rwsem(&mk->mk_secret_sem); 336 206 337 207 refcount_set(&mk->mk_refcount, 1); /* secret is present */ 338 208 INIT_LIST_HEAD(&mk->mk_decrypted_inodes); 339 209 spin_lock_init(&mk->mk_decrypted_inodes_lock); 340 210 211 + if (mk_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) { 212 + err = allocate_master_key_users_keyring(mk); 213 + if (err) 214 + goto out_free_mk; 215 + err = add_master_key_user(mk); 216 + if (err) 217 + goto out_free_mk; 218 + } 219 + 220 + /* 221 + * Note that we don't charge this key to anyone's quota, since when 222 + * ->mk_users is in use those keys are charged instead, and otherwise 223 + * (when ->mk_users isn't in use) only root can add these keys. 224 + */ 341 225 format_mk_description(description, mk_spec); 342 226 key = key_alloc(&key_type_fscrypt, description, 343 227 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(), ··· 379 233 static int add_existing_master_key(struct fscrypt_master_key *mk, 380 234 struct fscrypt_master_key_secret *secret) 381 235 { 382 - if (is_master_key_secret_present(&mk->mk_secret)) 383 - return 0; 236 + struct key *mk_user; 237 + bool rekey; 238 + int err; 384 239 385 - if (!refcount_inc_not_zero(&mk->mk_refcount)) 240 + /* 241 + * If the current user is already in ->mk_users, then there's nothing to 242 + * do. (Not applicable for v1 policy keys, which have NULL ->mk_users.) 243 + */ 244 + if (mk->mk_users) { 245 + mk_user = find_master_key_user(mk); 246 + if (mk_user != ERR_PTR(-ENOKEY)) { 247 + if (IS_ERR(mk_user)) 248 + return PTR_ERR(mk_user); 249 + key_put(mk_user); 250 + return 0; 251 + } 252 + } 253 + 254 + /* If we'll be re-adding ->mk_secret, try to take the reference. */ 255 + rekey = !is_master_key_secret_present(&mk->mk_secret); 256 + if (rekey && !refcount_inc_not_zero(&mk->mk_refcount)) 386 257 return KEY_DEAD; 387 258 388 - move_master_key_secret(&mk->mk_secret, secret); 259 + /* Add the current user to ->mk_users, if applicable. */ 260 + if (mk->mk_users) { 261 + err = add_master_key_user(mk); 262 + if (err) { 263 + if (rekey && refcount_dec_and_test(&mk->mk_refcount)) 264 + return KEY_DEAD; 265 + return err; 266 + } 267 + } 268 + 269 + /* Re-add the secret if needed. */ 270 + if (rekey) { 271 + down_write(&mk->mk_secret_sem); 272 + move_master_key_secret(&mk->mk_secret, secret); 273 + up_write(&mk->mk_secret_sem); 274 + } 389 275 return 0; 390 276 } 391 277 ··· 444 266 } else { 445 267 /* 446 268 * Found the key in ->s_master_keys. Re-add the secret if 447 - * needed. 269 + * needed, and add the user to ->mk_users if needed. 448 270 */ 449 271 down_write(&key->sem); 450 272 err = add_existing_master_key(key->payload.data[0], secret); ··· 465 287 /* 466 288 * Add a master encryption key to the filesystem, causing all files which were 467 289 * encrypted with it to appear "unlocked" (decrypted) when accessed. 290 + * 291 + * When adding a key for use by v1 encryption policies, this ioctl is 292 + * privileged, and userspace must provide the 'key_descriptor'. 293 + * 294 + * When adding a key for use by v2+ encryption policies, this ioctl is 295 + * unprivileged. This is needed, in general, to allow non-root users to use 296 + * encryption without encountering the visibility problems of process-subscribed 297 + * keyrings and the inability to properly remove keys. This works by having 298 + * each key identified by its cryptographically secure hash --- the 299 + * 'key_identifier'. The cryptographic hash ensures that a malicious user 300 + * cannot add the wrong key for a given identifier. Furthermore, each added key 301 + * is charged to the appropriate user's quota for the keyrings service, which 302 + * prevents a malicious user from adding too many keys. Finally, we forbid a 303 + * user from removing a key while other users have added it too, which prevents 304 + * a user who knows another user's key from causing a denial-of-service by 305 + * removing it at an inopportune time. (We tolerate that a user who knows a key 306 + * can prevent other users from removing it.) 468 307 * 469 308 * For more details, see the "FS_IOC_ADD_ENCRYPTION_KEY" section of 470 309 * Documentation/filesystems/fscrypt.rst. ··· 513 318 if (copy_from_user(secret.raw, uarg->raw, secret.size)) 514 319 goto out_wipe_secret; 515 320 516 - err = -EACCES; 517 - if (!capable(CAP_SYS_ADMIN)) 518 - goto out_wipe_secret; 519 - 520 - if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) { 321 + switch (arg.key_spec.type) { 322 + case FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR: 323 + /* 324 + * Only root can add keys that are identified by an arbitrary 325 + * descriptor rather than by a cryptographic hash --- since 326 + * otherwise a malicious user could add the wrong key. 327 + */ 328 + err = -EACCES; 329 + if (!capable(CAP_SYS_ADMIN)) 330 + goto out_wipe_secret; 331 + break; 332 + case FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER: 521 333 err = fscrypt_init_hkdf(&secret.hkdf, secret.raw, secret.size); 522 334 if (err) 523 335 goto out_wipe_secret; ··· 547 345 arg.key_spec.u.identifier, 548 346 FSCRYPT_KEY_IDENTIFIER_SIZE)) 549 347 goto out_wipe_secret; 348 + break; 349 + default: 350 + WARN_ON(1); 351 + err = -EINVAL; 352 + goto out_wipe_secret; 550 353 } 551 354 552 355 err = add_master_key(sb, &secret, &arg.key_spec); ··· 699 492 /* 700 493 * Try to remove an fscrypt master encryption key. 701 494 * 702 - * First we wipe the actual master key secret, so that no more inodes can be 703 - * unlocked with it. Then we try to evict all cached inodes that had been 704 - * unlocked with the key. 495 + * This removes the current user's claim to the key, then removes the key itself 496 + * if no other users have claims. 497 + * 498 + * To "remove the key itself", first we wipe the actual master key secret, so 499 + * that no more inodes can be unlocked with it. Then we try to evict all cached 500 + * inodes that had been unlocked with the key. 705 501 * 706 502 * If all inodes were evicted, then we unlink the fscrypt_master_key from the 707 503 * keyring. Otherwise it remains in the keyring in the "incompletely removed" ··· 735 525 if (memchr_inv(arg.__reserved, 0, sizeof(arg.__reserved))) 736 526 return -EINVAL; 737 527 738 - if (!capable(CAP_SYS_ADMIN)) 528 + /* 529 + * Only root can add and remove keys that are identified by an arbitrary 530 + * descriptor rather than by a cryptographic hash. 531 + */ 532 + if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR && 533 + !capable(CAP_SYS_ADMIN)) 739 534 return -EACCES; 740 535 741 536 /* Find the key being removed. */ ··· 751 536 752 537 down_write(&key->sem); 753 538 754 - /* Wipe the secret. */ 539 + /* If relevant, remove current user's claim to the key */ 540 + if (mk->mk_users && mk->mk_users->keys.nr_leaves_on_tree != 0) { 541 + err = remove_master_key_user(mk); 542 + if (err) { 543 + up_write(&key->sem); 544 + goto out_put_key; 545 + } 546 + if (mk->mk_users->keys.nr_leaves_on_tree != 0) { 547 + /* 548 + * Other users have still added the key too. We removed 549 + * the current user's claim to the key, but we still 550 + * can't remove the key itself. 551 + */ 552 + status_flags |= 553 + FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS; 554 + err = 0; 555 + up_write(&key->sem); 556 + goto out_put_key; 557 + } 558 + } 559 + 560 + /* No user claims remaining. Go ahead and wipe the secret. */ 755 561 dead = false; 756 562 if (is_master_key_secret_present(&mk->mk_secret)) { 563 + down_write(&mk->mk_secret_sem); 757 564 wipe_master_key_secret(&mk->mk_secret); 758 565 dead = refcount_dec_and_test(&mk->mk_refcount); 566 + up_write(&mk->mk_secret_sem); 759 567 } 760 568 up_write(&key->sem); 761 569 if (dead) { ··· 798 560 } 799 561 } 800 562 /* 801 - * We return 0 if we successfully did something: wiped the secret, or 802 - * tried locking the files again. Users need to check the informational 803 - * status flags if they care whether the key has been fully removed 804 - * including all files locked. 563 + * We return 0 if we successfully did something: removed a claim to the 564 + * key, wiped the secret, or tried locking the files again. Users need 565 + * to check the informational status flags if they care whether the key 566 + * has been fully removed including all files locked. 805 567 */ 568 + out_put_key: 806 569 key_put(key); 807 570 if (err == 0) 808 571 err = put_user(status_flags, &uarg->removal_status_flags); ··· 821 582 * of an encrypted directory without using a hack such as trying to open a 822 583 * regular file in it (which can confuse the "incompletely removed" state with 823 584 * absent or present). 585 + * 586 + * In addition, for v2 policy keys we allow applications to determine, via 587 + * ->status_flags and ->user_count, whether the key has been added by the 588 + * current user, by other users, or by both. Most applications should not need 589 + * this, since ordinarily only one user should know a given key. However, if a 590 + * secret key is shared by multiple users, applications may wish to add an 591 + * already-present key to prevent other users from removing it. This ioctl can 592 + * be used to check whether that really is the case before the work is done to 593 + * add the key --- which might e.g. require prompting the user for a passphrase. 824 594 * 825 595 * For more details, see the "FS_IOC_GET_ENCRYPTION_KEY_STATUS" section of 826 596 * Documentation/filesystems/fscrypt.rst. ··· 851 603 if (memchr_inv(arg.__reserved, 0, sizeof(arg.__reserved))) 852 604 return -EINVAL; 853 605 606 + arg.status_flags = 0; 607 + arg.user_count = 0; 854 608 memset(arg.__out_reserved, 0, sizeof(arg.__out_reserved)); 855 609 856 610 key = fscrypt_find_master_key(sb, &arg.key_spec); ··· 873 623 } 874 624 875 625 arg.status = FSCRYPT_KEY_STATUS_PRESENT; 626 + if (mk->mk_users) { 627 + struct key *mk_user; 628 + 629 + arg.user_count = mk->mk_users->keys.nr_leaves_on_tree; 630 + mk_user = find_master_key_user(mk); 631 + if (!IS_ERR(mk_user)) { 632 + arg.status_flags |= 633 + FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF; 634 + key_put(mk_user); 635 + } else if (mk_user != ERR_PTR(-ENOKEY)) { 636 + err = PTR_ERR(mk_user); 637 + goto out_release_key; 638 + } 639 + } 876 640 err = 0; 877 641 out_release_key: 878 642 up_read(&key->sem); ··· 900 636 901 637 int __init fscrypt_init_keyring(void) 902 638 { 903 - return register_key_type(&key_type_fscrypt); 639 + int err; 640 + 641 + err = register_key_type(&key_type_fscrypt); 642 + if (err) 643 + return err; 644 + 645 + err = register_key_type(&key_type_fscrypt_user); 646 + if (err) 647 + goto err_unregister_fscrypt; 648 + 649 + return 0; 650 + 651 + err_unregister_fscrypt: 652 + unregister_key_type(&key_type_fscrypt); 653 + return err; 904 654 }
+10 -8
fs/crypto/keysetup.c
··· 286 286 * 287 287 * If the master key is found in the filesystem-level keyring, then the 288 288 * corresponding 'struct key' is returned in *master_key_ret with 289 - * ->sem read-locked. This is needed to ensure that only one task links the 290 - * fscrypt_info into ->mk_decrypted_inodes (as multiple tasks may race to create 291 - * an fscrypt_info for the same inode), and to synchronize the master key being 292 - * removed with a new inode starting to use it. 289 + * ->mk_secret_sem read-locked. This is needed to ensure that only one task 290 + * links the fscrypt_info into ->mk_decrypted_inodes (as multiple tasks may race 291 + * to create an fscrypt_info for the same inode), and to synchronize the master 292 + * key being removed with a new inode starting to use it. 293 293 */ 294 294 static int setup_file_encryption_key(struct fscrypt_info *ci, 295 295 struct key **master_key_ret) ··· 333 333 } 334 334 335 335 mk = key->payload.data[0]; 336 - down_read(&key->sem); 336 + down_read(&mk->mk_secret_sem); 337 337 338 338 /* Has the secret been removed (via FS_IOC_REMOVE_ENCRYPTION_KEY)? */ 339 339 if (!is_master_key_secret_present(&mk->mk_secret)) { ··· 376 376 return 0; 377 377 378 378 out_release_key: 379 - up_read(&key->sem); 379 + up_read(&mk->mk_secret_sem); 380 380 key_put(key); 381 381 return err; 382 382 } ··· 514 514 res = 0; 515 515 out: 516 516 if (master_key) { 517 - up_read(&master_key->sem); 517 + struct fscrypt_master_key *mk = master_key->payload.data[0]; 518 + 519 + up_read(&mk->mk_secret_sem); 518 520 key_put(master_key); 519 521 } 520 522 if (res == -ENOKEY) ··· 579 577 mk = ci->ci_master_key->payload.data[0]; 580 578 581 579 /* 582 - * Note: since we aren't holding key->sem, the result here can 580 + * Note: since we aren't holding ->mk_secret_sem, the result here can 583 581 * immediately become outdated. But there's no correctness problem with 584 582 * unnecessarily evicting. Nor is there a correctness problem with not 585 583 * evicting while iput() is racing with the key being removed, since
+5 -1
include/uapi/linux/fscrypt.h
··· 120 120 struct fscrypt_remove_key_arg { 121 121 struct fscrypt_key_specifier key_spec; 122 122 #define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY 0x00000001 123 + #define FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS 0x00000002 123 124 __u32 removal_status_flags; /* output */ 124 125 __u32 __reserved[5]; 125 126 }; ··· 136 135 #define FSCRYPT_KEY_STATUS_PRESENT 2 137 136 #define FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED 3 138 137 __u32 status; 139 - __u32 __out_reserved[15]; 138 + #define FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF 0x00000001 139 + __u32 status_flags; 140 + __u32 user_count; 141 + __u32 __out_reserved[13]; 140 142 }; 141 143 142 144 #define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy)