Commit | Line | Data |
---|---|---|
efcc7ae2 EB |
1 | /* |
2 | * fs/crypto/hooks.c | |
3 | * | |
4 | * Encryption hooks for higher-level filesystem operations. | |
5 | */ | |
6 | ||
7 | #include <linux/ratelimit.h> | |
8 | #include "fscrypt_private.h" | |
9 | ||
10 | /** | |
11 | * fscrypt_file_open - prepare to open a possibly-encrypted regular file | |
12 | * @inode: the inode being opened | |
13 | * @filp: the struct file being set up | |
14 | * | |
15 | * Currently, an encrypted regular file can only be opened if its encryption key | |
16 | * is available; access to the raw encrypted contents is not supported. | |
17 | * Therefore, we first set up the inode's encryption key (if not already done) | |
18 | * and return an error if it's unavailable. | |
19 | * | |
20 | * We also verify that if the parent directory (from the path via which the file | |
21 | * is being opened) is encrypted, then the inode being opened uses the same | |
22 | * encryption policy. This is needed as part of the enforcement that all files | |
23 | * in an encrypted directory tree use the same encryption policy, as a | |
24 | * protection against certain types of offline attacks. Note that this check is | |
25 | * needed even when opening an *unencrypted* file, since it's forbidden to have | |
26 | * an unencrypted file in an encrypted directory. | |
27 | * | |
28 | * Return: 0 on success, -ENOKEY if the key is missing, or another -errno code | |
29 | */ | |
30 | int fscrypt_file_open(struct inode *inode, struct file *filp) | |
31 | { | |
32 | int err; | |
33 | struct dentry *dir; | |
34 | ||
35 | err = fscrypt_require_key(inode); | |
36 | if (err) | |
37 | return err; | |
38 | ||
39 | dir = dget_parent(file_dentry(filp)); | |
40 | if (IS_ENCRYPTED(d_inode(dir)) && | |
41 | !fscrypt_has_permitted_context(d_inode(dir), inode)) { | |
42 | pr_warn_ratelimited("fscrypt: inconsistent encryption contexts: %lu/%lu", | |
43 | d_inode(dir)->i_ino, inode->i_ino); | |
44 | err = -EPERM; | |
45 | } | |
46 | dput(dir); | |
47 | return err; | |
48 | } | |
49 | EXPORT_SYMBOL_GPL(fscrypt_file_open); | |
0ea87a96 EB |
50 | |
51 | int __fscrypt_prepare_link(struct inode *inode, struct inode *dir) | |
52 | { | |
53 | int err; | |
54 | ||
55 | err = fscrypt_require_key(dir); | |
56 | if (err) | |
57 | return err; | |
58 | ||
59 | if (!fscrypt_has_permitted_context(dir, inode)) | |
60 | return -EPERM; | |
61 | ||
62 | return 0; | |
63 | } | |
64 | EXPORT_SYMBOL_GPL(__fscrypt_prepare_link); |