| 1 | |
| 2 | |
| 3 | * eCryptfs: Linux filesystem encryption layer
|
| 4 | *
|
| 5 | * Copyright (C) 1997-2004 Erez Zadok
|
| 6 | * Copyright (C) 2001-2004 Stony Brook University
|
| 7 | * Copyright (C) 2004-2007 International Business Machines Corp.
|
| 8 | * Author(s): Michael A. Halcrow <[email protected]>
|
| 9 | * Michael C. Thompsion <[email protected]>
|
| 10 |
|
| 11 |
|
| 12 | #include <linux/file.h>
|
| 13 | #include <linux/vmalloc.h>
|
| 14 | #include <linux/pagemap.h>
|
| 15 | #include <linux/dcache.h>
|
| 16 | #include <linux/namei.h>
|
| 17 | #include <linux/mount.h>
|
| 18 | #include <linux/fs_stack.h>
|
| 19 | #include <linux/slab.h>
|
| 20 | #include <linux/xattr.h>
|
| 21 | #include <linux/posix_acl.h>
|
| 22 | #include <linux/posix_acl_xattr.h>
|
| 23 | #include <linux/fileattr.h>
|
| 24 | #include <linux/unaligned.h>
|
| 25 | #include "ecryptfs_kernel.h"
|
| 26 |
|
| 27 | static struct dentry *ecryptfs_start_creating_dentry(struct dentry *dentry)
|
| 28 | {
|
| 29 | struct dentry *parent = dget_parent(dentry);
|
| 30 | struct dentry *ret;
|
| 31 |
|
| 32 | ret = start_creating_dentry(ecryptfs_dentry_to_lower(parent),
|
| 33 | ecryptfs_dentry_to_lower(dentry));
|
| 34 | dput(parent);
|
| 35 | return ret;
|
| 36 | }
|
| 37 |
|
| 38 | static struct dentry *ecryptfs_start_removing_dentry(struct dentry *dentry)
|
| 39 | {
|
| 40 | struct dentry *parent = dget_parent(dentry);
|
| 41 | struct dentry *ret;
|
| 42 |
|
| 43 | ret = start_removing_dentry(ecryptfs_dentry_to_lower(parent),
|
| 44 | ecryptfs_dentry_to_lower(dentry));
|
| 45 | dput(parent);
|
| 46 | return ret;
|
| 47 | }
|
| 48 |
|
| 49 | static int ecryptfs_inode_test(struct inode *inode, void *lower_inode)
|
| 50 | {
|
| 51 | return ecryptfs_inode_to_lower(inode) == lower_inode;
|
| 52 | }
|
| 53 |
|
| 54 | static int ecryptfs_inode_set(struct inode *inode, void *opaque)
|
| 55 | {
|
| 56 | struct inode *lower_inode = opaque;
|
| 57 |
|
| 58 | ecryptfs_set_inode_lower(inode, lower_inode);
|
| 59 | fsstack_copy_attr_all(inode, lower_inode);
|
| 60 |
|
| 61 | fsstack_copy_inode_size(inode, lower_inode);
|
| 62 | inode->i_ino = lower_inode->i_ino;
|
| 63 | inode->i_mapping->a_ops = &ecryptfs_aops;
|
| 64 |
|
| 65 | if (S_ISLNK(inode->i_mode))
|
| 66 | inode->i_op = &ecryptfs_symlink_iops;
|
| 67 | else if (S_ISDIR(inode->i_mode))
|
| 68 | inode->i_op = &ecryptfs_dir_iops;
|
| 69 | else
|
| 70 | inode->i_op = &ecryptfs_main_iops;
|
| 71 |
|
| 72 | if (S_ISDIR(inode->i_mode))
|
| 73 | inode->i_fop = &ecryptfs_dir_fops;
|
| 74 | else if (special_file(inode->i_mode))
|
| 75 | init_special_inode(inode, inode->i_mode, inode->i_rdev);
|
| 76 | else
|
| 77 | inode->i_fop = &ecryptfs_main_fops;
|
| 78 |
|
| 79 | return 0;
|
| 80 | }
|
| 81 |
|
| 82 | static struct inode *__ecryptfs_get_inode(struct inode *lower_inode,
|
| 83 | struct super_block *sb)
|
| 84 | {
|
| 85 | struct inode *inode;
|
| 86 |
|
| 87 | if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb))
|
| 88 | return ERR_PTR(-EXDEV);
|
| 89 |
|
| 90 |
|
| 91 | if (IS_CASEFOLDED(lower_inode)) {
|
| 92 | pr_err_ratelimited("%s: Can't handle casefolded directory.\n",
|
| 93 | __func__);
|
| 94 | return ERR_PTR(-EREMOTE);
|
| 95 | }
|
| 96 |
|
| 97 | if (!igrab(lower_inode))
|
| 98 | return ERR_PTR(-ESTALE);
|
| 99 | inode = iget5_locked(sb, (unsigned long)lower_inode,
|
| 100 | ecryptfs_inode_test, ecryptfs_inode_set,
|
| 101 | lower_inode);
|
| 102 | if (!inode) {
|
| 103 | iput(lower_inode);
|
| 104 | return ERR_PTR(-EACCES);
|
| 105 | }
|
| 106 | if (!(inode_state_read_once(inode) & I_NEW))
|
| 107 | iput(lower_inode);
|
| 108 |
|
| 109 | return inode;
|
| 110 | }
|
| 111 |
|
| 112 | struct inode *ecryptfs_get_inode(struct inode *lower_inode,
|
| 113 | struct super_block *sb)
|
| 114 | {
|
| 115 | struct inode *inode = __ecryptfs_get_inode(lower_inode, sb);
|
| 116 |
|
| 117 | if (!IS_ERR(inode) && (inode_state_read_once(inode) & I_NEW))
|
| 118 | unlock_new_inode(inode);
|
| 119 |
|
| 120 | return inode;
|
| 121 | }
|
| 122 |
|
| 123 | |
| 124 | * ecryptfs_interpose
|
| 125 | * @lower_dentry: Existing dentry in the lower filesystem
|
| 126 | * @dentry: ecryptfs' dentry
|
| 127 | * @sb: ecryptfs's super_block
|
| 128 | *
|
| 129 | * Interposes upper and lower dentries.
|
| 130 | *
|
| 131 | * Returns zero on success; non-zero otherwise
|
| 132 |
|
| 133 | static int ecryptfs_interpose(struct dentry *lower_dentry,
|
| 134 | struct dentry *dentry, struct super_block *sb)
|
| 135 | {
|
| 136 | struct inode *inode = ecryptfs_get_inode(d_inode(lower_dentry), sb);
|
| 137 |
|
| 138 | if (IS_ERR(inode))
|
| 139 | return PTR_ERR(inode);
|
| 140 | d_instantiate(dentry, inode);
|
| 141 |
|
| 142 | return 0;
|
| 143 | }
|
| 144 |
|
| 145 | static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry,
|
| 146 | struct inode *inode)
|
| 147 | {
|
| 148 | struct dentry *lower_dentry;
|
| 149 | struct inode *lower_dir;
|
| 150 | int rc;
|
| 151 |
|
| 152 | lower_dentry = ecryptfs_start_removing_dentry(dentry);
|
| 153 | if (IS_ERR(lower_dentry))
|
| 154 | return PTR_ERR(lower_dentry);
|
| 155 |
|
| 156 | lower_dir = lower_dentry->d_parent->d_inode;
|
| 157 | rc = vfs_unlink(&nop_mnt_idmap, lower_dir, lower_dentry, NULL);
|
| 158 | if (rc) {
|
| 159 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
|
| 160 | goto out_unlock;
|
| 161 | }
|
| 162 | fsstack_copy_attr_times(dir, lower_dir);
|
| 163 | set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink);
|
| 164 | inode_set_ctime_to_ts(inode, inode_get_ctime(dir));
|
| 165 | out_unlock:
|
| 166 | end_removing(lower_dentry);
|
| 167 | if (!rc)
|
| 168 | d_drop(dentry);
|
| 169 | return rc;
|
| 170 | }
|
| 171 |
|
| 172 | |
| 173 | * ecryptfs_do_create
|
| 174 | * @directory_inode: inode of the new file's dentry's parent in ecryptfs
|
| 175 | * @ecryptfs_dentry: New file's dentry in ecryptfs
|
| 176 | * @mode: The mode of the new file
|
| 177 | *
|
| 178 | * Creates the underlying file and the eCryptfs inode which will link to
|
| 179 | * it. It will also update the eCryptfs directory inode to mimic the
|
| 180 | * stat of the lower directory inode.
|
| 181 | *
|
| 182 | * Returns the new eCryptfs inode on success; an ERR_PTR on error condition
|
| 183 |
|
| 184 | static struct inode *
|
| 185 | ecryptfs_do_create(struct inode *directory_inode,
|
| 186 | struct dentry *ecryptfs_dentry, umode_t mode)
|
| 187 | {
|
| 188 | int rc;
|
| 189 | struct dentry *lower_dentry;
|
| 190 | struct inode *lower_dir;
|
| 191 | struct inode *inode;
|
| 192 |
|
| 193 | lower_dentry = ecryptfs_start_creating_dentry(ecryptfs_dentry);
|
| 194 | if (IS_ERR(lower_dentry))
|
| 195 | return ERR_CAST(lower_dentry);
|
| 196 | lower_dir = lower_dentry->d_parent->d_inode;
|
| 197 | rc = vfs_create(&nop_mnt_idmap, lower_dentry, mode, NULL);
|
| 198 | if (rc) {
|
| 199 | printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
|
| 200 | "rc = [%d]\n", __func__, rc);
|
| 201 | inode = ERR_PTR(rc);
|
| 202 | goto out_lock;
|
| 203 | }
|
| 204 | inode = __ecryptfs_get_inode(d_inode(lower_dentry),
|
| 205 | directory_inode->i_sb);
|
| 206 | if (IS_ERR(inode)) {
|
| 207 | vfs_unlink(&nop_mnt_idmap, lower_dir, lower_dentry, NULL);
|
| 208 | goto out_lock;
|
| 209 | }
|
| 210 | fsstack_copy_attr_times(directory_inode, lower_dir);
|
| 211 | fsstack_copy_inode_size(directory_inode, lower_dir);
|
| 212 | out_lock:
|
| 213 | end_creating(lower_dentry);
|
| 214 | return inode;
|
| 215 | }
|
| 216 |
|
| 217 | |
| 218 | * ecryptfs_initialize_file
|
| 219 | *
|
| 220 | * Cause the file to be changed from a basic empty file to an ecryptfs
|
| 221 | * file with a header and first data page.
|
| 222 | *
|
| 223 | * Returns zero on success
|
| 224 |
|
| 225 | int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry,
|
| 226 | struct inode *ecryptfs_inode)
|
| 227 | {
|
| 228 | struct ecryptfs_crypt_stat *crypt_stat =
|
| 229 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
|
| 230 | int rc = 0;
|
| 231 |
|
| 232 | if (S_ISDIR(ecryptfs_inode->i_mode)) {
|
| 233 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
|
| 234 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
|
| 235 | goto out;
|
| 236 | }
|
| 237 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n");
|
| 238 | rc = ecryptfs_new_file_context(ecryptfs_inode);
|
| 239 | if (rc) {
|
| 240 | ecryptfs_printk(KERN_ERR, "Error creating new file "
|
| 241 | "context; rc = [%d]\n", rc);
|
| 242 | goto out;
|
| 243 | }
|
| 244 | rc = ecryptfs_get_lower_file(ecryptfs_dentry, ecryptfs_inode);
|
| 245 | if (rc) {
|
| 246 | printk(KERN_ERR "%s: Error attempting to initialize "
|
| 247 | "the lower file for the dentry with name "
|
| 248 | "[%pd]; rc = [%d]\n", __func__,
|
| 249 | ecryptfs_dentry, rc);
|
| 250 | goto out;
|
| 251 | }
|
| 252 | rc = ecryptfs_write_metadata(ecryptfs_dentry, ecryptfs_inode);
|
| 253 | if (rc)
|
| 254 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc);
|
| 255 | ecryptfs_put_lower_file(ecryptfs_inode);
|
| 256 | out:
|
| 257 | return rc;
|
| 258 | }
|
| 259 |
|
| 260 | |
| 261 | * ecryptfs_create
|
| 262 | * @mode: The mode of the new file.
|
| 263 | *
|
| 264 | * Creates a new file.
|
| 265 | *
|
| 266 | * Returns zero on success; non-zero on error condition
|
| 267 |
|
| 268 | static int
|
| 269 | ecryptfs_create(const struct mnt_idmap *idmap,
|
| 270 | struct inode *directory_inode, struct dentry *ecryptfs_dentry,
|
| 271 | umode_t mode)
|
| 272 | {
|
| 273 | struct inode *ecryptfs_inode;
|
| 274 | int rc;
|
| 275 |
|
| 276 | ecryptfs_inode = ecryptfs_do_create(directory_inode, ecryptfs_dentry,
|
| 277 | mode);
|
| 278 | if (IS_ERR(ecryptfs_inode)) {
|
| 279 | ecryptfs_printk(KERN_WARNING, "Failed to create file in"
|
| 280 | "lower filesystem\n");
|
| 281 | rc = PTR_ERR(ecryptfs_inode);
|
| 282 | goto out;
|
| 283 | }
|
| 284 | |
| 285 | * that this on disk file is prepared to be an ecryptfs file
|
| 286 | rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode);
|
| 287 | if (rc) {
|
| 288 | ecryptfs_do_unlink(directory_inode, ecryptfs_dentry,
|
| 289 | ecryptfs_inode);
|
| 290 | iget_failed(ecryptfs_inode);
|
| 291 | goto out;
|
| 292 | }
|
| 293 | d_instantiate_new(ecryptfs_dentry, ecryptfs_inode);
|
| 294 | out:
|
| 295 | return rc;
|
| 296 | }
|
| 297 |
|
| 298 | static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode)
|
| 299 | {
|
| 300 | struct ecryptfs_crypt_stat *crypt_stat;
|
| 301 | int rc;
|
| 302 |
|
| 303 | rc = ecryptfs_get_lower_file(dentry, inode);
|
| 304 | if (rc) {
|
| 305 | printk(KERN_ERR "%s: Error attempting to initialize "
|
| 306 | "the lower file for the dentry with name "
|
| 307 | "[%pd]; rc = [%d]\n", __func__,
|
| 308 | dentry, rc);
|
| 309 | return rc;
|
| 310 | }
|
| 311 |
|
| 312 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
|
| 313 |
|
| 314 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED))
|
| 315 | ecryptfs_set_default_sizes(crypt_stat);
|
| 316 |
|
| 317 | rc = ecryptfs_read_and_validate_header_region(inode);
|
| 318 | ecryptfs_put_lower_file(inode);
|
| 319 | if (rc) {
|
| 320 | rc = ecryptfs_read_and_validate_xattr_region(dentry, inode);
|
| 321 | if (!rc)
|
| 322 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
|
| 323 | }
|
| 324 |
|
| 325 |
|
| 326 | return 0;
|
| 327 | }
|
| 328 |
|
| 329 | |
| 330 | * ecryptfs_lookup_interpose - Dentry interposition for a lookup
|
| 331 |
|
| 332 | static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry,
|
| 333 | struct dentry *lower_dentry)
|
| 334 | {
|
| 335 | struct dentry *lower_parent = ecryptfs_dentry_to_lower(dentry->d_parent);
|
| 336 | struct inode *inode, *lower_inode;
|
| 337 | int rc = 0;
|
| 338 |
|
| 339 | fsstack_copy_attr_atime(d_inode(dentry->d_parent),
|
| 340 | d_inode(lower_parent));
|
| 341 | BUG_ON(!d_count(lower_dentry));
|
| 342 |
|
| 343 | ecryptfs_set_dentry_lower(dentry, lower_dentry);
|
| 344 |
|
| 345 | |
| 346 | * negative dentry can go positive under us here - its parent is not
|
| 347 | * locked. That's OK and that could happen just as we return from
|
| 348 | * ecryptfs_lookup() anyway. Just need to be careful and fetch
|
| 349 | * ->d_inode only once - it's not stable here.
|
| 350 |
|
| 351 | lower_inode = READ_ONCE(lower_dentry->d_inode);
|
| 352 |
|
| 353 | if (!lower_inode)
|
| 354 | return d_splice_alias(NULL, dentry);
|
| 355 |
|
| 356 | inode = __ecryptfs_get_inode(lower_inode, dentry->d_sb);
|
| 357 | if (IS_ERR(inode)) {
|
| 358 | printk(KERN_ERR "%s: Error interposing; rc = [%ld]\n",
|
| 359 | __func__, PTR_ERR(inode));
|
| 360 | return ERR_CAST(inode);
|
| 361 | }
|
| 362 | if (S_ISREG(inode->i_mode)) {
|
| 363 | rc = ecryptfs_i_size_read(dentry, inode);
|
| 364 | if (rc) {
|
| 365 | make_bad_inode(inode);
|
| 366 | return ERR_PTR(rc);
|
| 367 | }
|
| 368 | }
|
| 369 |
|
| 370 | if (inode_state_read_once(inode) & I_NEW)
|
| 371 | unlock_new_inode(inode);
|
| 372 | return d_splice_alias(inode, dentry);
|
| 373 | }
|
| 374 |
|
| 375 | |
| 376 | * ecryptfs_lookup
|
| 377 | * @ecryptfs_dir_inode: The eCryptfs directory inode
|
| 378 | * @ecryptfs_dentry: The eCryptfs dentry that we are looking up
|
| 379 | * @flags: lookup flags
|
| 380 | *
|
| 381 | * Find a file on disk. If the file does not exist, then we'll add it to the
|
| 382 | * dentry cache and continue on to read it from the disk.
|
| 383 |
|
| 384 | static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
|
| 385 | struct dentry *ecryptfs_dentry,
|
| 386 | unsigned int flags)
|
| 387 | {
|
| 388 | char *encrypted_and_encoded_name = NULL;
|
| 389 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
|
| 390 | struct dentry *lower_dir_dentry, *lower_dentry;
|
| 391 | struct qstr qname = QSTR_INIT(ecryptfs_dentry->d_name.name,
|
| 392 | ecryptfs_dentry->d_name.len);
|
| 393 | struct dentry *res;
|
| 394 | int rc = 0;
|
| 395 |
|
| 396 | lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent);
|
| 397 |
|
| 398 | mount_crypt_stat = &ecryptfs_superblock_to_private(
|
| 399 | ecryptfs_dentry->d_sb)->mount_crypt_stat;
|
| 400 | if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
|
| 401 | size_t len = qname.len;
|
| 402 | rc = ecryptfs_encrypt_and_encode_filename(
|
| 403 | &encrypted_and_encoded_name, &len,
|
| 404 | mount_crypt_stat, qname.name, len);
|
| 405 | if (rc) {
|
| 406 | printk(KERN_ERR "%s: Error attempting to encrypt and encode "
|
| 407 | "filename; rc = [%d]\n", __func__, rc);
|
| 408 | return ERR_PTR(rc);
|
| 409 | }
|
| 410 | qname.name = encrypted_and_encoded_name;
|
| 411 | qname.len = len;
|
| 412 | }
|
| 413 |
|
| 414 | lower_dentry = lookup_noperm_unlocked(&qname, lower_dir_dentry);
|
| 415 | if (IS_ERR(lower_dentry)) {
|
| 416 | ecryptfs_printk(KERN_DEBUG, "%s: lookup_noperm() returned "
|
| 417 | "[%ld] on lower_dentry = [%s]\n", __func__,
|
| 418 | PTR_ERR(lower_dentry),
|
| 419 | qname.name);
|
| 420 | res = ERR_CAST(lower_dentry);
|
| 421 | } else {
|
| 422 | res = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry);
|
| 423 | }
|
| 424 | kfree(encrypted_and_encoded_name);
|
| 425 | return res;
|
| 426 | }
|
| 427 |
|
| 428 | static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
|
| 429 | struct dentry *new_dentry)
|
| 430 | {
|
| 431 | struct dentry *lower_old_dentry;
|
| 432 | struct dentry *lower_new_dentry;
|
| 433 | struct inode *lower_dir;
|
| 434 | u64 file_size_save;
|
| 435 | int rc;
|
| 436 |
|
| 437 | file_size_save = i_size_read(d_inode(old_dentry));
|
| 438 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
|
| 439 | lower_new_dentry = ecryptfs_start_creating_dentry(new_dentry);
|
| 440 | if (IS_ERR(lower_new_dentry))
|
| 441 | return PTR_ERR(lower_new_dentry);
|
| 442 | lower_dir = lower_new_dentry->d_parent->d_inode;
|
| 443 | rc = vfs_link(lower_old_dentry, &nop_mnt_idmap, lower_dir,
|
| 444 | lower_new_dentry, NULL);
|
| 445 | if (rc || d_really_is_negative(lower_new_dentry))
|
| 446 | goto out_lock;
|
| 447 | rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb);
|
| 448 | if (rc)
|
| 449 | goto out_lock;
|
| 450 | fsstack_copy_attr_times(dir, lower_dir);
|
| 451 | fsstack_copy_inode_size(dir, lower_dir);
|
| 452 | set_nlink(d_inode(old_dentry),
|
| 453 | ecryptfs_inode_to_lower(d_inode(old_dentry))->i_nlink);
|
| 454 | i_size_write(d_inode(new_dentry), file_size_save);
|
| 455 | out_lock:
|
| 456 | end_creating(lower_new_dentry);
|
| 457 | return rc;
|
| 458 | }
|
| 459 |
|
| 460 | static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
|
| 461 | {
|
| 462 | return ecryptfs_do_unlink(dir, dentry, d_inode(dentry));
|
| 463 | }
|
| 464 |
|
| 465 | static int ecryptfs_symlink(const struct mnt_idmap *idmap,
|
| 466 | struct inode *dir, struct dentry *dentry,
|
| 467 | const char *symname)
|
| 468 | {
|
| 469 | int rc;
|
| 470 | struct dentry *lower_dentry;
|
| 471 | struct inode *lower_dir;
|
| 472 | char *encoded_symname;
|
| 473 | size_t encoded_symlen;
|
| 474 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL;
|
| 475 |
|
| 476 | lower_dentry = ecryptfs_start_creating_dentry(dentry);
|
| 477 | if (IS_ERR(lower_dentry))
|
| 478 | return PTR_ERR(lower_dentry);
|
| 479 | lower_dir = lower_dentry->d_parent->d_inode;
|
| 480 |
|
| 481 | mount_crypt_stat = &ecryptfs_superblock_to_private(
|
| 482 | dir->i_sb)->mount_crypt_stat;
|
| 483 | rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname,
|
| 484 | &encoded_symlen,
|
| 485 | mount_crypt_stat, symname,
|
| 486 | strlen(symname));
|
| 487 | if (rc)
|
| 488 | goto out_lock;
|
| 489 | rc = vfs_symlink(&nop_mnt_idmap, lower_dir, lower_dentry,
|
| 490 | encoded_symname, NULL);
|
| 491 | kfree(encoded_symname);
|
| 492 | if (rc || d_really_is_negative(lower_dentry))
|
| 493 | goto out_lock;
|
| 494 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
|
| 495 | if (rc)
|
| 496 | goto out_lock;
|
| 497 | fsstack_copy_attr_times(dir, lower_dir);
|
| 498 | fsstack_copy_inode_size(dir, lower_dir);
|
| 499 | out_lock:
|
| 500 | end_creating(lower_dentry);
|
| 501 | if (d_really_is_negative(dentry))
|
| 502 | d_drop(dentry);
|
| 503 | return rc;
|
| 504 | }
|
| 505 |
|
| 506 | static struct dentry *ecryptfs_mkdir(const struct mnt_idmap *idmap, struct inode *dir,
|
| 507 | struct dentry *dentry, umode_t mode)
|
| 508 | {
|
| 509 | int rc;
|
| 510 | struct dentry *lower_dentry;
|
| 511 | struct dentry *lower_dir_dentry;
|
| 512 | struct inode *lower_dir;
|
| 513 |
|
| 514 | lower_dentry = ecryptfs_start_creating_dentry(dentry);
|
| 515 | if (IS_ERR(lower_dentry))
|
| 516 | return lower_dentry;
|
| 517 | lower_dir_dentry = dget(lower_dentry->d_parent);
|
| 518 | lower_dir = lower_dir_dentry->d_inode;
|
| 519 | lower_dentry = vfs_mkdir(&nop_mnt_idmap, lower_dir,
|
| 520 | lower_dentry, mode, NULL);
|
| 521 | rc = PTR_ERR(lower_dentry);
|
| 522 | if (IS_ERR(lower_dentry))
|
| 523 | goto out;
|
| 524 | rc = 0;
|
| 525 | if (d_unhashed(lower_dentry))
|
| 526 | goto out;
|
| 527 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
|
| 528 | if (rc)
|
| 529 | goto out;
|
| 530 | fsstack_copy_attr_times(dir, lower_dir);
|
| 531 | fsstack_copy_inode_size(dir, lower_dir);
|
| 532 | set_nlink(dir, lower_dir->i_nlink);
|
| 533 | out:
|
| 534 | dput(lower_dir_dentry);
|
| 535 | end_creating(lower_dentry);
|
| 536 | if (d_really_is_negative(dentry))
|
| 537 | d_drop(dentry);
|
| 538 | return ERR_PTR(rc);
|
| 539 | }
|
| 540 |
|
| 541 | static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
|
| 542 | {
|
| 543 | struct dentry *lower_dentry;
|
| 544 | struct inode *lower_dir;
|
| 545 | int rc;
|
| 546 |
|
| 547 | lower_dentry = ecryptfs_start_removing_dentry(dentry);
|
| 548 | if (IS_ERR(lower_dentry))
|
| 549 | return PTR_ERR(lower_dentry);
|
| 550 | lower_dir = lower_dentry->d_parent->d_inode;
|
| 551 |
|
| 552 | rc = vfs_rmdir(&nop_mnt_idmap, lower_dir, lower_dentry, NULL);
|
| 553 | if (!rc) {
|
| 554 | clear_nlink(d_inode(dentry));
|
| 555 | fsstack_copy_attr_times(dir, lower_dir);
|
| 556 | set_nlink(dir, lower_dir->i_nlink);
|
| 557 | }
|
| 558 | end_removing(lower_dentry);
|
| 559 | if (!rc)
|
| 560 | d_drop(dentry);
|
| 561 | return rc;
|
| 562 | }
|
| 563 |
|
| 564 | static int
|
| 565 | ecryptfs_mknod(const struct mnt_idmap *idmap, struct inode *dir,
|
| 566 | struct dentry *dentry, umode_t mode, dev_t dev)
|
| 567 | {
|
| 568 | int rc;
|
| 569 | struct dentry *lower_dentry;
|
| 570 | struct inode *lower_dir;
|
| 571 |
|
| 572 | lower_dentry = ecryptfs_start_creating_dentry(dentry);
|
| 573 | if (IS_ERR(lower_dentry))
|
| 574 | return PTR_ERR(lower_dentry);
|
| 575 | lower_dir = lower_dentry->d_parent->d_inode;
|
| 576 |
|
| 577 | rc = vfs_mknod(&nop_mnt_idmap, lower_dir, lower_dentry, mode, dev, NULL);
|
| 578 | if (rc || d_really_is_negative(lower_dentry))
|
| 579 | goto out;
|
| 580 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
|
| 581 | if (rc)
|
| 582 | goto out;
|
| 583 | fsstack_copy_attr_times(dir, lower_dir);
|
| 584 | fsstack_copy_inode_size(dir, lower_dir);
|
| 585 | out:
|
| 586 | end_creating(lower_dentry);
|
| 587 | if (d_really_is_negative(dentry))
|
| 588 | d_drop(dentry);
|
| 589 | return rc;
|
| 590 | }
|
| 591 |
|
| 592 | static int
|
| 593 | ecryptfs_rename(const struct mnt_idmap *idmap, struct inode *old_dir,
|
| 594 | struct dentry *old_dentry, struct inode *new_dir,
|
| 595 | struct dentry *new_dentry, unsigned int flags)
|
| 596 | {
|
| 597 | int rc;
|
| 598 | struct dentry *lower_old_dentry;
|
| 599 | struct dentry *lower_new_dentry;
|
| 600 | struct dentry *lower_old_dir_dentry;
|
| 601 | struct dentry *lower_new_dir_dentry;
|
| 602 | struct inode *target_inode;
|
| 603 | struct renamedata rd = {};
|
| 604 |
|
| 605 | if (flags)
|
| 606 | return -EINVAL;
|
| 607 |
|
| 608 | lower_old_dir_dentry = ecryptfs_dentry_to_lower(old_dentry->d_parent);
|
| 609 | lower_new_dir_dentry = ecryptfs_dentry_to_lower(new_dentry->d_parent);
|
| 610 |
|
| 611 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
|
| 612 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
|
| 613 |
|
| 614 | target_inode = d_inode(new_dentry);
|
| 615 |
|
| 616 | rd.mnt_idmap = &nop_mnt_idmap;
|
| 617 | rd.old_parent = lower_old_dir_dentry;
|
| 618 | rd.new_parent = lower_new_dir_dentry;
|
| 619 | rc = start_renaming_two_dentries(&rd, lower_old_dentry, lower_new_dentry);
|
| 620 | if (rc)
|
| 621 | return rc;
|
| 622 |
|
| 623 | rc = vfs_rename(&rd);
|
| 624 | if (rc)
|
| 625 | goto out_lock;
|
| 626 | if (target_inode)
|
| 627 | fsstack_copy_attr_all(target_inode,
|
| 628 | ecryptfs_inode_to_lower(target_inode));
|
| 629 | fsstack_copy_attr_all(new_dir, d_inode(lower_new_dir_dentry));
|
| 630 | if (new_dir != old_dir)
|
| 631 | fsstack_copy_attr_all(old_dir, d_inode(lower_old_dir_dentry));
|
| 632 | out_lock:
|
| 633 | end_renaming(&rd);
|
| 634 | return rc;
|
| 635 | }
|
| 636 |
|
| 637 | static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz)
|
| 638 | {
|
| 639 | DEFINE_DELAYED_CALL(done);
|
| 640 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
| 641 | const char *link;
|
| 642 | char *buf;
|
| 643 | int rc;
|
| 644 |
|
| 645 | link = vfs_get_link(lower_dentry, &done);
|
| 646 | if (IS_ERR(link))
|
| 647 | return ERR_CAST(link);
|
| 648 |
|
| 649 | rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb,
|
| 650 | link, strlen(link));
|
| 651 | do_delayed_call(&done);
|
| 652 | if (rc)
|
| 653 | return ERR_PTR(rc);
|
| 654 |
|
| 655 | return buf;
|
| 656 | }
|
| 657 |
|
| 658 | static const char *ecryptfs_get_link(struct dentry *dentry,
|
| 659 | struct inode *inode,
|
| 660 | struct delayed_call *done)
|
| 661 | {
|
| 662 | size_t len;
|
| 663 | char *buf;
|
| 664 |
|
| 665 | if (!dentry)
|
| 666 | return ERR_PTR(-ECHILD);
|
| 667 |
|
| 668 | buf = ecryptfs_readlink_lower(dentry, &len);
|
| 669 | if (IS_ERR(buf))
|
| 670 | return buf;
|
| 671 | fsstack_copy_attr_atime(d_inode(dentry),
|
| 672 | d_inode(ecryptfs_dentry_to_lower(dentry)));
|
| 673 | buf[len] = '\0';
|
| 674 | set_delayed_call(done, kfree_link, buf);
|
| 675 | return buf;
|
| 676 | }
|
| 677 |
|
| 678 | static void ecryptfs_iattr_to_lower(struct iattr *lower_ia,
|
| 679 | const struct iattr *ia)
|
| 680 | {
|
| 681 | memcpy(lower_ia, ia, sizeof(*lower_ia));
|
| 682 | if (ia->ia_valid & ATTR_FILE)
|
| 683 | lower_ia->ia_file = ecryptfs_file_to_lower(ia->ia_file);
|
| 684 | |
| 685 | * If the mode change is for clearing setuid/setgid bits, allow the lower
|
| 686 | * file system to interpret this in its own way.
|
| 687 |
|
| 688 | if (lower_ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
|
| 689 | lower_ia->ia_valid &= ~ATTR_MODE;
|
| 690 | }
|
| 691 |
|
| 692 | |
| 693 | * upper_size_to_lower_size
|
| 694 | * @crypt_stat: Crypt_stat associated with file
|
| 695 | * @upper_size: Size of the upper file
|
| 696 | *
|
| 697 | * Calculate the required size of the lower file based on the
|
| 698 | * specified size of the upper file. This calculation is based on the
|
| 699 | * number of headers in the underlying file and the extent size.
|
| 700 | *
|
| 701 | * Returns Calculated size of the lower file.
|
| 702 |
|
| 703 | static loff_t
|
| 704 | upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
|
| 705 | loff_t upper_size)
|
| 706 | {
|
| 707 | loff_t lower_size;
|
| 708 |
|
| 709 | lower_size = ecryptfs_lower_header_size(crypt_stat);
|
| 710 | if (upper_size != 0) {
|
| 711 | loff_t num_extents;
|
| 712 |
|
| 713 | num_extents = upper_size >> crypt_stat->extent_shift;
|
| 714 | if (upper_size & ~crypt_stat->extent_mask)
|
| 715 | num_extents++;
|
| 716 | lower_size += (num_extents * crypt_stat->extent_size);
|
| 717 | }
|
| 718 | return lower_size;
|
| 719 | }
|
| 720 |
|
| 721 | |
| 722 | * __ecryptfs_truncate
|
| 723 | * @dentry: The ecryptfs layer dentry
|
| 724 | * @ia: Address of the ecryptfs inode's attributes
|
| 725 | *
|
| 726 | * Handle truncations modifying the size of the file. Note that the file sizes
|
| 727 | * are interpolated. When expanding, we are simply writing strings of 0's out.
|
| 728 | * When truncating, we truncate the upper inode and update the lower_ia
|
| 729 | * according to the page index interpolations.
|
| 730 | *
|
| 731 | * Returns zero on success; non-zero otherwise
|
| 732 |
|
| 733 | static int __ecryptfs_truncate(struct dentry *dentry, const struct iattr *ia)
|
| 734 | {
|
| 735 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
| 736 | struct inode *inode = d_inode(dentry);
|
| 737 | struct ecryptfs_crypt_stat *crypt_stat;
|
| 738 | loff_t i_size = i_size_read(inode);
|
| 739 | loff_t lower_size_before_truncate;
|
| 740 | loff_t lower_size_after_truncate;
|
| 741 | struct iattr lower_ia;
|
| 742 | size_t num_zeros;
|
| 743 | int rc;
|
| 744 |
|
| 745 | ecryptfs_iattr_to_lower(&lower_ia, ia);
|
| 746 |
|
| 747 | if (unlikely((ia->ia_size == i_size)))
|
| 748 | return 0;
|
| 749 |
|
| 750 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
|
| 751 | lower_size_before_truncate =
|
| 752 | upper_size_to_lower_size(crypt_stat, i_size);
|
| 753 | lower_size_after_truncate =
|
| 754 | upper_size_to_lower_size(crypt_stat, ia->ia_size);
|
| 755 | if (lower_size_after_truncate > lower_size_before_truncate) {
|
| 756 | |
| 757 | * The eCryptfs inode and the new *lower* size are mixed here
|
| 758 | * because we may not have the lower i_mutex held and/or it may
|
| 759 | * not be appropriate to call inode_newsize_ok() with inodes
|
| 760 | * from other filesystems.
|
| 761 |
|
| 762 | rc = inode_newsize_ok(inode, lower_size_after_truncate);
|
| 763 | if (rc)
|
| 764 | return rc;
|
| 765 | }
|
| 766 |
|
| 767 | rc = ecryptfs_get_lower_file(dentry, inode);
|
| 768 | if (rc)
|
| 769 | return rc;
|
| 770 |
|
| 771 | if (ia->ia_size > i_size) {
|
| 772 | char zero[] = { 0x00 };
|
| 773 |
|
| 774 | |
| 775 | * Write a single 0 at the last position of the file; this
|
| 776 | * triggers code that will fill in 0's throughout the
|
| 777 | * intermediate portion of the previous end of the file and the
|
| 778 | * new end of the file.
|
| 779 |
|
| 780 | rc = ecryptfs_write(inode, zero, ia->ia_size - 1, 1);
|
| 781 | goto out;
|
| 782 | }
|
| 783 |
|
| 784 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
|
| 785 | truncate_setsize(inode, ia->ia_size);
|
| 786 | lower_ia.ia_size = ia->ia_size;
|
| 787 | goto set_size;
|
| 788 | }
|
| 789 |
|
| 790 | |
| 791 | * We're chopping off all the pages down to the page in which
|
| 792 | * ia->ia_size is located. Fill in the end of that page from
|
| 793 | * (ia->ia_size & ~PAGE_MASK) to PAGE_SIZE with zeros.
|
| 794 |
|
| 795 | num_zeros = PAGE_SIZE - (ia->ia_size & ~PAGE_MASK);
|
| 796 | if (num_zeros) {
|
| 797 | rc = ecryptfs_write(inode, page_address(ZERO_PAGE(0)),
|
| 798 | ia->ia_size, num_zeros);
|
| 799 | if (rc) {
|
| 800 | pr_err("Error attempting to zero out the remainder of the end page on reducing truncate; rc = [%d]\n",
|
| 801 | rc);
|
| 802 | goto out;
|
| 803 | }
|
| 804 | }
|
| 805 | truncate_setsize(inode, ia->ia_size);
|
| 806 | rc = ecryptfs_write_inode_size_to_metadata(inode);
|
| 807 | if (rc) {
|
| 808 | pr_err("Problem with ecryptfs_write_inode_size_to_metadata; rc = [%d]\n",
|
| 809 | rc);
|
| 810 | goto out;
|
| 811 | }
|
| 812 |
|
| 813 | |
| 814 | * We are reducing the size of the ecryptfs file, and need to know if we
|
| 815 | * need to reduce the size of the lower file.
|
| 816 |
|
| 817 | if (lower_size_after_truncate >= lower_size_before_truncate)
|
| 818 | goto out;
|
| 819 |
|
| 820 | lower_ia.ia_size = lower_size_after_truncate;
|
| 821 | set_size:
|
| 822 | lower_ia.ia_valid |= ATTR_SIZE;
|
| 823 | inode_lock(d_inode(lower_dentry));
|
| 824 | rc = notify_change(&nop_mnt_idmap, lower_dentry, &lower_ia, NULL);
|
| 825 | inode_unlock(d_inode(lower_dentry));
|
| 826 | out:
|
| 827 | ecryptfs_put_lower_file(inode);
|
| 828 | return rc;
|
| 829 | }
|
| 830 |
|
| 831 | |
| 832 | * ecryptfs_truncate
|
| 833 | * @dentry: The ecryptfs layer dentry
|
| 834 | * @new_length: The length to expand the file to
|
| 835 | *
|
| 836 | * Simple function that handles the truncation of an eCryptfs inode and
|
| 837 | * its corresponding lower inode.
|
| 838 | *
|
| 839 | * Returns zero on success; non-zero otherwise
|
| 840 |
|
| 841 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
|
| 842 | {
|
| 843 | const struct iattr ia = {
|
| 844 | .ia_valid = ATTR_SIZE,
|
| 845 | .ia_size = new_length,
|
| 846 | };
|
| 847 |
|
| 848 | return __ecryptfs_truncate(dentry, &ia);
|
| 849 | }
|
| 850 |
|
| 851 | static int
|
| 852 | ecryptfs_permission(const struct mnt_idmap *idmap, struct inode *inode,
|
| 853 | int mask)
|
| 854 | {
|
| 855 | return inode_permission(&nop_mnt_idmap,
|
| 856 | ecryptfs_inode_to_lower(inode), mask);
|
| 857 | }
|
| 858 |
|
| 859 | |
| 860 | * ecryptfs_setattr
|
| 861 | * @idmap: idmap of the target mount
|
| 862 | * @dentry: dentry handle to the inode to modify
|
| 863 | * @ia: Structure with flags of what to change and values
|
| 864 | *
|
| 865 | * Updates the metadata of an inode. If the update is to the size
|
| 866 | * i.e. truncation, then ecryptfs_truncate will handle the size modification
|
| 867 | * of both the ecryptfs inode and the lower inode.
|
| 868 | *
|
| 869 | * All other metadata changes will be passed right to the lower filesystem,
|
| 870 | * and we will just update our inode to look like the lower.
|
| 871 |
|
| 872 | static int ecryptfs_setattr(const struct mnt_idmap *idmap,
|
| 873 | struct dentry *dentry, struct iattr *ia)
|
| 874 | {
|
| 875 | struct inode *inode = d_inode(dentry);
|
| 876 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
| 877 | struct inode *lower_inode = ecryptfs_inode_to_lower(inode);
|
| 878 | struct ecryptfs_crypt_stat *crypt_stat;
|
| 879 | int rc;
|
| 880 |
|
| 881 | crypt_stat = &ecryptfs_inode_to_private(d_inode(dentry))->crypt_stat;
|
| 882 | if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED))
|
| 883 | ecryptfs_init_crypt_stat(crypt_stat);
|
| 884 |
|
| 885 | mutex_lock(&crypt_stat->cs_mutex);
|
| 886 | if (d_is_dir(dentry))
|
| 887 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
|
| 888 | else if (d_is_reg(dentry) &&
|
| 889 | (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) ||
|
| 890 | !(crypt_stat->flags & ECRYPTFS_KEY_VALID))) {
|
| 891 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
|
| 892 |
|
| 893 | mount_crypt_stat = &ecryptfs_superblock_to_private(
|
| 894 | dentry->d_sb)->mount_crypt_stat;
|
| 895 | rc = ecryptfs_get_lower_file(dentry, inode);
|
| 896 | if (rc) {
|
| 897 | mutex_unlock(&crypt_stat->cs_mutex);
|
| 898 | goto out;
|
| 899 | }
|
| 900 | rc = ecryptfs_read_metadata(dentry);
|
| 901 | ecryptfs_put_lower_file(inode);
|
| 902 | if (rc) {
|
| 903 | if (!(mount_crypt_stat->flags &
|
| 904 | ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
|
| 905 | rc = -EIO;
|
| 906 | printk(KERN_WARNING "Either the lower file "
|
| 907 | "is not in a valid eCryptfs format, "
|
| 908 | "or the key could not be retrieved. "
|
| 909 | "Plaintext passthrough mode is not "
|
| 910 | "enabled; returning -EIO\n");
|
| 911 | mutex_unlock(&crypt_stat->cs_mutex);
|
| 912 | goto out;
|
| 913 | }
|
| 914 | rc = 0;
|
| 915 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
|
| 916 | | ECRYPTFS_ENCRYPTED);
|
| 917 | }
|
| 918 | }
|
| 919 | mutex_unlock(&crypt_stat->cs_mutex);
|
| 920 |
|
| 921 | rc = setattr_prepare(&nop_mnt_idmap, dentry, ia);
|
| 922 | if (rc)
|
| 923 | goto out;
|
| 924 |
|
| 925 | if (ia->ia_valid & ATTR_SIZE) {
|
| 926 | rc = __ecryptfs_truncate(dentry, ia);
|
| 927 | } else {
|
| 928 | struct iattr lower_ia;
|
| 929 |
|
| 930 | ecryptfs_iattr_to_lower(&lower_ia, ia);
|
| 931 |
|
| 932 | inode_lock(d_inode(lower_dentry));
|
| 933 | rc = notify_change(&nop_mnt_idmap, lower_dentry, &lower_ia,
|
| 934 | NULL);
|
| 935 | inode_unlock(d_inode(lower_dentry));
|
| 936 | }
|
| 937 | out:
|
| 938 | fsstack_copy_attr_all(inode, lower_inode);
|
| 939 | return rc;
|
| 940 | }
|
| 941 |
|
| 942 | static int ecryptfs_getattr_link(const struct mnt_idmap *idmap,
|
| 943 | const struct path *path, struct kstat *stat,
|
| 944 | u32 request_mask, unsigned int flags)
|
| 945 | {
|
| 946 | struct dentry *dentry = path->dentry;
|
| 947 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
|
| 948 | int rc = 0;
|
| 949 |
|
| 950 | mount_crypt_stat = &ecryptfs_superblock_to_private(
|
| 951 | dentry->d_sb)->mount_crypt_stat;
|
| 952 | generic_fillattr(&nop_mnt_idmap, request_mask, d_inode(dentry), stat);
|
| 953 | if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
|
| 954 | char *target;
|
| 955 | size_t targetsiz;
|
| 956 |
|
| 957 | target = ecryptfs_readlink_lower(dentry, &targetsiz);
|
| 958 | if (!IS_ERR(target)) {
|
| 959 | kfree(target);
|
| 960 | stat->size = targetsiz;
|
| 961 | } else {
|
| 962 | rc = PTR_ERR(target);
|
| 963 | }
|
| 964 | }
|
| 965 | return rc;
|
| 966 | }
|
| 967 |
|
| 968 | static int ecryptfs_getattr(const struct mnt_idmap *idmap,
|
| 969 | const struct path *path, struct kstat *stat,
|
| 970 | u32 request_mask, unsigned int flags)
|
| 971 | {
|
| 972 | struct dentry *dentry = path->dentry;
|
| 973 | struct kstat lower_stat;
|
| 974 | struct path lower_path = ecryptfs_lower_path(dentry);
|
| 975 | int rc;
|
| 976 |
|
| 977 | rc = vfs_getattr_nosec(&lower_path, &lower_stat, request_mask, flags);
|
| 978 | if (!rc) {
|
| 979 | fsstack_copy_attr_all(d_inode(dentry),
|
| 980 | ecryptfs_inode_to_lower(d_inode(dentry)));
|
| 981 | generic_fillattr(&nop_mnt_idmap, request_mask,
|
| 982 | d_inode(dentry), stat);
|
| 983 | stat->blocks = lower_stat.blocks;
|
| 984 | }
|
| 985 | return rc;
|
| 986 | }
|
| 987 |
|
| 988 | int
|
| 989 | ecryptfs_setxattr(struct dentry *dentry, struct inode *inode,
|
| 990 | const char *name, const void *value,
|
| 991 | size_t size, int flags)
|
| 992 | {
|
| 993 | int rc;
|
| 994 | struct dentry *lower_dentry;
|
| 995 | struct inode *lower_inode;
|
| 996 |
|
| 997 | lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
| 998 | lower_inode = d_inode(lower_dentry);
|
| 999 | if (!(lower_inode->i_opflags & IOP_XATTR)) {
|
| 1000 | rc = -EOPNOTSUPP;
|
| 1001 | goto out;
|
| 1002 | }
|
| 1003 | inode_lock(lower_inode);
|
| 1004 | rc = __vfs_setxattr_locked(&nop_mnt_idmap, lower_dentry, name, value, size, flags, NULL);
|
| 1005 | inode_unlock(lower_inode);
|
| 1006 | if (!rc && inode)
|
| 1007 | fsstack_copy_attr_all(inode, lower_inode);
|
| 1008 | out:
|
| 1009 | return rc;
|
| 1010 | }
|
| 1011 |
|
| 1012 | ssize_t
|
| 1013 | ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
|
| 1014 | const char *name, void *value, size_t size)
|
| 1015 | {
|
| 1016 | int rc;
|
| 1017 |
|
| 1018 | if (!(lower_inode->i_opflags & IOP_XATTR)) {
|
| 1019 | rc = -EOPNOTSUPP;
|
| 1020 | goto out;
|
| 1021 | }
|
| 1022 | inode_lock(lower_inode);
|
| 1023 | rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size);
|
| 1024 | inode_unlock(lower_inode);
|
| 1025 | out:
|
| 1026 | return rc;
|
| 1027 | }
|
| 1028 |
|
| 1029 | static ssize_t
|
| 1030 | ecryptfs_getxattr(struct dentry *dentry, struct inode *inode,
|
| 1031 | const char *name, void *value, size_t size)
|
| 1032 | {
|
| 1033 | return ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry),
|
| 1034 | ecryptfs_inode_to_lower(inode),
|
| 1035 | name, value, size);
|
| 1036 | }
|
| 1037 |
|
| 1038 | static ssize_t
|
| 1039 | ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
|
| 1040 | {
|
| 1041 | int rc = 0;
|
| 1042 | struct dentry *lower_dentry;
|
| 1043 |
|
| 1044 | lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
| 1045 | if (!d_inode(lower_dentry)->i_op->listxattr) {
|
| 1046 | rc = -EOPNOTSUPP;
|
| 1047 | goto out;
|
| 1048 | }
|
| 1049 | inode_lock(d_inode(lower_dentry));
|
| 1050 | rc = d_inode(lower_dentry)->i_op->listxattr(lower_dentry, list, size);
|
| 1051 | inode_unlock(d_inode(lower_dentry));
|
| 1052 | out:
|
| 1053 | return rc;
|
| 1054 | }
|
| 1055 |
|
| 1056 | static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode,
|
| 1057 | const char *name)
|
| 1058 | {
|
| 1059 | int rc;
|
| 1060 | struct dentry *lower_dentry;
|
| 1061 | struct inode *lower_inode;
|
| 1062 |
|
| 1063 | lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
| 1064 | lower_inode = ecryptfs_inode_to_lower(inode);
|
| 1065 | if (!(lower_inode->i_opflags & IOP_XATTR)) {
|
| 1066 | rc = -EOPNOTSUPP;
|
| 1067 | goto out;
|
| 1068 | }
|
| 1069 | inode_lock(lower_inode);
|
| 1070 | rc = __vfs_removexattr(&nop_mnt_idmap, lower_dentry, name);
|
| 1071 | inode_unlock(lower_inode);
|
| 1072 | out:
|
| 1073 | return rc;
|
| 1074 | }
|
| 1075 |
|
| 1076 | static int ecryptfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
|
| 1077 | {
|
| 1078 | return vfs_fileattr_get(ecryptfs_dentry_to_lower(dentry), fa);
|
| 1079 | }
|
| 1080 |
|
| 1081 | static int ecryptfs_fileattr_set(const struct mnt_idmap *idmap,
|
| 1082 | struct dentry *dentry, struct file_kattr *fa)
|
| 1083 | {
|
| 1084 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
| 1085 | int rc;
|
| 1086 |
|
| 1087 | rc = vfs_fileattr_set(&nop_mnt_idmap, lower_dentry, fa);
|
| 1088 | fsstack_copy_attr_all(d_inode(dentry), d_inode(lower_dentry));
|
| 1089 |
|
| 1090 | return rc;
|
| 1091 | }
|
| 1092 |
|
| 1093 | static struct posix_acl *ecryptfs_get_acl(const struct mnt_idmap *idmap,
|
| 1094 | struct dentry *dentry, int type)
|
| 1095 | {
|
| 1096 | return vfs_get_acl(idmap, ecryptfs_dentry_to_lower(dentry),
|
| 1097 | posix_acl_xattr_name(type));
|
| 1098 | }
|
| 1099 |
|
| 1100 | static int ecryptfs_set_acl(const struct mnt_idmap *idmap,
|
| 1101 | struct dentry *dentry, struct posix_acl *acl,
|
| 1102 | int type)
|
| 1103 | {
|
| 1104 | int rc;
|
| 1105 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
| 1106 | struct inode *lower_inode = d_inode(lower_dentry);
|
| 1107 |
|
| 1108 | rc = vfs_set_acl(&nop_mnt_idmap, lower_dentry,
|
| 1109 | posix_acl_xattr_name(type), acl);
|
| 1110 | if (!rc)
|
| 1111 | fsstack_copy_attr_all(d_inode(dentry), lower_inode);
|
| 1112 | return rc;
|
| 1113 | }
|
| 1114 |
|
| 1115 | const struct inode_operations ecryptfs_symlink_iops = {
|
| 1116 | .get_link = ecryptfs_get_link,
|
| 1117 | .permission = ecryptfs_permission,
|
| 1118 | .setattr = ecryptfs_setattr,
|
| 1119 | .getattr = ecryptfs_getattr_link,
|
| 1120 | .listxattr = ecryptfs_listxattr,
|
| 1121 | };
|
| 1122 |
|
| 1123 | const struct inode_operations ecryptfs_dir_iops = {
|
| 1124 | .create = ecryptfs_create,
|
| 1125 | .lookup = ecryptfs_lookup,
|
| 1126 | .link = ecryptfs_link,
|
| 1127 | .unlink = ecryptfs_unlink,
|
| 1128 | .symlink = ecryptfs_symlink,
|
| 1129 | .mkdir = ecryptfs_mkdir,
|
| 1130 | .rmdir = ecryptfs_rmdir,
|
| 1131 | .mknod = ecryptfs_mknod,
|
| 1132 | .rename = ecryptfs_rename,
|
| 1133 | .permission = ecryptfs_permission,
|
| 1134 | .setattr = ecryptfs_setattr,
|
| 1135 | .listxattr = ecryptfs_listxattr,
|
| 1136 | .fileattr_get = ecryptfs_fileattr_get,
|
| 1137 | .fileattr_set = ecryptfs_fileattr_set,
|
| 1138 | .get_acl = ecryptfs_get_acl,
|
| 1139 | .set_acl = ecryptfs_set_acl,
|
| 1140 | };
|
| 1141 |
|
| 1142 | const struct inode_operations ecryptfs_main_iops = {
|
| 1143 | .permission = ecryptfs_permission,
|
| 1144 | .setattr = ecryptfs_setattr,
|
| 1145 | .getattr = ecryptfs_getattr,
|
| 1146 | .listxattr = ecryptfs_listxattr,
|
| 1147 | .fileattr_get = ecryptfs_fileattr_get,
|
| 1148 | .fileattr_set = ecryptfs_fileattr_set,
|
| 1149 | .get_acl = ecryptfs_get_acl,
|
| 1150 | .set_acl = ecryptfs_set_acl,
|
| 1151 | };
|
| 1152 |
|
| 1153 | static int ecryptfs_xattr_get(const struct xattr_handler *handler,
|
| 1154 | struct dentry *dentry, struct inode *inode,
|
| 1155 | const char *name, void *buffer, size_t size)
|
| 1156 | {
|
| 1157 | return ecryptfs_getxattr(dentry, inode, name, buffer, size);
|
| 1158 | }
|
| 1159 |
|
| 1160 | static int ecryptfs_xattr_set(const struct xattr_handler *handler,
|
| 1161 | const struct mnt_idmap *idmap,
|
| 1162 | struct dentry *dentry, struct inode *inode,
|
| 1163 | const char *name, const void *value, size_t size,
|
| 1164 | int flags)
|
| 1165 | {
|
| 1166 | if (value)
|
| 1167 | return ecryptfs_setxattr(dentry, inode, name, value, size, flags);
|
| 1168 | else {
|
| 1169 | BUG_ON(flags != XATTR_REPLACE);
|
| 1170 | return ecryptfs_removexattr(dentry, inode, name);
|
| 1171 | }
|
| 1172 | }
|
| 1173 |
|
| 1174 | static const struct xattr_handler ecryptfs_xattr_handler = {
|
| 1175 | .prefix = "",
|
| 1176 | .get = ecryptfs_xattr_get,
|
| 1177 | .set = ecryptfs_xattr_set,
|
| 1178 | };
|
| 1179 |
|
| 1180 | const struct xattr_handler * const ecryptfs_xattr_handlers[] = {
|
| 1181 | &ecryptfs_xattr_handler,
|
| 1182 | NULL
|
| 1183 | };
|