diff options
Diffstat (limited to 'fs/ecryptfs/inode.c')
| -rw-r--r-- | fs/ecryptfs/inode.c | 52 |
1 files changed, 29 insertions, 23 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index c92cc1c00aae..89209f00f9c7 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/mount.h> | 31 | #include <linux/mount.h> |
| 32 | #include <linux/crypto.h> | 32 | #include <linux/crypto.h> |
| 33 | #include <linux/fs_stack.h> | 33 | #include <linux/fs_stack.h> |
| 34 | #include <asm/unaligned.h> | ||
| 34 | #include "ecryptfs_kernel.h" | 35 | #include "ecryptfs_kernel.h" |
| 35 | 36 | ||
| 36 | static struct dentry *lock_parent(struct dentry *dentry) | 37 | static struct dentry *lock_parent(struct dentry *dentry) |
| @@ -188,6 +189,16 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
| 188 | "context; rc = [%d]\n", rc); | 189 | "context; rc = [%d]\n", rc); |
| 189 | goto out; | 190 | goto out; |
| 190 | } | 191 | } |
| 192 | if (!ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->lower_file) { | ||
| 193 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | ||
| 194 | if (rc) { | ||
| 195 | printk(KERN_ERR "%s: Error attempting to initialize " | ||
| 196 | "the persistent file for the dentry with name " | ||
| 197 | "[%s]; rc = [%d]\n", __func__, | ||
| 198 | ecryptfs_dentry->d_name.name, rc); | ||
| 199 | goto out; | ||
| 200 | } | ||
| 201 | } | ||
| 191 | rc = ecryptfs_write_metadata(ecryptfs_dentry); | 202 | rc = ecryptfs_write_metadata(ecryptfs_dentry); |
| 192 | if (rc) { | 203 | if (rc) { |
| 193 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); | 204 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); |
| @@ -307,10 +318,11 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 307 | d_add(dentry, NULL); | 318 | d_add(dentry, NULL); |
| 308 | goto out; | 319 | goto out; |
| 309 | } | 320 | } |
| 310 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 1); | 321 | rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, |
| 322 | ECRYPTFS_INTERPOSE_FLAG_D_ADD); | ||
| 311 | if (rc) { | 323 | if (rc) { |
| 312 | ecryptfs_printk(KERN_ERR, "Error interposing\n"); | 324 | ecryptfs_printk(KERN_ERR, "Error interposing\n"); |
| 313 | goto out_dput; | 325 | goto out; |
| 314 | } | 326 | } |
| 315 | if (S_ISDIR(lower_inode->i_mode)) { | 327 | if (S_ISDIR(lower_inode->i_mode)) { |
| 316 | ecryptfs_printk(KERN_DEBUG, "Is a directory; returning\n"); | 328 | ecryptfs_printk(KERN_DEBUG, "Is a directory; returning\n"); |
| @@ -336,11 +348,21 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 336 | rc = -ENOMEM; | 348 | rc = -ENOMEM; |
| 337 | ecryptfs_printk(KERN_ERR, | 349 | ecryptfs_printk(KERN_ERR, |
| 338 | "Cannot ecryptfs_kmalloc a page\n"); | 350 | "Cannot ecryptfs_kmalloc a page\n"); |
| 339 | goto out_dput; | 351 | goto out; |
| 340 | } | 352 | } |
| 341 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 353 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
| 342 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) | 354 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) |
| 343 | ecryptfs_set_default_sizes(crypt_stat); | 355 | ecryptfs_set_default_sizes(crypt_stat); |
| 356 | if (!ecryptfs_inode_to_private(dentry->d_inode)->lower_file) { | ||
| 357 | rc = ecryptfs_init_persistent_file(dentry); | ||
| 358 | if (rc) { | ||
| 359 | printk(KERN_ERR "%s: Error attempting to initialize " | ||
| 360 | "the persistent file for the dentry with name " | ||
| 361 | "[%s]; rc = [%d]\n", __func__, | ||
| 362 | dentry->d_name.name, rc); | ||
| 363 | goto out; | ||
| 364 | } | ||
| 365 | } | ||
| 344 | rc = ecryptfs_read_and_validate_header_region(page_virt, | 366 | rc = ecryptfs_read_and_validate_header_region(page_virt, |
| 345 | dentry->d_inode); | 367 | dentry->d_inode); |
| 346 | if (rc) { | 368 | if (rc) { |
| @@ -364,8 +386,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 364 | else | 386 | else |
| 365 | file_size = i_size_read(lower_dentry->d_inode); | 387 | file_size = i_size_read(lower_dentry->d_inode); |
| 366 | } else { | 388 | } else { |
| 367 | memcpy(&file_size, page_virt, sizeof(file_size)); | 389 | file_size = get_unaligned_be64(page_virt); |
| 368 | file_size = be64_to_cpu(file_size); | ||
| 369 | } | 390 | } |
| 370 | i_size_write(dentry->d_inode, (loff_t)file_size); | 391 | i_size_write(dentry->d_inode, (loff_t)file_size); |
| 371 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 392 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
| @@ -444,7 +465,6 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 444 | int rc; | 465 | int rc; |
| 445 | struct dentry *lower_dentry; | 466 | struct dentry *lower_dentry; |
| 446 | struct dentry *lower_dir_dentry; | 467 | struct dentry *lower_dir_dentry; |
| 447 | umode_t mode; | ||
| 448 | char *encoded_symname; | 468 | char *encoded_symname; |
| 449 | int encoded_symlen; | 469 | int encoded_symlen; |
| 450 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | 470 | struct ecryptfs_crypt_stat *crypt_stat = NULL; |
| @@ -452,7 +472,6 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 452 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 472 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
| 453 | dget(lower_dentry); | 473 | dget(lower_dentry); |
| 454 | lower_dir_dentry = lock_parent(lower_dentry); | 474 | lower_dir_dentry = lock_parent(lower_dentry); |
| 455 | mode = S_IALLUGO; | ||
| 456 | encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, | 475 | encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, |
| 457 | strlen(symname), | 476 | strlen(symname), |
| 458 | &encoded_symname); | 477 | &encoded_symname); |
| @@ -461,7 +480,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 461 | goto out_lock; | 480 | goto out_lock; |
| 462 | } | 481 | } |
| 463 | rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, | 482 | rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, |
| 464 | encoded_symname, mode); | 483 | encoded_symname); |
| 465 | kfree(encoded_symname); | 484 | kfree(encoded_symname); |
| 466 | if (rc || !lower_dentry->d_inode) | 485 | if (rc || !lower_dentry->d_inode) |
| 467 | goto out_lock; | 486 | goto out_lock; |
| @@ -809,22 +828,9 @@ out: | |||
| 809 | } | 828 | } |
| 810 | 829 | ||
| 811 | static int | 830 | static int |
| 812 | ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd) | 831 | ecryptfs_permission(struct inode *inode, int mask) |
| 813 | { | 832 | { |
| 814 | int rc; | 833 | return inode_permission(ecryptfs_inode_to_lower(inode), mask); |
| 815 | |||
| 816 | if (nd) { | ||
| 817 | struct vfsmount *vfsmnt_save = nd->path.mnt; | ||
| 818 | struct dentry *dentry_save = nd->path.dentry; | ||
| 819 | |||
| 820 | nd->path.mnt = ecryptfs_dentry_to_lower_mnt(nd->path.dentry); | ||
| 821 | nd->path.dentry = ecryptfs_dentry_to_lower(nd->path.dentry); | ||
| 822 | rc = permission(ecryptfs_inode_to_lower(inode), mask, nd); | ||
| 823 | nd->path.mnt = vfsmnt_save; | ||
| 824 | nd->path.dentry = dentry_save; | ||
| 825 | } else | ||
| 826 | rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL); | ||
| 827 | return rc; | ||
| 828 | } | 834 | } |
| 829 | 835 | ||
| 830 | /** | 836 | /** |
