aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2017-10-09 15:15:41 -0400
committerTheodore Ts'o <tytso@mit.edu>2017-10-18 19:52:38 -0400
commit0ea87a9644ebb5c9a3b100585d10533366de3269 (patch)
tree3934cd8c3a6f16ecbabd3b2909dba12bfde6b4ce
parentefcc7ae2c9172d9a7ae94afdaf066a7abf0b9a90 (diff)
fscrypt: new helper function - fscrypt_prepare_link()
Introduce a helper function which prepares to link an inode into a possibly-encrypted directory. It handles setting up the target directory's encryption key, then verifying that the link won't violate the constraint that all files in an encrypted directory tree use the same encryption policy. Acked-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--fs/crypto/hooks.c15
-rw-r--r--include/linux/fscrypt.h27
-rw-r--r--include/linux/fscrypt_notsupp.h6
-rw-r--r--include/linux/fscrypt_supp.h1
4 files changed, 49 insertions, 0 deletions
diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index 069088e91ea9..8b90217320dd 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -47,3 +47,18 @@ int fscrypt_file_open(struct inode *inode, struct file *filp)
47 return err; 47 return err;
48} 48}
49EXPORT_SYMBOL_GPL(fscrypt_file_open); 49EXPORT_SYMBOL_GPL(fscrypt_file_open);
50
51int __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}
64EXPORT_SYMBOL_GPL(__fscrypt_prepare_link);
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index b3e2a5f93415..9c9a53f99327 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -177,4 +177,31 @@ static inline int fscrypt_require_key(struct inode *inode)
177 return 0; 177 return 0;
178} 178}
179 179
180/**
181 * fscrypt_prepare_link - prepare to link an inode into a possibly-encrypted directory
182 * @old_dentry: an existing dentry for the inode being linked
183 * @dir: the target directory
184 * @dentry: negative dentry for the target filename
185 *
186 * A new link can only be added to an encrypted directory if the directory's
187 * encryption key is available --- since otherwise we'd have no way to encrypt
188 * the filename. Therefore, we first set up the directory's encryption key (if
189 * not already done) and return an error if it's unavailable.
190 *
191 * We also verify that the link will not violate the constraint that all files
192 * in an encrypted directory tree use the same encryption policy.
193 *
194 * Return: 0 on success, -ENOKEY if the directory's encryption key is missing,
195 * -EPERM if the link would result in an inconsistent encryption policy, or
196 * another -errno code.
197 */
198static inline int fscrypt_prepare_link(struct dentry *old_dentry,
199 struct inode *dir,
200 struct dentry *dentry)
201{
202 if (IS_ENCRYPTED(dir))
203 return __fscrypt_prepare_link(d_inode(old_dentry), dir);
204 return 0;
205}
206
180#endif /* _LINUX_FSCRYPT_H */ 207#endif /* _LINUX_FSCRYPT_H */
diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h
index 162da6517ac4..d7d1039eb6b5 100644
--- a/include/linux/fscrypt_notsupp.h
+++ b/include/linux/fscrypt_notsupp.h
@@ -186,4 +186,10 @@ static inline int fscrypt_file_open(struct inode *inode, struct file *filp)
186 return 0; 186 return 0;
187} 187}
188 188
189static inline int __fscrypt_prepare_link(struct inode *inode,
190 struct inode *dir)
191{
192 return -EOPNOTSUPP;
193}
194
189#endif /* _LINUX_FSCRYPT_NOTSUPP_H */ 195#endif /* _LINUX_FSCRYPT_NOTSUPP_H */
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index fd2f6decaee4..80706283da75 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -145,5 +145,6 @@ extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t,
145 145
146/* hooks.c */ 146/* hooks.c */
147extern int fscrypt_file_open(struct inode *inode, struct file *filp); 147extern int fscrypt_file_open(struct inode *inode, struct file *filp);
148extern int __fscrypt_prepare_link(struct inode *inode, struct inode *dir);
148 149
149#endif /* _LINUX_FSCRYPT_SUPP_H */ 150#endif /* _LINUX_FSCRYPT_SUPP_H */