| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * fs/crypto/hooks.c |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Encryption hooks for higher-level filesystem operations. |
|---|
| 5 | 6 | */ |
|---|
| 6 | | - |
|---|
| 7 | | -#include <linux/key.h> |
|---|
| 8 | 7 | |
|---|
| 9 | 8 | #include "fscrypt_private.h" |
|---|
| 10 | 9 | |
|---|
| .. | .. |
|---|
| 53 | 52 | int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, |
|---|
| 54 | 53 | struct dentry *dentry) |
|---|
| 55 | 54 | { |
|---|
| 56 | | - int err; |
|---|
| 57 | | - |
|---|
| 58 | | - err = fscrypt_require_key(dir); |
|---|
| 59 | | - if (err) |
|---|
| 60 | | - return err; |
|---|
| 61 | | - |
|---|
| 62 | | - /* ... in case we looked up no-key name before key was added */ |
|---|
| 63 | 55 | if (fscrypt_is_nokey_name(dentry)) |
|---|
| 64 | 56 | return -ENOKEY; |
|---|
| 57 | + /* |
|---|
| 58 | + * We don't need to separately check that the directory inode's key is |
|---|
| 59 | + * available, as it's implied by the dentry not being a no-key name. |
|---|
| 60 | + */ |
|---|
| 65 | 61 | |
|---|
| 66 | 62 | if (!fscrypt_has_permitted_context(dir, inode)) |
|---|
| 67 | 63 | return -EXDEV; |
|---|
| .. | .. |
|---|
| 74 | 70 | struct inode *new_dir, struct dentry *new_dentry, |
|---|
| 75 | 71 | unsigned int flags) |
|---|
| 76 | 72 | { |
|---|
| 77 | | - int err; |
|---|
| 78 | | - |
|---|
| 79 | | - err = fscrypt_require_key(old_dir); |
|---|
| 80 | | - if (err) |
|---|
| 81 | | - return err; |
|---|
| 82 | | - |
|---|
| 83 | | - err = fscrypt_require_key(new_dir); |
|---|
| 84 | | - if (err) |
|---|
| 85 | | - return err; |
|---|
| 86 | | - |
|---|
| 87 | | - /* ... in case we looked up no-key name(s) before key was added */ |
|---|
| 88 | 73 | if (fscrypt_is_nokey_name(old_dentry) || |
|---|
| 89 | 74 | fscrypt_is_nokey_name(new_dentry)) |
|---|
| 90 | 75 | return -ENOKEY; |
|---|
| 76 | + /* |
|---|
| 77 | + * We don't need to separately check that the directory inodes' keys are |
|---|
| 78 | + * available, as it's implied by the dentries not being no-key names. |
|---|
| 79 | + */ |
|---|
| 91 | 80 | |
|---|
| 92 | 81 | if (old_dir != new_dir) { |
|---|
| 93 | 82 | if (IS_ENCRYPTED(new_dir) && |
|---|
| .. | .. |
|---|
| 113 | 102 | if (err && err != -ENOENT) |
|---|
| 114 | 103 | return err; |
|---|
| 115 | 104 | |
|---|
| 116 | | - if (fname->is_ciphertext_name) { |
|---|
| 105 | + if (fname->is_nokey_name) { |
|---|
| 117 | 106 | spin_lock(&dentry->d_lock); |
|---|
| 118 | | - dentry->d_flags |= DCACHE_ENCRYPTED_NAME; |
|---|
| 107 | + dentry->d_flags |= DCACHE_NOKEY_NAME; |
|---|
| 119 | 108 | spin_unlock(&dentry->d_lock); |
|---|
| 120 | 109 | } |
|---|
| 121 | 110 | return err; |
|---|
| 122 | 111 | } |
|---|
| 123 | 112 | EXPORT_SYMBOL_GPL(__fscrypt_prepare_lookup); |
|---|
| 113 | + |
|---|
| 114 | +int __fscrypt_prepare_readdir(struct inode *dir) |
|---|
| 115 | +{ |
|---|
| 116 | + return fscrypt_get_encryption_info(dir, true); |
|---|
| 117 | +} |
|---|
| 118 | +EXPORT_SYMBOL_GPL(__fscrypt_prepare_readdir); |
|---|
| 119 | + |
|---|
| 120 | +int __fscrypt_prepare_setattr(struct dentry *dentry, struct iattr *attr) |
|---|
| 121 | +{ |
|---|
| 122 | + if (attr->ia_valid & ATTR_SIZE) |
|---|
| 123 | + return fscrypt_require_key(d_inode(dentry)); |
|---|
| 124 | + return 0; |
|---|
| 125 | +} |
|---|
| 126 | +EXPORT_SYMBOL_GPL(__fscrypt_prepare_setattr); |
|---|
| 124 | 127 | |
|---|
| 125 | 128 | /** |
|---|
| 126 | 129 | * fscrypt_prepare_setflags() - prepare to change flags with FS_IOC_SETFLAGS |
|---|
| .. | .. |
|---|
| 152 | 155 | ci = inode->i_crypt_info; |
|---|
| 153 | 156 | if (ci->ci_policy.version != FSCRYPT_POLICY_V2) |
|---|
| 154 | 157 | return -EINVAL; |
|---|
| 155 | | - mk = ci->ci_master_key->payload.data[0]; |
|---|
| 156 | | - down_read(&mk->mk_secret_sem); |
|---|
| 158 | + mk = ci->ci_master_key; |
|---|
| 159 | + down_read(&mk->mk_sem); |
|---|
| 157 | 160 | if (is_master_key_secret_present(&mk->mk_secret)) |
|---|
| 158 | 161 | err = fscrypt_derive_dirhash_key(ci, mk); |
|---|
| 159 | 162 | else |
|---|
| 160 | 163 | err = -ENOKEY; |
|---|
| 161 | | - up_read(&mk->mk_secret_sem); |
|---|
| 164 | + up_read(&mk->mk_sem); |
|---|
| 162 | 165 | return err; |
|---|
| 163 | 166 | } |
|---|
| 164 | 167 | return 0; |
|---|
| 165 | 168 | } |
|---|
| 166 | 169 | |
|---|
| 167 | | -int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len, |
|---|
| 168 | | - unsigned int max_len, |
|---|
| 169 | | - struct fscrypt_str *disk_link) |
|---|
| 170 | +/** |
|---|
| 171 | + * fscrypt_prepare_symlink() - prepare to create a possibly-encrypted symlink |
|---|
| 172 | + * @dir: directory in which the symlink is being created |
|---|
| 173 | + * @target: plaintext symlink target |
|---|
| 174 | + * @len: length of @target excluding null terminator |
|---|
| 175 | + * @max_len: space the filesystem has available to store the symlink target |
|---|
| 176 | + * @disk_link: (out) the on-disk symlink target being prepared |
|---|
| 177 | + * |
|---|
| 178 | + * This function computes the size the symlink target will require on-disk, |
|---|
| 179 | + * stores it in @disk_link->len, and validates it against @max_len. An |
|---|
| 180 | + * encrypted symlink may be longer than the original. |
|---|
| 181 | + * |
|---|
| 182 | + * Additionally, @disk_link->name is set to @target if the symlink will be |
|---|
| 183 | + * unencrypted, but left NULL if the symlink will be encrypted. For encrypted |
|---|
| 184 | + * symlinks, the filesystem must call fscrypt_encrypt_symlink() to create the |
|---|
| 185 | + * on-disk target later. (The reason for the two-step process is that some |
|---|
| 186 | + * filesystems need to know the size of the symlink target before creating the |
|---|
| 187 | + * inode, e.g. to determine whether it will be a "fast" or "slow" symlink.) |
|---|
| 188 | + * |
|---|
| 189 | + * Return: 0 on success, -ENAMETOOLONG if the symlink target is too long, |
|---|
| 190 | + * -ENOKEY if the encryption key is missing, or another -errno code if a problem |
|---|
| 191 | + * occurred while setting up the encryption key. |
|---|
| 192 | + */ |
|---|
| 193 | +int fscrypt_prepare_symlink(struct inode *dir, const char *target, |
|---|
| 194 | + unsigned int len, unsigned int max_len, |
|---|
| 195 | + struct fscrypt_str *disk_link) |
|---|
| 170 | 196 | { |
|---|
| 171 | | - int err; |
|---|
| 197 | + const union fscrypt_policy *policy; |
|---|
| 172 | 198 | |
|---|
| 173 | 199 | /* |
|---|
| 174 | 200 | * To calculate the size of the encrypted symlink target we need to know |
|---|
| 175 | 201 | * the amount of NUL padding, which is determined by the flags set in |
|---|
| 176 | 202 | * the encryption policy which will be inherited from the directory. |
|---|
| 177 | | - * The easiest way to get access to this is to just load the directory's |
|---|
| 178 | | - * fscrypt_info, since we'll need it to create the dir_entry anyway. |
|---|
| 179 | | - * |
|---|
| 180 | | - * Note: in test_dummy_encryption mode, @dir may be unencrypted. |
|---|
| 181 | 203 | */ |
|---|
| 182 | | - err = fscrypt_get_encryption_info(dir); |
|---|
| 183 | | - if (err) |
|---|
| 184 | | - return err; |
|---|
| 185 | | - if (!fscrypt_has_encryption_key(dir)) |
|---|
| 186 | | - return -ENOKEY; |
|---|
| 204 | + policy = fscrypt_policy_to_inherit(dir); |
|---|
| 205 | + if (policy == NULL) { |
|---|
| 206 | + /* Not encrypted */ |
|---|
| 207 | + disk_link->name = (unsigned char *)target; |
|---|
| 208 | + disk_link->len = len + 1; |
|---|
| 209 | + if (disk_link->len > max_len) |
|---|
| 210 | + return -ENAMETOOLONG; |
|---|
| 211 | + return 0; |
|---|
| 212 | + } |
|---|
| 213 | + if (IS_ERR(policy)) |
|---|
| 214 | + return PTR_ERR(policy); |
|---|
| 187 | 215 | |
|---|
| 188 | 216 | /* |
|---|
| 189 | 217 | * Calculate the size of the encrypted symlink and verify it won't |
|---|
| .. | .. |
|---|
| 196 | 224 | * counting it (even though it is meaningless for ciphertext) is simpler |
|---|
| 197 | 225 | * for now since filesystems will assume it is there and subtract it. |
|---|
| 198 | 226 | */ |
|---|
| 199 | | - if (!fscrypt_fname_encrypted_size(dir, len, |
|---|
| 227 | + if (!fscrypt_fname_encrypted_size(policy, len, |
|---|
| 200 | 228 | max_len - sizeof(struct fscrypt_symlink_data), |
|---|
| 201 | 229 | &disk_link->len)) |
|---|
| 202 | 230 | return -ENAMETOOLONG; |
|---|
| .. | .. |
|---|
| 205 | 233 | disk_link->name = NULL; |
|---|
| 206 | 234 | return 0; |
|---|
| 207 | 235 | } |
|---|
| 208 | | -EXPORT_SYMBOL_GPL(__fscrypt_prepare_symlink); |
|---|
| 236 | +EXPORT_SYMBOL_GPL(fscrypt_prepare_symlink); |
|---|
| 209 | 237 | |
|---|
| 210 | 238 | int __fscrypt_encrypt_symlink(struct inode *inode, const char *target, |
|---|
| 211 | 239 | unsigned int len, struct fscrypt_str *disk_link) |
|---|
| .. | .. |
|---|
| 215 | 243 | struct fscrypt_symlink_data *sd; |
|---|
| 216 | 244 | unsigned int ciphertext_len; |
|---|
| 217 | 245 | |
|---|
| 218 | | - err = fscrypt_require_key(inode); |
|---|
| 219 | | - if (err) |
|---|
| 220 | | - return err; |
|---|
| 246 | + /* |
|---|
| 247 | + * fscrypt_prepare_new_inode() should have already set up the new |
|---|
| 248 | + * symlink inode's encryption key. We don't wait until now to do it, |
|---|
| 249 | + * since we may be in a filesystem transaction now. |
|---|
| 250 | + */ |
|---|
| 251 | + if (WARN_ON_ONCE(!fscrypt_has_encryption_key(inode))) |
|---|
| 252 | + return -ENOKEY; |
|---|
| 221 | 253 | |
|---|
| 222 | 254 | if (disk_link->name) { |
|---|
| 223 | 255 | /* filesystem-provided buffer */ |
|---|
| .. | .. |
|---|
| 295 | 327 | * Try to set up the symlink's encryption key, but we can continue |
|---|
| 296 | 328 | * regardless of whether the key is available or not. |
|---|
| 297 | 329 | */ |
|---|
| 298 | | - err = fscrypt_get_encryption_info(inode); |
|---|
| 330 | + err = fscrypt_get_encryption_info(inode, false); |
|---|
| 299 | 331 | if (err) |
|---|
| 300 | 332 | return ERR_PTR(err); |
|---|
| 301 | 333 | has_key = fscrypt_has_encryption_key(inode); |
|---|
| .. | .. |
|---|
| 317 | 349 | if (cstr.len + sizeof(*sd) - 1 > max_size) |
|---|
| 318 | 350 | return ERR_PTR(-EUCLEAN); |
|---|
| 319 | 351 | |
|---|
| 320 | | - err = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr); |
|---|
| 352 | + err = fscrypt_fname_alloc_buffer(cstr.len, &pstr); |
|---|
| 321 | 353 | if (err) |
|---|
| 322 | 354 | return ERR_PTR(err); |
|---|
| 323 | 355 | |
|---|