Pull fscrypt updates from Ted Ts'o: "Clean up fscrypt's dcache revalidation support, and other miscellaneous cleanups" * tag 'fscrypt_for_linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt: fscrypt: cache decrypted symlink target in ->i_link vfs: use READ_ONCE() to access ->i_link fscrypt: fix race where ->lookup() marks plaintext dentry as ciphertext fscrypt: only set dentry_operations on ciphertext dentries fs, fscrypt: clear DCACHE_ENCRYPTED_NAME when unaliasing directory fscrypt: fix race allowing rename() and link() of ciphertext dentries fscrypt: clean up and improve dentry revalidation fscrypt: use READ_ONCE() to access ->i_crypt_info fscrypt: remove WARN_ON_ONCE() when decryption fails fscrypt: drop inode argument from fscrypt_get_ctx()
Showing the changes to include/linux (2 of 18 files). Show all
Unified · Split
| @@ -211,7 +211,7 @@ struct dentry_operations { · 210 unmodified lines | |||
| 211 | 211 | ||
| 212 | #define DCACHE_MAY_FREE 0x00800000 | 212 | #define DCACHE_MAY_FREE 0x00800000 |
| 213 | #define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */ | 213 | #define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */ |
| 214 | #define DCACHE_ENCRYPTED_WITH_KEY 0x02000000 /* dir is encrypted with a valid key */ | 214 | #define DCACHE_ENCRYPTED_NAME 0x02000000 /* Encrypted name (dir key was unavailable) */ |
| 215 | #define DCACHE_OP_REAL 0x04000000 | 215 | #define DCACHE_OP_REAL 0x04000000 |
| 216 | 216 | ||
| 217 | #define DCACHE_PAR_LOOKUP 0x10000000 /* being looked up (with parent locked shared) */ | 217 | #define DCACHE_PAR_LOOKUP 0x10000000 /* being looked up (with parent locked shared) */ |
| @@ -33,6 +33,7 @@ struct fscrypt_name { · 32 unmodified lines | |||
| 33 | u32 hash; | 33 | u32 hash; |
| 34 | u32 minor_hash; | 34 | u32 minor_hash; |
| 35 | struct fscrypt_str crypto_buf; | 35 | struct fscrypt_str crypto_buf; |
| 36 | bool is_ciphertext_name; | ||
| 36 | }; | 37 | }; |
| 37 | 38 | ||
| 38 | #define FSTR_INIT(n, l) { .name = n, .len = l } | 39 | #define FSTR_INIT(n, l) { .name = n, .len = l } |
| @@ -79,7 +80,8 @@ struct fscrypt_ctx { · 40 unmodified lines | |||
| 79 | 80 | ||
| 80 | static inline bool fscrypt_has_encryption_key(const struct inode *inode) | 81 | static inline bool fscrypt_has_encryption_key(const struct inode *inode) |
| 81 | { | 82 | { |
| 82 | return (inode->i_crypt_info != NULL); | 83 | /* pairs with cmpxchg_release() in fscrypt_get_encryption_info() */ |
| 84 | return READ_ONCE(inode->i_crypt_info) != NULL; | ||
| 83 | } | 85 | } |
| 84 | 86 | ||
| 85 | static inline bool fscrypt_dummy_context_enabled(struct inode *inode) | 87 | static inline bool fscrypt_dummy_context_enabled(struct inode *inode) |
| @@ -88,9 +90,21 @@ static inline bool fscrypt_dummy_context_enabled(struct inode *inode) · 2 unmodified lines | |||
| 88 | inode->i_sb->s_cop->dummy_context(inode); | 90 | inode->i_sb->s_cop->dummy_context(inode); |
| 89 | } | 91 | } |
| 90 | 92 | ||
| 93 | /* | ||
| 94 | * When d_splice_alias() moves a directory's encrypted alias to its decrypted | ||
| 95 | * alias as a result of the encryption key being added, DCACHE_ENCRYPTED_NAME | ||
| 96 | * must be cleared. Note that we don't have to support arbitrary moves of this | ||
| 97 | * flag because fscrypt doesn't allow encrypted aliases to be the source or | ||
| 98 | * target of a rename(). | ||
| 99 | */ | ||
| 100 | static inline void fscrypt_handle_d_move(struct dentry *dentry) | ||
| 101 | { | ||
| 102 | dentry->d_flags &= ~DCACHE_ENCRYPTED_NAME; | ||
| 103 | } | ||
| 104 | |||
| 91 | /* crypto.c */ | 105 | /* crypto.c */ |
| 92 | extern void fscrypt_enqueue_decrypt_work(struct work_struct *); | 106 | extern void fscrypt_enqueue_decrypt_work(struct work_struct *); |
| 93 | extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t); | 107 | extern struct fscrypt_ctx *fscrypt_get_ctx(gfp_t); |
| 94 | extern void fscrypt_release_ctx(struct fscrypt_ctx *); | 108 | extern void fscrypt_release_ctx(struct fscrypt_ctx *); |
| 95 | extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *, | 109 | extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *, |
| 96 | unsigned int, unsigned int, | 110 | unsigned int, unsigned int, |
| @@ -114,6 +128,7 @@ extern int fscrypt_inherit_context(struct inode *, struct inode *, · 17 unmodified lines | |||
| 114 | /* keyinfo.c */ | 128 | /* keyinfo.c */ |
| 115 | extern int fscrypt_get_encryption_info(struct inode *); | 129 | extern int fscrypt_get_encryption_info(struct inode *); |
| 116 | extern void fscrypt_put_encryption_info(struct inode *); | 130 | extern void fscrypt_put_encryption_info(struct inode *); |
| 131 | extern void fscrypt_free_inode(struct inode *); | ||
| 117 | 132 | ||
| 118 | /* fname.c */ | 133 | /* fname.c */ |
| 119 | extern int fscrypt_setup_filename(struct inode *, const struct qstr *, | 134 | extern int fscrypt_setup_filename(struct inode *, const struct qstr *, |
| @@ -214,13 +229,15 @@ extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t, · 94 unmodified lines | |||
| 214 | 229 | ||
| 215 | /* hooks.c */ | 230 | /* hooks.c */ |
| 216 | extern int fscrypt_file_open(struct inode *inode, struct file *filp); | 231 | extern int fscrypt_file_open(struct inode *inode, struct file *filp); |
| 217 | extern int __fscrypt_prepare_link(struct inode *inode, struct inode *dir); | 232 | extern int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, |
| 233 | struct dentry *dentry); | ||
| 218 | extern int __fscrypt_prepare_rename(struct inode *old_dir, | 234 | extern int __fscrypt_prepare_rename(struct inode *old_dir, |
| 219 | struct dentry *old_dentry, | 235 | struct dentry *old_dentry, |
| 220 | struct inode *new_dir, | 236 | struct inode *new_dir, |
| 221 | struct dentry *new_dentry, | 237 | struct dentry *new_dentry, |
| 222 | unsigned int flags); | 238 | unsigned int flags); |
| 223 | extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry); | 239 | extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry, |
| 240 | struct fscrypt_name *fname); | ||
| 224 | extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len, | 241 | extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len, |
| 225 | unsigned int max_len, | 242 | unsigned int max_len, |
| 226 | struct fscrypt_str *disk_link); | 243 | struct fscrypt_str *disk_link); |
| @@ -242,13 +259,16 @@ static inline bool fscrypt_dummy_context_enabled(struct inode *inode) · 15 unmodified lines | |||
| 242 | return false; | 259 | return false; |
| 243 | } | 260 | } |
| 244 | 261 | ||
| 262 | static inline void fscrypt_handle_d_move(struct dentry *dentry) | ||
| 263 | { | ||
| 264 | } | ||
| 265 | |||
| 245 | /* crypto.c */ | 266 | /* crypto.c */ |
| 246 | static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work) | 267 | static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work) |
| 247 | { | 268 | { |
| 248 | } | 269 | } |
| 249 | 270 | ||
| 250 | static inline struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode, | 271 | static inline struct fscrypt_ctx *fscrypt_get_ctx(gfp_t gfp_flags) |
| 251 | gfp_t gfp_flags) | ||
| 252 | { | 272 | { |
| 253 | return ERR_PTR(-EOPNOTSUPP); | 273 | return ERR_PTR(-EOPNOTSUPP); |
| 254 | } | 274 | } |
| @@ -322,6 +342,10 @@ static inline void fscrypt_put_encryption_info(struct inode *inode) · 67 unmodified lines | |||
| 322 | return; | 342 | return; |
| 323 | } | 343 | } |
| 324 | 344 | ||
| 345 | static inline void fscrypt_free_inode(struct inode *inode) | ||
| 346 | { | ||
| 347 | } | ||
| 348 | |||
| 325 | /* fname.c */ | 349 | /* fname.c */ |
| 326 | static inline int fscrypt_setup_filename(struct inode *dir, | 350 | static inline int fscrypt_setup_filename(struct inode *dir, |
| 327 | const struct qstr *iname, | 351 | const struct qstr *iname, |
| @@ -330,7 +354,7 @@ static inline int fscrypt_setup_filename(struct inode *dir, · 2 unmodified lines | |||
| 330 | if (IS_ENCRYPTED(dir)) | 354 | if (IS_ENCRYPTED(dir)) |
| 331 | return -EOPNOTSUPP; | 355 | return -EOPNOTSUPP; |
| 332 | 356 | ||
| 333 | memset(fname, 0, sizeof(struct fscrypt_name)); | 357 | memset(fname, 0, sizeof(*fname)); |
| 334 | fname->usr_fname = iname; | 358 | fname->usr_fname = iname; |
| 335 | fname->disk_name.name = (unsigned char *)iname->name; | 359 | fname->disk_name.name = (unsigned char *)iname->name; |
| 336 | fname->disk_name.len = iname->len; | 360 | fname->disk_name.len = iname->len; |
| @@ -401,8 +425,8 @@ static inline int fscrypt_file_open(struct inode *inode, struct file *filp) · 64 unmodified lines | |||
| 401 | return 0; | 425 | return 0; |
| 402 | } | 426 | } |
| 403 | 427 | ||
| 404 | static inline int __fscrypt_prepare_link(struct inode *inode, | 428 | static inline int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, |
| 405 | struct inode *dir) | 429 | struct dentry *dentry) |
| 406 | { | 430 | { |
| 407 | return -EOPNOTSUPP; | 431 | return -EOPNOTSUPP; |
| 408 | } | 432 | } |
| @@ -417,7 +441,8 @@ static inline int __fscrypt_prepare_rename(struct inode *old_dir, · 8 unmodified lines | |||
| 417 | } | 441 | } |
| 418 | 442 | ||
| 419 | static inline int __fscrypt_prepare_lookup(struct inode *dir, | 443 | static inline int __fscrypt_prepare_lookup(struct inode *dir, |
| 420 | struct dentry *dentry) | 444 | struct dentry *dentry, |
| 445 | struct fscrypt_name *fname) | ||
| 421 | { | 446 | { |
| 422 | return -EOPNOTSUPP; | 447 | return -EOPNOTSUPP; |
| 423 | } | 448 | } |
| @@ -497,7 +522,7 @@ static inline int fscrypt_prepare_link(struct dentry *old_dentry, · 73 unmodified lines | |||
| 497 | struct dentry *dentry) | 522 | struct dentry *dentry) |
| 498 | { | 523 | { |
| 499 | if (IS_ENCRYPTED(dir)) | 524 | if (IS_ENCRYPTED(dir)) |
| 500 | return __fscrypt_prepare_link(d_inode(old_dentry), dir); | 525 | return __fscrypt_prepare_link(d_inode(old_dentry), dir, dentry); |
| 501 | return 0; | 526 | return 0; |
| 502 | } | 527 | } |
| 503 | 528 | ||
| @@ -538,27 +563,32 @@ static inline int fscrypt_prepare_rename(struct inode *old_dir, · 34 unmodified lines | |||
| 538 | * fscrypt_prepare_lookup - prepare to lookup a name in a possibly-encrypted directory | 563 | * fscrypt_prepare_lookup - prepare to lookup a name in a possibly-encrypted directory |
| 539 | * @dir: directory being searched | 564 | * @dir: directory being searched |
| 540 | * @dentry: filename being looked up | 565 | * @dentry: filename being looked up |
| 541 | * @flags: lookup flags | 566 | * @fname: (output) the name to use to search the on-disk directory |
| 542 | * | 567 | * |
| 543 | * Prepare for ->lookup() in a directory which may be encrypted. Lookups can be | 568 | * Prepare for ->lookup() in a directory which may be encrypted by determining |
| 544 | * done with or without the directory's encryption key; without the key, | 569 | * the name that will actually be used to search the directory on-disk. Lookups |
| 570 | * can be done with or without the directory's encryption key; without the key, | ||
| 545 | * filenames are presented in encrypted form. Therefore, we'll try to set up | 571 | * filenames are presented in encrypted form. Therefore, we'll try to set up |
| 546 | * the directory's encryption key, but even without it the lookup can continue. | 572 | * the directory's encryption key, but even without it the lookup can continue. |
| 547 | * | 573 | * |
| 548 | * To allow invalidating stale dentries if the directory's encryption key is | 574 | * This also installs a custom ->d_revalidate() method which will invalidate the |
| 549 | * added later, we also install a custom ->d_revalidate() method and use the | 575 | * dentry if it was created without the key and the key is later added. |
| 550 | * DCACHE_ENCRYPTED_WITH_KEY flag to indicate whether a given dentry is a | ||
| 551 | * plaintext name (flag set) or a ciphertext name (flag cleared). | ||
| 552 | * | 576 | * |
| 553 | * Return: 0 on success, -errno if a problem occurred while setting up the | 577 | * Return: 0 on success; -ENOENT if key is unavailable but the filename isn't a |
| 554 | * encryption key | 578 | * correctly formed encoded ciphertext name, so a negative dentry should be |
| 579 | * created; or another -errno code. | ||
| 555 | */ | 580 | */ |
| 556 | static inline int fscrypt_prepare_lookup(struct inode *dir, | 581 | static inline int fscrypt_prepare_lookup(struct inode *dir, |
| 557 | struct dentry *dentry, | 582 | struct dentry *dentry, |
| 558 | unsigned int flags) | 583 | struct fscrypt_name *fname) |
| 559 | { | 584 | { |
| 560 | if (IS_ENCRYPTED(dir)) | 585 | if (IS_ENCRYPTED(dir)) |
| 561 | return __fscrypt_prepare_lookup(dir, dentry); | 586 | return __fscrypt_prepare_lookup(dir, dentry, fname); |
| 587 | |||
| 588 | memset(fname, 0, sizeof(*fname)); | ||
| 589 | fname->usr_fname = &dentry->d_name; | ||
| 590 | fname->disk_name.name = (unsigned char *)dentry->d_name.name; | ||
| 591 | fname->disk_name.len = dentry->d_name.len; | ||
| 562 | return 0; | 592 | return 0; |
| 563 | } | 593 | } |
| 564 | 594 | ||