132190f0aSLinus Torvalds /* SPDX-License-Identifier: GPL-2.0 */ 2734f0d24SDave Chinner /* 3734f0d24SDave Chinner * fscrypt.h: declarations for per-file encryption 4734f0d24SDave Chinner * 5643fa961SChandan Rajendra * Filesystems that implement per-file encryption must include this header 6643fa961SChandan Rajendra * file. 7734f0d24SDave Chinner * 8734f0d24SDave Chinner * Copyright (C) 2015, Google, Inc. 9734f0d24SDave Chinner * 10734f0d24SDave Chinner * Written by Michael Halcrow, 2015. 11734f0d24SDave Chinner * Modified by Jaegeuk Kim, 2015. 12734f0d24SDave Chinner */ 13734f0d24SDave Chinner #ifndef _LINUX_FSCRYPT_H 14734f0d24SDave Chinner #define _LINUX_FSCRYPT_H 15734f0d24SDave Chinner 16734f0d24SDave Chinner #include <linux/fs.h> 17643fa961SChandan Rajendra #include <linux/mm.h> 18643fa961SChandan Rajendra #include <linux/slab.h> 197af0ab0dSEric Biggers #include <uapi/linux/fscrypt.h> 20734f0d24SDave Chinner 21734f0d24SDave Chinner #define FS_CRYPTO_BLOCK_SIZE 16 22734f0d24SDave Chinner 23ac4acb1fSEric Biggers union fscrypt_policy; 24734f0d24SDave Chinner struct fscrypt_info; 25ed318a6cSEric Biggers struct seq_file; 26734f0d24SDave Chinner 27734f0d24SDave Chinner struct fscrypt_str { 28734f0d24SDave Chinner unsigned char *name; 29734f0d24SDave Chinner u32 len; 30734f0d24SDave Chinner }; 31734f0d24SDave Chinner 32734f0d24SDave Chinner struct fscrypt_name { 33734f0d24SDave Chinner const struct qstr *usr_fname; 34734f0d24SDave Chinner struct fscrypt_str disk_name; 35734f0d24SDave Chinner u32 hash; 36734f0d24SDave Chinner u32 minor_hash; 37734f0d24SDave Chinner struct fscrypt_str crypto_buf; 3870fb2612SEric Biggers bool is_nokey_name; 39734f0d24SDave Chinner }; 40734f0d24SDave Chinner 41734f0d24SDave Chinner #define FSTR_INIT(n, l) { .name = n, .len = l } 42734f0d24SDave Chinner #define FSTR_TO_QSTR(f) QSTR_INIT((f)->name, (f)->len) 43734f0d24SDave Chinner #define fname_name(p) ((p)->disk_name.name) 44734f0d24SDave Chinner #define fname_len(p) ((p)->disk_name.len) 45734f0d24SDave Chinner 46734f0d24SDave Chinner /* Maximum value for the third parameter of fscrypt_operations.set_context(). */ 475dae460cSEric Biggers #define FSCRYPT_SET_CONTEXT_MAX_SIZE 40 48734f0d24SDave Chinner 49643fa961SChandan Rajendra #ifdef CONFIG_FS_ENCRYPTION 50643fa961SChandan Rajendra /* 51643fa961SChandan Rajendra * fscrypt superblock flags 52643fa961SChandan Rajendra */ 53643fa961SChandan Rajendra #define FS_CFLG_OWN_PAGES (1U << 1) 54643fa961SChandan Rajendra 55643fa961SChandan Rajendra /* 56643fa961SChandan Rajendra * crypto operations for filesystems 57643fa961SChandan Rajendra */ 58643fa961SChandan Rajendra struct fscrypt_operations { 59643fa961SChandan Rajendra unsigned int flags; 60643fa961SChandan Rajendra const char *key_prefix; 61fe015a78SEric Biggers int (*get_context)(struct inode *inode, void *ctx, size_t len); 62fe015a78SEric Biggers int (*set_context)(struct inode *inode, const void *ctx, size_t len, 63fe015a78SEric Biggers void *fs_data); 64ac4acb1fSEric Biggers const union fscrypt_policy *(*get_dummy_policy)(struct super_block *sb); 65fe015a78SEric Biggers bool (*empty_dir)(struct inode *inode); 66643fa961SChandan Rajendra unsigned int max_namelen; 67b103fb76SEric Biggers bool (*has_stable_inodes)(struct super_block *sb); 68b103fb76SEric Biggers void (*get_ino_and_lblk_bits)(struct super_block *sb, 69b103fb76SEric Biggers int *ino_bits_ret, int *lblk_bits_ret); 705fee3609SSatya Tangirala int (*get_num_devices)(struct super_block *sb); 715fee3609SSatya Tangirala void (*get_devices)(struct super_block *sb, 725fee3609SSatya Tangirala struct request_queue **devs); 73643fa961SChandan Rajendra }; 74643fa961SChandan Rajendra 75ab673b98SEric Biggers static inline struct fscrypt_info *fscrypt_get_info(const struct inode *inode) 76643fa961SChandan Rajendra { 77ab673b98SEric Biggers /* 78ab673b98SEric Biggers * Pairs with the cmpxchg_release() in fscrypt_get_encryption_info(). 79ab673b98SEric Biggers * I.e., another task may publish ->i_crypt_info concurrently, executing 80ab673b98SEric Biggers * a RELEASE barrier. We need to use smp_load_acquire() here to safely 81ab673b98SEric Biggers * ACQUIRE the memory the other task published. 82ab673b98SEric Biggers */ 83ab673b98SEric Biggers return smp_load_acquire(&inode->i_crypt_info); 84643fa961SChandan Rajendra } 85643fa961SChandan Rajendra 8656dce717SEric Biggers /** 8756dce717SEric Biggers * fscrypt_needs_contents_encryption() - check whether an inode needs 8856dce717SEric Biggers * contents encryption 89d2fe9754SEric Biggers * @inode: the inode to check 9056dce717SEric Biggers * 9156dce717SEric Biggers * Return: %true iff the inode is an encrypted regular file and the kernel was 9256dce717SEric Biggers * built with fscrypt support. 9356dce717SEric Biggers * 9456dce717SEric Biggers * If you need to know whether the encrypt bit is set even when the kernel was 9556dce717SEric Biggers * built without fscrypt support, you must use IS_ENCRYPTED() directly instead. 9656dce717SEric Biggers */ 9756dce717SEric Biggers static inline bool fscrypt_needs_contents_encryption(const struct inode *inode) 9856dce717SEric Biggers { 9956dce717SEric Biggers return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode); 10056dce717SEric Biggers } 10156dce717SEric Biggers 1020bf3d5c1SEric Biggers /* 103501e43fbSEric Biggers * When d_splice_alias() moves a directory's no-key alias to its plaintext alias 104501e43fbSEric Biggers * as a result of the encryption key being added, DCACHE_NOKEY_NAME must be 105501e43fbSEric Biggers * cleared. Note that we don't have to support arbitrary moves of this flag 106501e43fbSEric Biggers * because fscrypt doesn't allow no-key names to be the source or target of a 107501e43fbSEric Biggers * rename(). 1080bf3d5c1SEric Biggers */ 1090bf3d5c1SEric Biggers static inline void fscrypt_handle_d_move(struct dentry *dentry) 1100bf3d5c1SEric Biggers { 111501e43fbSEric Biggers dentry->d_flags &= ~DCACHE_NOKEY_NAME; 1120bf3d5c1SEric Biggers } 1130bf3d5c1SEric Biggers 114643fa961SChandan Rajendra /* crypto.c */ 11560700902SEric Biggers void fscrypt_enqueue_decrypt_work(struct work_struct *); 11653bc1d85SEric Biggers 11760700902SEric Biggers struct page *fscrypt_encrypt_pagecache_blocks(struct page *page, 11853bc1d85SEric Biggers unsigned int len, 11953bc1d85SEric Biggers unsigned int offs, 12053bc1d85SEric Biggers gfp_t gfp_flags); 12160700902SEric Biggers int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, 12260700902SEric Biggers unsigned int len, unsigned int offs, 12360700902SEric Biggers u64 lblk_num, gfp_t gfp_flags); 124aa8bc1acSEric Biggers 12560700902SEric Biggers int fscrypt_decrypt_pagecache_blocks(struct page *page, unsigned int len, 126aa8bc1acSEric Biggers unsigned int offs); 12760700902SEric Biggers int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page, 12860700902SEric Biggers unsigned int len, unsigned int offs, 12960700902SEric Biggers u64 lblk_num); 130643fa961SChandan Rajendra 131d2d0727bSEric Biggers static inline bool fscrypt_is_bounce_page(struct page *page) 132643fa961SChandan Rajendra { 133d2d0727bSEric Biggers return page->mapping == NULL; 134643fa961SChandan Rajendra } 135643fa961SChandan Rajendra 136d2d0727bSEric Biggers static inline struct page *fscrypt_pagecache_page(struct page *bounce_page) 137d2d0727bSEric Biggers { 138d2d0727bSEric Biggers return (struct page *)page_private(bounce_page); 139d2d0727bSEric Biggers } 140d2d0727bSEric Biggers 14160700902SEric Biggers void fscrypt_free_bounce_page(struct page *bounce_page); 142643fa961SChandan Rajendra 143643fa961SChandan Rajendra /* policy.c */ 14460700902SEric Biggers int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg); 14560700902SEric Biggers int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg); 14660700902SEric Biggers int fscrypt_ioctl_get_policy_ex(struct file *filp, void __user *arg); 14760700902SEric Biggers int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg); 14860700902SEric Biggers int fscrypt_has_permitted_context(struct inode *parent, struct inode *child); 149a992b20cSEric Biggers int fscrypt_set_context(struct inode *inode, void *fs_data); 150fe015a78SEric Biggers 151ac4acb1fSEric Biggers struct fscrypt_dummy_policy { 152ac4acb1fSEric Biggers const union fscrypt_policy *policy; 153ed318a6cSEric Biggers }; 154ed318a6cSEric Biggers 155c8c868abSEric Biggers int fscrypt_set_test_dummy_encryption(struct super_block *sb, const char *arg, 156ac4acb1fSEric Biggers struct fscrypt_dummy_policy *dummy_policy); 157ed318a6cSEric Biggers void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep, 158ed318a6cSEric Biggers struct super_block *sb); 159ed318a6cSEric Biggers static inline void 160ac4acb1fSEric Biggers fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy) 161ed318a6cSEric Biggers { 162ac4acb1fSEric Biggers kfree(dummy_policy->policy); 163ac4acb1fSEric Biggers dummy_policy->policy = NULL; 164ed318a6cSEric Biggers } 165ed318a6cSEric Biggers 16622d94f49SEric Biggers /* keyring.c */ 16760700902SEric Biggers void fscrypt_sb_free(struct super_block *sb); 16860700902SEric Biggers int fscrypt_ioctl_add_key(struct file *filp, void __user *arg); 16960700902SEric Biggers int fscrypt_ioctl_remove_key(struct file *filp, void __user *arg); 17060700902SEric Biggers int fscrypt_ioctl_remove_key_all_users(struct file *filp, void __user *arg); 17160700902SEric Biggers int fscrypt_ioctl_get_key_status(struct file *filp, void __user *arg); 17222d94f49SEric Biggers 173feed8258SEric Biggers /* keysetup.c */ 17460700902SEric Biggers int fscrypt_get_encryption_info(struct inode *inode); 175a992b20cSEric Biggers int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode, 176a992b20cSEric Biggers bool *encrypt_ret); 17760700902SEric Biggers void fscrypt_put_encryption_info(struct inode *inode); 17860700902SEric Biggers void fscrypt_free_inode(struct inode *inode); 17960700902SEric Biggers int fscrypt_drop_inode(struct inode *inode); 180643fa961SChandan Rajendra 181643fa961SChandan Rajendra /* fname.c */ 18260700902SEric Biggers int fscrypt_setup_filename(struct inode *inode, const struct qstr *iname, 183fe015a78SEric Biggers int lookup, struct fscrypt_name *fname); 184643fa961SChandan Rajendra 185643fa961SChandan Rajendra static inline void fscrypt_free_filename(struct fscrypt_name *fname) 186643fa961SChandan Rajendra { 187643fa961SChandan Rajendra kfree(fname->crypto_buf.name); 188643fa961SChandan Rajendra } 189643fa961SChandan Rajendra 1908b10fe68SJeff Layton int fscrypt_fname_alloc_buffer(u32 max_encrypted_len, 191fe015a78SEric Biggers struct fscrypt_str *crypto_str); 19260700902SEric Biggers void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str); 19360700902SEric Biggers int fscrypt_fname_disk_to_usr(const struct inode *inode, 1948a4ab0b8SEric Biggers u32 hash, u32 minor_hash, 1958a4ab0b8SEric Biggers const struct fscrypt_str *iname, 1968a4ab0b8SEric Biggers struct fscrypt_str *oname); 19760700902SEric Biggers bool fscrypt_match_name(const struct fscrypt_name *fname, 198edc440e3SDaniel Rosenberg const u8 *de_name, u32 de_name_len); 19960700902SEric Biggers u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name); 2005b2a828bSEric Biggers int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags); 201aa408f83SDaniel Rosenberg 202643fa961SChandan Rajendra /* bio.c */ 20360700902SEric Biggers void fscrypt_decrypt_bio(struct bio *bio); 20460700902SEric Biggers int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, 205fe015a78SEric Biggers sector_t pblk, unsigned int len); 206643fa961SChandan Rajendra 207643fa961SChandan Rajendra /* hooks.c */ 20860700902SEric Biggers int fscrypt_file_open(struct inode *inode, struct file *filp); 20960700902SEric Biggers int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, 210968dd6d0SEric Biggers struct dentry *dentry); 21160700902SEric Biggers int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry, 21260700902SEric Biggers struct inode *new_dir, struct dentry *new_dentry, 213643fa961SChandan Rajendra unsigned int flags); 21460700902SEric Biggers int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry, 215b01531dbSEric Biggers struct fscrypt_name *fname); 21660700902SEric Biggers int fscrypt_prepare_setflags(struct inode *inode, 2176e1918cfSDaniel Rosenberg unsigned int oldflags, unsigned int flags); 21831114726SEric Biggers int fscrypt_prepare_symlink(struct inode *dir, const char *target, 21931114726SEric Biggers unsigned int len, unsigned int max_len, 220643fa961SChandan Rajendra struct fscrypt_str *disk_link); 22160700902SEric Biggers int __fscrypt_encrypt_symlink(struct inode *inode, const char *target, 22260700902SEric Biggers unsigned int len, struct fscrypt_str *disk_link); 22360700902SEric Biggers const char *fscrypt_get_symlink(struct inode *inode, const void *caddr, 224643fa961SChandan Rajendra unsigned int max_size, 225643fa961SChandan Rajendra struct delayed_call *done); 226eea2c05dSSascha Hauer static inline void fscrypt_set_ops(struct super_block *sb, 227eea2c05dSSascha Hauer const struct fscrypt_operations *s_cop) 228eea2c05dSSascha Hauer { 229eea2c05dSSascha Hauer sb->s_cop = s_cop; 230eea2c05dSSascha Hauer } 231643fa961SChandan Rajendra #else /* !CONFIG_FS_ENCRYPTION */ 232643fa961SChandan Rajendra 233ab673b98SEric Biggers static inline struct fscrypt_info *fscrypt_get_info(const struct inode *inode) 234643fa961SChandan Rajendra { 235ab673b98SEric Biggers return NULL; 236643fa961SChandan Rajendra } 237643fa961SChandan Rajendra 23856dce717SEric Biggers static inline bool fscrypt_needs_contents_encryption(const struct inode *inode) 23956dce717SEric Biggers { 24056dce717SEric Biggers return false; 24156dce717SEric Biggers } 24256dce717SEric Biggers 2430bf3d5c1SEric Biggers static inline void fscrypt_handle_d_move(struct dentry *dentry) 2440bf3d5c1SEric Biggers { 2450bf3d5c1SEric Biggers } 2460bf3d5c1SEric Biggers 247643fa961SChandan Rajendra /* crypto.c */ 248643fa961SChandan Rajendra static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work) 249643fa961SChandan Rajendra { 250643fa961SChandan Rajendra } 251643fa961SChandan Rajendra 25253bc1d85SEric Biggers static inline struct page *fscrypt_encrypt_pagecache_blocks(struct page *page, 253643fa961SChandan Rajendra unsigned int len, 254643fa961SChandan Rajendra unsigned int offs, 25553bc1d85SEric Biggers gfp_t gfp_flags) 256643fa961SChandan Rajendra { 257643fa961SChandan Rajendra return ERR_PTR(-EOPNOTSUPP); 258643fa961SChandan Rajendra } 259643fa961SChandan Rajendra 26003569f2fSEric Biggers static inline int fscrypt_encrypt_block_inplace(const struct inode *inode, 26103569f2fSEric Biggers struct page *page, 26203569f2fSEric Biggers unsigned int len, 26303569f2fSEric Biggers unsigned int offs, u64 lblk_num, 26403569f2fSEric Biggers gfp_t gfp_flags) 26503569f2fSEric Biggers { 26603569f2fSEric Biggers return -EOPNOTSUPP; 26703569f2fSEric Biggers } 26803569f2fSEric Biggers 269aa8bc1acSEric Biggers static inline int fscrypt_decrypt_pagecache_blocks(struct page *page, 270aa8bc1acSEric Biggers unsigned int len, 271aa8bc1acSEric Biggers unsigned int offs) 272643fa961SChandan Rajendra { 273643fa961SChandan Rajendra return -EOPNOTSUPP; 274643fa961SChandan Rajendra } 275643fa961SChandan Rajendra 27641adbcb7SEric Biggers static inline int fscrypt_decrypt_block_inplace(const struct inode *inode, 27741adbcb7SEric Biggers struct page *page, 27841adbcb7SEric Biggers unsigned int len, 27941adbcb7SEric Biggers unsigned int offs, u64 lblk_num) 28041adbcb7SEric Biggers { 28141adbcb7SEric Biggers return -EOPNOTSUPP; 28241adbcb7SEric Biggers } 28341adbcb7SEric Biggers 284d2d0727bSEric Biggers static inline bool fscrypt_is_bounce_page(struct page *page) 285d2d0727bSEric Biggers { 286d2d0727bSEric Biggers return false; 287d2d0727bSEric Biggers } 288d2d0727bSEric Biggers 289d2d0727bSEric Biggers static inline struct page *fscrypt_pagecache_page(struct page *bounce_page) 290643fa961SChandan Rajendra { 291643fa961SChandan Rajendra WARN_ON_ONCE(1); 292643fa961SChandan Rajendra return ERR_PTR(-EINVAL); 293643fa961SChandan Rajendra } 294643fa961SChandan Rajendra 295d2d0727bSEric Biggers static inline void fscrypt_free_bounce_page(struct page *bounce_page) 296643fa961SChandan Rajendra { 297643fa961SChandan Rajendra } 298643fa961SChandan Rajendra 299643fa961SChandan Rajendra /* policy.c */ 300643fa961SChandan Rajendra static inline int fscrypt_ioctl_set_policy(struct file *filp, 301643fa961SChandan Rajendra const void __user *arg) 302643fa961SChandan Rajendra { 303643fa961SChandan Rajendra return -EOPNOTSUPP; 304643fa961SChandan Rajendra } 305643fa961SChandan Rajendra 306643fa961SChandan Rajendra static inline int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg) 307643fa961SChandan Rajendra { 308643fa961SChandan Rajendra return -EOPNOTSUPP; 309643fa961SChandan Rajendra } 310643fa961SChandan Rajendra 3115dae460cSEric Biggers static inline int fscrypt_ioctl_get_policy_ex(struct file *filp, 3125dae460cSEric Biggers void __user *arg) 3135dae460cSEric Biggers { 3145dae460cSEric Biggers return -EOPNOTSUPP; 3155dae460cSEric Biggers } 3165dae460cSEric Biggers 317e98ad464SEric Biggers static inline int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg) 318e98ad464SEric Biggers { 319e98ad464SEric Biggers return -EOPNOTSUPP; 320e98ad464SEric Biggers } 321e98ad464SEric Biggers 322643fa961SChandan Rajendra static inline int fscrypt_has_permitted_context(struct inode *parent, 323643fa961SChandan Rajendra struct inode *child) 324643fa961SChandan Rajendra { 325643fa961SChandan Rajendra return 0; 326643fa961SChandan Rajendra } 327643fa961SChandan Rajendra 328a992b20cSEric Biggers static inline int fscrypt_set_context(struct inode *inode, void *fs_data) 329a992b20cSEric Biggers { 330a992b20cSEric Biggers return -EOPNOTSUPP; 331a992b20cSEric Biggers } 332a992b20cSEric Biggers 333ac4acb1fSEric Biggers struct fscrypt_dummy_policy { 334ed318a6cSEric Biggers }; 335ed318a6cSEric Biggers 336ed318a6cSEric Biggers static inline void fscrypt_show_test_dummy_encryption(struct seq_file *seq, 337ed318a6cSEric Biggers char sep, 338ed318a6cSEric Biggers struct super_block *sb) 339ed318a6cSEric Biggers { 340ed318a6cSEric Biggers } 341ed318a6cSEric Biggers 342ed318a6cSEric Biggers static inline void 343ac4acb1fSEric Biggers fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy) 344ed318a6cSEric Biggers { 345ed318a6cSEric Biggers } 346ed318a6cSEric Biggers 34722d94f49SEric Biggers /* keyring.c */ 34822d94f49SEric Biggers static inline void fscrypt_sb_free(struct super_block *sb) 34922d94f49SEric Biggers { 35022d94f49SEric Biggers } 35122d94f49SEric Biggers 35222d94f49SEric Biggers static inline int fscrypt_ioctl_add_key(struct file *filp, void __user *arg) 35322d94f49SEric Biggers { 35422d94f49SEric Biggers return -EOPNOTSUPP; 35522d94f49SEric Biggers } 35622d94f49SEric Biggers 357b1c0ec35SEric Biggers static inline int fscrypt_ioctl_remove_key(struct file *filp, void __user *arg) 358b1c0ec35SEric Biggers { 359b1c0ec35SEric Biggers return -EOPNOTSUPP; 360b1c0ec35SEric Biggers } 361b1c0ec35SEric Biggers 36278a1b96bSEric Biggers static inline int fscrypt_ioctl_remove_key_all_users(struct file *filp, 36378a1b96bSEric Biggers void __user *arg) 36478a1b96bSEric Biggers { 36578a1b96bSEric Biggers return -EOPNOTSUPP; 36678a1b96bSEric Biggers } 36778a1b96bSEric Biggers 3685a7e2992SEric Biggers static inline int fscrypt_ioctl_get_key_status(struct file *filp, 3695a7e2992SEric Biggers void __user *arg) 3705a7e2992SEric Biggers { 3715a7e2992SEric Biggers return -EOPNOTSUPP; 3725a7e2992SEric Biggers } 3735a7e2992SEric Biggers 374feed8258SEric Biggers /* keysetup.c */ 375643fa961SChandan Rajendra static inline int fscrypt_get_encryption_info(struct inode *inode) 376643fa961SChandan Rajendra { 377643fa961SChandan Rajendra return -EOPNOTSUPP; 378643fa961SChandan Rajendra } 379643fa961SChandan Rajendra 380a992b20cSEric Biggers static inline int fscrypt_prepare_new_inode(struct inode *dir, 381a992b20cSEric Biggers struct inode *inode, 382a992b20cSEric Biggers bool *encrypt_ret) 383a992b20cSEric Biggers { 384a992b20cSEric Biggers if (IS_ENCRYPTED(dir)) 385a992b20cSEric Biggers return -EOPNOTSUPP; 386a992b20cSEric Biggers return 0; 387a992b20cSEric Biggers } 388a992b20cSEric Biggers 389643fa961SChandan Rajendra static inline void fscrypt_put_encryption_info(struct inode *inode) 390643fa961SChandan Rajendra { 391643fa961SChandan Rajendra return; 392643fa961SChandan Rajendra } 393643fa961SChandan Rajendra 3942c58d548SEric Biggers static inline void fscrypt_free_inode(struct inode *inode) 3952c58d548SEric Biggers { 3962c58d548SEric Biggers } 3972c58d548SEric Biggers 398b1c0ec35SEric Biggers static inline int fscrypt_drop_inode(struct inode *inode) 399b1c0ec35SEric Biggers { 400b1c0ec35SEric Biggers return 0; 401b1c0ec35SEric Biggers } 402b1c0ec35SEric Biggers 403643fa961SChandan Rajendra /* fname.c */ 404643fa961SChandan Rajendra static inline int fscrypt_setup_filename(struct inode *dir, 405643fa961SChandan Rajendra const struct qstr *iname, 406643fa961SChandan Rajendra int lookup, struct fscrypt_name *fname) 407643fa961SChandan Rajendra { 408643fa961SChandan Rajendra if (IS_ENCRYPTED(dir)) 409643fa961SChandan Rajendra return -EOPNOTSUPP; 410643fa961SChandan Rajendra 411b01531dbSEric Biggers memset(fname, 0, sizeof(*fname)); 412643fa961SChandan Rajendra fname->usr_fname = iname; 413643fa961SChandan Rajendra fname->disk_name.name = (unsigned char *)iname->name; 414643fa961SChandan Rajendra fname->disk_name.len = iname->len; 415643fa961SChandan Rajendra return 0; 416643fa961SChandan Rajendra } 417643fa961SChandan Rajendra 418643fa961SChandan Rajendra static inline void fscrypt_free_filename(struct fscrypt_name *fname) 419643fa961SChandan Rajendra { 420643fa961SChandan Rajendra return; 421643fa961SChandan Rajendra } 422643fa961SChandan Rajendra 4238b10fe68SJeff Layton static inline int fscrypt_fname_alloc_buffer(u32 max_encrypted_len, 424643fa961SChandan Rajendra struct fscrypt_str *crypto_str) 425643fa961SChandan Rajendra { 426643fa961SChandan Rajendra return -EOPNOTSUPP; 427643fa961SChandan Rajendra } 428643fa961SChandan Rajendra 429643fa961SChandan Rajendra static inline void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str) 430643fa961SChandan Rajendra { 431643fa961SChandan Rajendra return; 432643fa961SChandan Rajendra } 433643fa961SChandan Rajendra 4348a4ab0b8SEric Biggers static inline int fscrypt_fname_disk_to_usr(const struct inode *inode, 435643fa961SChandan Rajendra u32 hash, u32 minor_hash, 436643fa961SChandan Rajendra const struct fscrypt_str *iname, 437643fa961SChandan Rajendra struct fscrypt_str *oname) 438643fa961SChandan Rajendra { 439643fa961SChandan Rajendra return -EOPNOTSUPP; 440643fa961SChandan Rajendra } 441643fa961SChandan Rajendra 442643fa961SChandan Rajendra static inline bool fscrypt_match_name(const struct fscrypt_name *fname, 443643fa961SChandan Rajendra const u8 *de_name, u32 de_name_len) 444643fa961SChandan Rajendra { 445643fa961SChandan Rajendra /* Encryption support disabled; use standard comparison */ 446643fa961SChandan Rajendra if (de_name_len != fname->disk_name.len) 447643fa961SChandan Rajendra return false; 448643fa961SChandan Rajendra return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len); 449643fa961SChandan Rajendra } 450643fa961SChandan Rajendra 451aa408f83SDaniel Rosenberg static inline u64 fscrypt_fname_siphash(const struct inode *dir, 452aa408f83SDaniel Rosenberg const struct qstr *name) 453aa408f83SDaniel Rosenberg { 454aa408f83SDaniel Rosenberg WARN_ON_ONCE(1); 455aa408f83SDaniel Rosenberg return 0; 456aa408f83SDaniel Rosenberg } 457aa408f83SDaniel Rosenberg 4585b2a828bSEric Biggers static inline int fscrypt_d_revalidate(struct dentry *dentry, 4595b2a828bSEric Biggers unsigned int flags) 4605b2a828bSEric Biggers { 4615b2a828bSEric Biggers return 1; 4625b2a828bSEric Biggers } 4635b2a828bSEric Biggers 464643fa961SChandan Rajendra /* bio.c */ 465643fa961SChandan Rajendra static inline void fscrypt_decrypt_bio(struct bio *bio) 466643fa961SChandan Rajendra { 467643fa961SChandan Rajendra } 468643fa961SChandan Rajendra 469643fa961SChandan Rajendra static inline int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, 470643fa961SChandan Rajendra sector_t pblk, unsigned int len) 471643fa961SChandan Rajendra { 472643fa961SChandan Rajendra return -EOPNOTSUPP; 473643fa961SChandan Rajendra } 474643fa961SChandan Rajendra 475643fa961SChandan Rajendra /* hooks.c */ 476643fa961SChandan Rajendra 477643fa961SChandan Rajendra static inline int fscrypt_file_open(struct inode *inode, struct file *filp) 478643fa961SChandan Rajendra { 479643fa961SChandan Rajendra if (IS_ENCRYPTED(inode)) 480643fa961SChandan Rajendra return -EOPNOTSUPP; 481643fa961SChandan Rajendra return 0; 482643fa961SChandan Rajendra } 483643fa961SChandan Rajendra 484968dd6d0SEric Biggers static inline int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, 485968dd6d0SEric Biggers struct dentry *dentry) 486643fa961SChandan Rajendra { 487643fa961SChandan Rajendra return -EOPNOTSUPP; 488643fa961SChandan Rajendra } 489643fa961SChandan Rajendra 490643fa961SChandan Rajendra static inline int __fscrypt_prepare_rename(struct inode *old_dir, 491643fa961SChandan Rajendra struct dentry *old_dentry, 492643fa961SChandan Rajendra struct inode *new_dir, 493643fa961SChandan Rajendra struct dentry *new_dentry, 494643fa961SChandan Rajendra unsigned int flags) 495643fa961SChandan Rajendra { 496643fa961SChandan Rajendra return -EOPNOTSUPP; 497643fa961SChandan Rajendra } 498643fa961SChandan Rajendra 499643fa961SChandan Rajendra static inline int __fscrypt_prepare_lookup(struct inode *dir, 500b01531dbSEric Biggers struct dentry *dentry, 501b01531dbSEric Biggers struct fscrypt_name *fname) 502643fa961SChandan Rajendra { 503643fa961SChandan Rajendra return -EOPNOTSUPP; 504643fa961SChandan Rajendra } 505643fa961SChandan Rajendra 5066e1918cfSDaniel Rosenberg static inline int fscrypt_prepare_setflags(struct inode *inode, 5076e1918cfSDaniel Rosenberg unsigned int oldflags, 5086e1918cfSDaniel Rosenberg unsigned int flags) 5096e1918cfSDaniel Rosenberg { 5106e1918cfSDaniel Rosenberg return 0; 5116e1918cfSDaniel Rosenberg } 5126e1918cfSDaniel Rosenberg 51331114726SEric Biggers static inline int fscrypt_prepare_symlink(struct inode *dir, 51431114726SEric Biggers const char *target, 515643fa961SChandan Rajendra unsigned int len, 516643fa961SChandan Rajendra unsigned int max_len, 517643fa961SChandan Rajendra struct fscrypt_str *disk_link) 518643fa961SChandan Rajendra { 51931114726SEric Biggers if (IS_ENCRYPTED(dir)) 520643fa961SChandan Rajendra return -EOPNOTSUPP; 52131114726SEric Biggers disk_link->name = (unsigned char *)target; 52231114726SEric Biggers disk_link->len = len + 1; 52331114726SEric Biggers if (disk_link->len > max_len) 52431114726SEric Biggers return -ENAMETOOLONG; 52531114726SEric Biggers return 0; 526643fa961SChandan Rajendra } 527643fa961SChandan Rajendra 528643fa961SChandan Rajendra static inline int __fscrypt_encrypt_symlink(struct inode *inode, 529643fa961SChandan Rajendra const char *target, 530643fa961SChandan Rajendra unsigned int len, 531643fa961SChandan Rajendra struct fscrypt_str *disk_link) 532643fa961SChandan Rajendra { 533643fa961SChandan Rajendra return -EOPNOTSUPP; 534643fa961SChandan Rajendra } 535643fa961SChandan Rajendra 536643fa961SChandan Rajendra static inline const char *fscrypt_get_symlink(struct inode *inode, 537643fa961SChandan Rajendra const void *caddr, 538643fa961SChandan Rajendra unsigned int max_size, 539643fa961SChandan Rajendra struct delayed_call *done) 540643fa961SChandan Rajendra { 541643fa961SChandan Rajendra return ERR_PTR(-EOPNOTSUPP); 542643fa961SChandan Rajendra } 543eea2c05dSSascha Hauer 544eea2c05dSSascha Hauer static inline void fscrypt_set_ops(struct super_block *sb, 545eea2c05dSSascha Hauer const struct fscrypt_operations *s_cop) 546eea2c05dSSascha Hauer { 547eea2c05dSSascha Hauer } 548eea2c05dSSascha Hauer 549643fa961SChandan Rajendra #endif /* !CONFIG_FS_ENCRYPTION */ 550734f0d24SDave Chinner 5515fee3609SSatya Tangirala /* inline_crypt.c */ 5525fee3609SSatya Tangirala #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT 5535fee3609SSatya Tangirala 5545fee3609SSatya Tangirala bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode); 5555fee3609SSatya Tangirala 5565fee3609SSatya Tangirala void fscrypt_set_bio_crypt_ctx(struct bio *bio, 5575fee3609SSatya Tangirala const struct inode *inode, u64 first_lblk, 5585fee3609SSatya Tangirala gfp_t gfp_mask); 5595fee3609SSatya Tangirala 5605fee3609SSatya Tangirala void fscrypt_set_bio_crypt_ctx_bh(struct bio *bio, 5615fee3609SSatya Tangirala const struct buffer_head *first_bh, 5625fee3609SSatya Tangirala gfp_t gfp_mask); 5635fee3609SSatya Tangirala 5645fee3609SSatya Tangirala bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, 5655fee3609SSatya Tangirala u64 next_lblk); 5665fee3609SSatya Tangirala 5675fee3609SSatya Tangirala bool fscrypt_mergeable_bio_bh(struct bio *bio, 5685fee3609SSatya Tangirala const struct buffer_head *next_bh); 5695fee3609SSatya Tangirala 5705fee3609SSatya Tangirala #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ 5715fee3609SSatya Tangirala 5725fee3609SSatya Tangirala static inline bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode) 5735fee3609SSatya Tangirala { 5745fee3609SSatya Tangirala return false; 5755fee3609SSatya Tangirala } 5765fee3609SSatya Tangirala 5775fee3609SSatya Tangirala static inline void fscrypt_set_bio_crypt_ctx(struct bio *bio, 5785fee3609SSatya Tangirala const struct inode *inode, 5795fee3609SSatya Tangirala u64 first_lblk, gfp_t gfp_mask) { } 5805fee3609SSatya Tangirala 5815fee3609SSatya Tangirala static inline void fscrypt_set_bio_crypt_ctx_bh( 5825fee3609SSatya Tangirala struct bio *bio, 5835fee3609SSatya Tangirala const struct buffer_head *first_bh, 5845fee3609SSatya Tangirala gfp_t gfp_mask) { } 5855fee3609SSatya Tangirala 5865fee3609SSatya Tangirala static inline bool fscrypt_mergeable_bio(struct bio *bio, 5875fee3609SSatya Tangirala const struct inode *inode, 5885fee3609SSatya Tangirala u64 next_lblk) 5895fee3609SSatya Tangirala { 5905fee3609SSatya Tangirala return true; 5915fee3609SSatya Tangirala } 5925fee3609SSatya Tangirala 5935fee3609SSatya Tangirala static inline bool fscrypt_mergeable_bio_bh(struct bio *bio, 5945fee3609SSatya Tangirala const struct buffer_head *next_bh) 5955fee3609SSatya Tangirala { 5965fee3609SSatya Tangirala return true; 5975fee3609SSatya Tangirala } 5985fee3609SSatya Tangirala #endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ 5995fee3609SSatya Tangirala 6005fee3609SSatya Tangirala /** 6015fee3609SSatya Tangirala * fscrypt_inode_uses_inline_crypto() - test whether an inode uses inline 6025fee3609SSatya Tangirala * encryption 6035fee3609SSatya Tangirala * @inode: an inode. If encrypted, its key must be set up. 6045fee3609SSatya Tangirala * 6055fee3609SSatya Tangirala * Return: true if the inode requires file contents encryption and if the 6065fee3609SSatya Tangirala * encryption should be done in the block layer via blk-crypto rather 6075fee3609SSatya Tangirala * than in the filesystem layer. 6085fee3609SSatya Tangirala */ 6095fee3609SSatya Tangirala static inline bool fscrypt_inode_uses_inline_crypto(const struct inode *inode) 6105fee3609SSatya Tangirala { 6115fee3609SSatya Tangirala return fscrypt_needs_contents_encryption(inode) && 6125fee3609SSatya Tangirala __fscrypt_inode_uses_inline_crypto(inode); 6135fee3609SSatya Tangirala } 6145fee3609SSatya Tangirala 6155fee3609SSatya Tangirala /** 6165fee3609SSatya Tangirala * fscrypt_inode_uses_fs_layer_crypto() - test whether an inode uses fs-layer 6175fee3609SSatya Tangirala * encryption 6185fee3609SSatya Tangirala * @inode: an inode. If encrypted, its key must be set up. 6195fee3609SSatya Tangirala * 6205fee3609SSatya Tangirala * Return: true if the inode requires file contents encryption and if the 6215fee3609SSatya Tangirala * encryption should be done in the filesystem layer rather than in the 6225fee3609SSatya Tangirala * block layer via blk-crypto. 6235fee3609SSatya Tangirala */ 6245fee3609SSatya Tangirala static inline bool fscrypt_inode_uses_fs_layer_crypto(const struct inode *inode) 6255fee3609SSatya Tangirala { 6265fee3609SSatya Tangirala return fscrypt_needs_contents_encryption(inode) && 6275fee3609SSatya Tangirala !__fscrypt_inode_uses_inline_crypto(inode); 6285fee3609SSatya Tangirala } 6295fee3609SSatya Tangirala 630d293c3e4SEric Biggers /** 631ab673b98SEric Biggers * fscrypt_has_encryption_key() - check whether an inode has had its key set up 632ab673b98SEric Biggers * @inode: the inode to check 633ab673b98SEric Biggers * 634ab673b98SEric Biggers * Return: %true if the inode has had its encryption key set up, else %false. 635ab673b98SEric Biggers * 636ab673b98SEric Biggers * Usually this should be preceded by fscrypt_get_encryption_info() to try to 637ab673b98SEric Biggers * set up the key first. 638ab673b98SEric Biggers */ 639ab673b98SEric Biggers static inline bool fscrypt_has_encryption_key(const struct inode *inode) 640ab673b98SEric Biggers { 641ab673b98SEric Biggers return fscrypt_get_info(inode) != NULL; 642ab673b98SEric Biggers } 643ab673b98SEric Biggers 644ab673b98SEric Biggers /** 645d2fe9754SEric Biggers * fscrypt_require_key() - require an inode's encryption key 646d293c3e4SEric Biggers * @inode: the inode we need the key for 647d293c3e4SEric Biggers * 648d293c3e4SEric Biggers * If the inode is encrypted, set up its encryption key if not already done. 649d293c3e4SEric Biggers * Then require that the key be present and return -ENOKEY otherwise. 650d293c3e4SEric Biggers * 651d293c3e4SEric Biggers * No locks are needed, and the key will live as long as the struct inode --- so 652d293c3e4SEric Biggers * it won't go away from under you. 653d293c3e4SEric Biggers * 654d293c3e4SEric Biggers * Return: 0 on success, -ENOKEY if the key is missing, or another -errno code 655d293c3e4SEric Biggers * if a problem occurred while setting up the encryption key. 656d293c3e4SEric Biggers */ 657d293c3e4SEric Biggers static inline int fscrypt_require_key(struct inode *inode) 658d293c3e4SEric Biggers { 659d293c3e4SEric Biggers if (IS_ENCRYPTED(inode)) { 660d293c3e4SEric Biggers int err = fscrypt_get_encryption_info(inode); 661d293c3e4SEric Biggers 662d293c3e4SEric Biggers if (err) 663d293c3e4SEric Biggers return err; 664d293c3e4SEric Biggers if (!fscrypt_has_encryption_key(inode)) 665d293c3e4SEric Biggers return -ENOKEY; 666d293c3e4SEric Biggers } 667d293c3e4SEric Biggers return 0; 668d293c3e4SEric Biggers } 669734f0d24SDave Chinner 6700ea87a96SEric Biggers /** 671d2fe9754SEric Biggers * fscrypt_prepare_link() - prepare to link an inode into a possibly-encrypted 672d2fe9754SEric Biggers * directory 6730ea87a96SEric Biggers * @old_dentry: an existing dentry for the inode being linked 6740ea87a96SEric Biggers * @dir: the target directory 6750ea87a96SEric Biggers * @dentry: negative dentry for the target filename 6760ea87a96SEric Biggers * 6770ea87a96SEric Biggers * A new link can only be added to an encrypted directory if the directory's 6780ea87a96SEric Biggers * encryption key is available --- since otherwise we'd have no way to encrypt 6790ea87a96SEric Biggers * the filename. Therefore, we first set up the directory's encryption key (if 6800ea87a96SEric Biggers * not already done) and return an error if it's unavailable. 6810ea87a96SEric Biggers * 6820ea87a96SEric Biggers * We also verify that the link will not violate the constraint that all files 6830ea87a96SEric Biggers * in an encrypted directory tree use the same encryption policy. 6840ea87a96SEric Biggers * 6850ea87a96SEric Biggers * Return: 0 on success, -ENOKEY if the directory's encryption key is missing, 686f5e55e77SEric Biggers * -EXDEV if the link would result in an inconsistent encryption policy, or 6870ea87a96SEric Biggers * another -errno code. 6880ea87a96SEric Biggers */ 6890ea87a96SEric Biggers static inline int fscrypt_prepare_link(struct dentry *old_dentry, 6900ea87a96SEric Biggers struct inode *dir, 6910ea87a96SEric Biggers struct dentry *dentry) 6920ea87a96SEric Biggers { 6930ea87a96SEric Biggers if (IS_ENCRYPTED(dir)) 694968dd6d0SEric Biggers return __fscrypt_prepare_link(d_inode(old_dentry), dir, dentry); 6950ea87a96SEric Biggers return 0; 6960ea87a96SEric Biggers } 6970ea87a96SEric Biggers 69894b26f36SEric Biggers /** 699d2fe9754SEric Biggers * fscrypt_prepare_rename() - prepare for a rename between possibly-encrypted 700d2fe9754SEric Biggers * directories 70194b26f36SEric Biggers * @old_dir: source directory 70294b26f36SEric Biggers * @old_dentry: dentry for source file 70394b26f36SEric Biggers * @new_dir: target directory 70494b26f36SEric Biggers * @new_dentry: dentry for target location (may be negative unless exchanging) 70594b26f36SEric Biggers * @flags: rename flags (we care at least about %RENAME_EXCHANGE) 70694b26f36SEric Biggers * 70794b26f36SEric Biggers * Prepare for ->rename() where the source and/or target directories may be 70894b26f36SEric Biggers * encrypted. A new link can only be added to an encrypted directory if the 70994b26f36SEric Biggers * directory's encryption key is available --- since otherwise we'd have no way 71094b26f36SEric Biggers * to encrypt the filename. A rename to an existing name, on the other hand, 71194b26f36SEric Biggers * *is* cryptographically possible without the key. However, we take the more 71294b26f36SEric Biggers * conservative approach and just forbid all no-key renames. 71394b26f36SEric Biggers * 71494b26f36SEric Biggers * We also verify that the rename will not violate the constraint that all files 71594b26f36SEric Biggers * in an encrypted directory tree use the same encryption policy. 71694b26f36SEric Biggers * 717f5e55e77SEric Biggers * Return: 0 on success, -ENOKEY if an encryption key is missing, -EXDEV if the 71894b26f36SEric Biggers * rename would cause inconsistent encryption policies, or another -errno code. 71994b26f36SEric Biggers */ 72094b26f36SEric Biggers static inline int fscrypt_prepare_rename(struct inode *old_dir, 72194b26f36SEric Biggers struct dentry *old_dentry, 72294b26f36SEric Biggers struct inode *new_dir, 72394b26f36SEric Biggers struct dentry *new_dentry, 72494b26f36SEric Biggers unsigned int flags) 72594b26f36SEric Biggers { 72694b26f36SEric Biggers if (IS_ENCRYPTED(old_dir) || IS_ENCRYPTED(new_dir)) 72794b26f36SEric Biggers return __fscrypt_prepare_rename(old_dir, old_dentry, 72894b26f36SEric Biggers new_dir, new_dentry, flags); 72994b26f36SEric Biggers return 0; 73094b26f36SEric Biggers } 73194b26f36SEric Biggers 73232c3cf02SEric Biggers /** 733d2fe9754SEric Biggers * fscrypt_prepare_lookup() - prepare to lookup a name in a possibly-encrypted 734d2fe9754SEric Biggers * directory 73532c3cf02SEric Biggers * @dir: directory being searched 73632c3cf02SEric Biggers * @dentry: filename being looked up 737b01531dbSEric Biggers * @fname: (output) the name to use to search the on-disk directory 73832c3cf02SEric Biggers * 739b01531dbSEric Biggers * Prepare for ->lookup() in a directory which may be encrypted by determining 74070fb2612SEric Biggers * the name that will actually be used to search the directory on-disk. If the 74170fb2612SEric Biggers * directory's encryption key is available, then the lookup is assumed to be by 74270fb2612SEric Biggers * plaintext name; otherwise, it is assumed to be by no-key name. 74332c3cf02SEric Biggers * 744*bb9cd910SDaniel Rosenberg * This will set DCACHE_NOKEY_NAME on the dentry if the lookup is by no-key 745*bb9cd910SDaniel Rosenberg * name. In this case the filesystem must assign the dentry a dentry_operations 746*bb9cd910SDaniel Rosenberg * which contains fscrypt_d_revalidate (or contains a d_revalidate method that 747*bb9cd910SDaniel Rosenberg * calls fscrypt_d_revalidate), so that the dentry will be invalidated if the 748*bb9cd910SDaniel Rosenberg * directory's encryption key is later added. 74932c3cf02SEric Biggers * 75070fb2612SEric Biggers * Return: 0 on success; -ENOENT if the directory's key is unavailable but the 75170fb2612SEric Biggers * filename isn't a valid no-key name, so a negative dentry should be created; 75270fb2612SEric Biggers * or another -errno code. 75332c3cf02SEric Biggers */ 75432c3cf02SEric Biggers static inline int fscrypt_prepare_lookup(struct inode *dir, 75532c3cf02SEric Biggers struct dentry *dentry, 756b01531dbSEric Biggers struct fscrypt_name *fname) 75732c3cf02SEric Biggers { 75832c3cf02SEric Biggers if (IS_ENCRYPTED(dir)) 759b01531dbSEric Biggers return __fscrypt_prepare_lookup(dir, dentry, fname); 760b01531dbSEric Biggers 761b01531dbSEric Biggers memset(fname, 0, sizeof(*fname)); 762b01531dbSEric Biggers fname->usr_fname = &dentry->d_name; 763b01531dbSEric Biggers fname->disk_name.name = (unsigned char *)dentry->d_name.name; 764b01531dbSEric Biggers fname->disk_name.len = dentry->d_name.len; 76532c3cf02SEric Biggers return 0; 76632c3cf02SEric Biggers } 76732c3cf02SEric Biggers 768815dac33SEric Biggers /** 769d2fe9754SEric Biggers * fscrypt_prepare_setattr() - prepare to change a possibly-encrypted inode's 770d2fe9754SEric Biggers * attributes 771815dac33SEric Biggers * @dentry: dentry through which the inode is being changed 772815dac33SEric Biggers * @attr: attributes to change 773815dac33SEric Biggers * 774815dac33SEric Biggers * Prepare for ->setattr() on a possibly-encrypted inode. On an encrypted file, 775815dac33SEric Biggers * most attribute changes are allowed even without the encryption key. However, 776815dac33SEric Biggers * without the encryption key we do have to forbid truncates. This is needed 777815dac33SEric Biggers * because the size being truncated to may not be a multiple of the filesystem 778815dac33SEric Biggers * block size, and in that case we'd have to decrypt the final block, zero the 779815dac33SEric Biggers * portion past i_size, and re-encrypt it. (We *could* allow truncating to a 780815dac33SEric Biggers * filesystem block boundary, but it's simpler to just forbid all truncates --- 781815dac33SEric Biggers * and we already forbid all other contents modifications without the key.) 782815dac33SEric Biggers * 783815dac33SEric Biggers * Return: 0 on success, -ENOKEY if the key is missing, or another -errno code 784815dac33SEric Biggers * if a problem occurred while setting up the encryption key. 785815dac33SEric Biggers */ 786815dac33SEric Biggers static inline int fscrypt_prepare_setattr(struct dentry *dentry, 787815dac33SEric Biggers struct iattr *attr) 788815dac33SEric Biggers { 789815dac33SEric Biggers if (attr->ia_valid & ATTR_SIZE) 790815dac33SEric Biggers return fscrypt_require_key(d_inode(dentry)); 791815dac33SEric Biggers return 0; 792815dac33SEric Biggers } 793815dac33SEric Biggers 79476e81d6dSEric Biggers /** 795d2fe9754SEric Biggers * fscrypt_encrypt_symlink() - encrypt the symlink target if needed 79676e81d6dSEric Biggers * @inode: symlink inode 79776e81d6dSEric Biggers * @target: plaintext symlink target 79876e81d6dSEric Biggers * @len: length of @target excluding null terminator 79976e81d6dSEric Biggers * @disk_link: (in/out) the on-disk symlink target being prepared 80076e81d6dSEric Biggers * 80176e81d6dSEric Biggers * If the symlink target needs to be encrypted, then this function encrypts it 80276e81d6dSEric Biggers * into @disk_link->name. fscrypt_prepare_symlink() must have been called 80376e81d6dSEric Biggers * previously to compute @disk_link->len. If the filesystem did not allocate a 80476e81d6dSEric Biggers * buffer for @disk_link->name after calling fscrypt_prepare_link(), then one 80576e81d6dSEric Biggers * will be kmalloc()'ed and the filesystem will be responsible for freeing it. 80676e81d6dSEric Biggers * 80776e81d6dSEric Biggers * Return: 0 on success, -errno on failure 80876e81d6dSEric Biggers */ 80976e81d6dSEric Biggers static inline int fscrypt_encrypt_symlink(struct inode *inode, 81076e81d6dSEric Biggers const char *target, 81176e81d6dSEric Biggers unsigned int len, 81276e81d6dSEric Biggers struct fscrypt_str *disk_link) 81376e81d6dSEric Biggers { 81476e81d6dSEric Biggers if (IS_ENCRYPTED(inode)) 81576e81d6dSEric Biggers return __fscrypt_encrypt_symlink(inode, target, len, disk_link); 81676e81d6dSEric Biggers return 0; 81776e81d6dSEric Biggers } 81876e81d6dSEric Biggers 819d2d0727bSEric Biggers /* If *pagep is a bounce page, free it and set *pagep to the pagecache page */ 820d2d0727bSEric Biggers static inline void fscrypt_finalize_bounce_page(struct page **pagep) 821d2d0727bSEric Biggers { 822d2d0727bSEric Biggers struct page *page = *pagep; 823d2d0727bSEric Biggers 824d2d0727bSEric Biggers if (fscrypt_is_bounce_page(page)) { 825d2d0727bSEric Biggers *pagep = fscrypt_pagecache_page(page); 826d2d0727bSEric Biggers fscrypt_free_bounce_page(page); 827d2d0727bSEric Biggers } 828d2d0727bSEric Biggers } 829d2d0727bSEric Biggers 830734f0d24SDave Chinner #endif /* _LINUX_FSCRYPT_H */ 831