diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2007-10-16 04:28:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:12 -0400 |
commit | d7cdc5febf9f2664755002c3a2f84bd348389fe9 (patch) | |
tree | ad770ac2031d87474220cc20eb7b99a246dea8bb | |
parent | 4981e081cfe2c3f4abcfa3924ebd999cdbed4914 (diff) |
eCryptfs: update metadata read/write functions
Update the metadata read/write functions and grow_file() to use the
read_write.c routines. Do not open another lower file; use the persistent
lower file instead. Provide a separate function for
crypto.c::ecryptfs_read_xattr_region() to get to the lower xattr without
having to go through the eCryptfs getxattr.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/ecryptfs/crypto.c | 127 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 15 | ||||
-rw-r--r-- | fs/ecryptfs/file.c | 2 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 101 | ||||
-rw-r--r-- | fs/ecryptfs/mmap.c | 2 |
5 files changed, 114 insertions, 133 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 7f788ea5da2b..55110ffe9ebd 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -1342,21 +1342,28 @@ out: | |||
1342 | return rc; | 1342 | return rc; |
1343 | } | 1343 | } |
1344 | 1344 | ||
1345 | int ecryptfs_read_and_validate_header_region(char *data, struct dentry *dentry, | 1345 | int ecryptfs_read_and_validate_header_region(char *data, |
1346 | struct vfsmount *mnt) | 1346 | struct inode *ecryptfs_inode) |
1347 | { | 1347 | { |
1348 | struct ecryptfs_crypt_stat *crypt_stat = | ||
1349 | &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat); | ||
1348 | int rc; | 1350 | int rc; |
1349 | 1351 | ||
1350 | rc = ecryptfs_read_header_region(data, dentry, mnt); | 1352 | rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size, |
1351 | if (rc) | 1353 | ecryptfs_inode); |
1354 | if (rc) { | ||
1355 | printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n", | ||
1356 | __FUNCTION__, rc); | ||
1352 | goto out; | 1357 | goto out; |
1353 | if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) | 1358 | } |
1359 | if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) { | ||
1354 | rc = -EINVAL; | 1360 | rc = -EINVAL; |
1361 | ecryptfs_printk(KERN_DEBUG, "Valid marker not found\n"); | ||
1362 | } | ||
1355 | out: | 1363 | out: |
1356 | return rc; | 1364 | return rc; |
1357 | } | 1365 | } |
1358 | 1366 | ||
1359 | |||
1360 | void | 1367 | void |
1361 | ecryptfs_write_header_metadata(char *virt, | 1368 | ecryptfs_write_header_metadata(char *virt, |
1362 | struct ecryptfs_crypt_stat *crypt_stat, | 1369 | struct ecryptfs_crypt_stat *crypt_stat, |
@@ -1441,24 +1448,19 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t *size, | |||
1441 | 1448 | ||
1442 | static int | 1449 | static int |
1443 | ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, | 1450 | ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, |
1444 | struct file *lower_file, char *page_virt) | 1451 | struct dentry *ecryptfs_dentry, |
1452 | char *page_virt) | ||
1445 | { | 1453 | { |
1446 | mm_segment_t oldfs; | ||
1447 | int current_header_page; | 1454 | int current_header_page; |
1448 | int header_pages; | 1455 | int header_pages; |
1449 | ssize_t size; | 1456 | int rc; |
1450 | int rc = 0; | ||
1451 | 1457 | ||
1452 | lower_file->f_pos = 0; | 1458 | rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, page_virt, |
1453 | oldfs = get_fs(); | 1459 | 0, PAGE_CACHE_SIZE); |
1454 | set_fs(get_ds()); | 1460 | if (rc) { |
1455 | size = vfs_write(lower_file, (char __user *)page_virt, PAGE_CACHE_SIZE, | 1461 | printk(KERN_ERR "%s: Error attempting to write header " |
1456 | &lower_file->f_pos); | 1462 | "information to lower file; rc = [%d]\n", __FUNCTION__, |
1457 | if (size < 0) { | 1463 | rc); |
1458 | rc = (int)size; | ||
1459 | printk(KERN_ERR "Error attempting to write lower page; " | ||
1460 | "rc = [%d]\n", rc); | ||
1461 | set_fs(oldfs); | ||
1462 | goto out; | 1464 | goto out; |
1463 | } | 1465 | } |
1464 | header_pages = ((crypt_stat->extent_size | 1466 | header_pages = ((crypt_stat->extent_size |
@@ -1467,18 +1469,19 @@ ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, | |||
1467 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 1469 | memset(page_virt, 0, PAGE_CACHE_SIZE); |
1468 | current_header_page = 1; | 1470 | current_header_page = 1; |
1469 | while (current_header_page < header_pages) { | 1471 | while (current_header_page < header_pages) { |
1470 | size = vfs_write(lower_file, (char __user *)page_virt, | 1472 | loff_t offset; |
1471 | PAGE_CACHE_SIZE, &lower_file->f_pos); | 1473 | |
1472 | if (size < 0) { | 1474 | offset = (current_header_page << PAGE_CACHE_SHIFT); |
1473 | rc = (int)size; | 1475 | if ((rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, |
1474 | printk(KERN_ERR "Error attempting to write lower page; " | 1476 | page_virt, offset, |
1475 | "rc = [%d]\n", rc); | 1477 | PAGE_CACHE_SIZE))) { |
1476 | set_fs(oldfs); | 1478 | printk(KERN_ERR "%s: Error attempting to write header " |
1479 | "information to lower file; rc = [%d]\n", | ||
1480 | __FUNCTION__, rc); | ||
1477 | goto out; | 1481 | goto out; |
1478 | } | 1482 | } |
1479 | current_header_page++; | 1483 | current_header_page++; |
1480 | } | 1484 | } |
1481 | set_fs(oldfs); | ||
1482 | out: | 1485 | out: |
1483 | return rc; | 1486 | return rc; |
1484 | } | 1487 | } |
@@ -1498,7 +1501,6 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, | |||
1498 | /** | 1501 | /** |
1499 | * ecryptfs_write_metadata | 1502 | * ecryptfs_write_metadata |
1500 | * @ecryptfs_dentry: The eCryptfs dentry | 1503 | * @ecryptfs_dentry: The eCryptfs dentry |
1501 | * @lower_file: The lower file struct, which was returned from dentry_open | ||
1502 | * | 1504 | * |
1503 | * Write the file headers out. This will likely involve a userspace | 1505 | * Write the file headers out. This will likely involve a userspace |
1504 | * callout, in which the session key is encrypted with one or more | 1506 | * callout, in which the session key is encrypted with one or more |
@@ -1506,22 +1508,21 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, | |||
1506 | * retrieved via a prompt. Exactly what happens at this point should | 1508 | * retrieved via a prompt. Exactly what happens at this point should |
1507 | * be policy-dependent. | 1509 | * be policy-dependent. |
1508 | * | 1510 | * |
1511 | * TODO: Support header information spanning multiple pages | ||
1512 | * | ||
1509 | * Returns zero on success; non-zero on error | 1513 | * Returns zero on success; non-zero on error |
1510 | */ | 1514 | */ |
1511 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry, | 1515 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) |
1512 | struct file *lower_file) | ||
1513 | { | 1516 | { |
1514 | struct ecryptfs_crypt_stat *crypt_stat; | 1517 | struct ecryptfs_crypt_stat *crypt_stat = |
1518 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | ||
1515 | char *page_virt; | 1519 | char *page_virt; |
1516 | size_t size; | 1520 | size_t size = 0; |
1517 | int rc = 0; | 1521 | int rc = 0; |
1518 | 1522 | ||
1519 | crypt_stat = &ecryptfs_inode_to_private( | ||
1520 | ecryptfs_dentry->d_inode)->crypt_stat; | ||
1521 | if (likely(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | 1523 | if (likely(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
1522 | if (!(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { | 1524 | if (!(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { |
1523 | ecryptfs_printk(KERN_DEBUG, "Key is " | 1525 | printk(KERN_ERR "Key is invalid; bailing out\n"); |
1524 | "invalid; bailing out\n"); | ||
1525 | rc = -EINVAL; | 1526 | rc = -EINVAL; |
1526 | goto out; | 1527 | goto out; |
1527 | } | 1528 | } |
@@ -1550,7 +1551,8 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry, | |||
1550 | crypt_stat, page_virt, | 1551 | crypt_stat, page_virt, |
1551 | size); | 1552 | size); |
1552 | else | 1553 | else |
1553 | rc = ecryptfs_write_metadata_to_contents(crypt_stat, lower_file, | 1554 | rc = ecryptfs_write_metadata_to_contents(crypt_stat, |
1555 | ecryptfs_dentry, | ||
1554 | page_virt); | 1556 | page_virt); |
1555 | if (rc) { | 1557 | if (rc) { |
1556 | printk(KERN_ERR "Error writing metadata out to lower file; " | 1558 | printk(KERN_ERR "Error writing metadata out to lower file; " |
@@ -1678,15 +1680,17 @@ out: | |||
1678 | * | 1680 | * |
1679 | * Returns zero on success; non-zero on error | 1681 | * Returns zero on success; non-zero on error |
1680 | */ | 1682 | */ |
1681 | int ecryptfs_read_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry) | 1683 | int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode) |
1682 | { | 1684 | { |
1685 | struct dentry *lower_dentry = | ||
1686 | ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry; | ||
1683 | ssize_t size; | 1687 | ssize_t size; |
1684 | int rc = 0; | 1688 | int rc = 0; |
1685 | 1689 | ||
1686 | size = ecryptfs_getxattr(ecryptfs_dentry, ECRYPTFS_XATTR_NAME, | 1690 | size = ecryptfs_getxattr_lower(lower_dentry, ECRYPTFS_XATTR_NAME, |
1687 | page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE); | 1691 | page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE); |
1688 | if (size < 0) { | 1692 | if (size < 0) { |
1689 | printk(KERN_DEBUG "Error attempting to read the [%s] " | 1693 | printk(KERN_ERR "Error attempting to read the [%s] " |
1690 | "xattr from the lower file; return value = [%zd]\n", | 1694 | "xattr from the lower file; return value = [%zd]\n", |
1691 | ECRYPTFS_XATTR_NAME, size); | 1695 | ECRYPTFS_XATTR_NAME, size); |
1692 | rc = -EINVAL; | 1696 | rc = -EINVAL; |
@@ -1701,7 +1705,7 @@ int ecryptfs_read_and_validate_xattr_region(char *page_virt, | |||
1701 | { | 1705 | { |
1702 | int rc; | 1706 | int rc; |
1703 | 1707 | ||
1704 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_dentry); | 1708 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_dentry->d_inode); |
1705 | if (rc) | 1709 | if (rc) |
1706 | goto out; | 1710 | goto out; |
1707 | if (!contains_ecryptfs_marker(page_virt + ECRYPTFS_FILE_SIZE_BYTES)) { | 1711 | if (!contains_ecryptfs_marker(page_virt + ECRYPTFS_FILE_SIZE_BYTES)) { |
@@ -1715,8 +1719,6 @@ out: | |||
1715 | 1719 | ||
1716 | /** | 1720 | /** |
1717 | * ecryptfs_read_metadata | 1721 | * ecryptfs_read_metadata |
1718 | * @ecryptfs_dentry: The eCryptfs dentry | ||
1719 | * @lower_file: The lower file from which to read the metadata | ||
1720 | * | 1722 | * |
1721 | * Common entry point for reading file metadata. From here, we could | 1723 | * Common entry point for reading file metadata. From here, we could |
1722 | * retrieve the header information from the header region of the file, | 1724 | * retrieve the header information from the header region of the file, |
@@ -1727,15 +1729,13 @@ out: | |||
1727 | * | 1729 | * |
1728 | * Returns zero if valid headers found and parsed; non-zero otherwise | 1730 | * Returns zero if valid headers found and parsed; non-zero otherwise |
1729 | */ | 1731 | */ |
1730 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry, | 1732 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) |
1731 | struct file *lower_file) | ||
1732 | { | 1733 | { |
1733 | int rc = 0; | 1734 | int rc = 0; |
1734 | char *page_virt = NULL; | 1735 | char *page_virt = NULL; |
1735 | mm_segment_t oldfs; | 1736 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; |
1736 | ssize_t bytes_read; | ||
1737 | struct ecryptfs_crypt_stat *crypt_stat = | 1737 | struct ecryptfs_crypt_stat *crypt_stat = |
1738 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | 1738 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
1739 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 1739 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
1740 | &ecryptfs_superblock_to_private( | 1740 | &ecryptfs_superblock_to_private( |
1741 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 1741 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
@@ -1746,27 +1746,18 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry, | |||
1746 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); | 1746 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); |
1747 | if (!page_virt) { | 1747 | if (!page_virt) { |
1748 | rc = -ENOMEM; | 1748 | rc = -ENOMEM; |
1749 | ecryptfs_printk(KERN_ERR, "Unable to allocate page_virt\n"); | 1749 | printk(KERN_ERR "%s: Unable to allocate page_virt\n", |
1750 | __FUNCTION__); | ||
1750 | goto out; | 1751 | goto out; |
1751 | } | 1752 | } |
1752 | lower_file->f_pos = 0; | 1753 | rc = ecryptfs_read_lower(page_virt, 0, crypt_stat->extent_size, |
1753 | oldfs = get_fs(); | 1754 | ecryptfs_inode); |
1754 | set_fs(get_ds()); | 1755 | if (!rc) |
1755 | bytes_read = lower_file->f_op->read(lower_file, | 1756 | rc = ecryptfs_read_headers_virt(page_virt, crypt_stat, |
1756 | (char __user *)page_virt, | 1757 | ecryptfs_dentry, |
1757 | ECRYPTFS_DEFAULT_EXTENT_SIZE, | 1758 | ECRYPTFS_VALIDATE_HEADER_SIZE); |
1758 | &lower_file->f_pos); | ||
1759 | set_fs(oldfs); | ||
1760 | if (bytes_read != ECRYPTFS_DEFAULT_EXTENT_SIZE) { | ||
1761 | rc = -EINVAL; | ||
1762 | goto out; | ||
1763 | } | ||
1764 | rc = ecryptfs_read_headers_virt(page_virt, crypt_stat, | ||
1765 | ecryptfs_dentry, | ||
1766 | ECRYPTFS_VALIDATE_HEADER_SIZE); | ||
1767 | if (rc) { | 1759 | if (rc) { |
1768 | rc = ecryptfs_read_xattr_region(page_virt, | 1760 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode); |
1769 | ecryptfs_dentry); | ||
1770 | if (rc) { | 1761 | if (rc) { |
1771 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " | 1762 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " |
1772 | "file header region or xattr region\n"); | 1763 | "file header region or xattr region\n"); |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 65f7ddfd4d4a..3e52b42fba06 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -570,13 +570,11 @@ int ecryptfs_writepage_and_release_lower_page(struct page *lower_page, | |||
570 | struct writeback_control *wbc); | 570 | struct writeback_control *wbc); |
571 | int ecryptfs_encrypt_page(struct page *page); | 571 | int ecryptfs_encrypt_page(struct page *page); |
572 | int ecryptfs_decrypt_page(struct page *page); | 572 | int ecryptfs_decrypt_page(struct page *page); |
573 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry, | 573 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry); |
574 | struct file *lower_file); | 574 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry); |
575 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry, | ||
576 | struct file *lower_file); | ||
577 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); | 575 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); |
578 | int ecryptfs_read_and_validate_header_region(char *data, struct dentry *dentry, | 576 | int ecryptfs_read_and_validate_header_region(char *data, |
579 | struct vfsmount *mnt); | 577 | struct inode *ecryptfs_inode); |
580 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, | 578 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, |
581 | struct dentry *ecryptfs_dentry); | 579 | struct dentry *ecryptfs_dentry); |
582 | u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat); | 580 | u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat); |
@@ -599,10 +597,13 @@ int ecryptfs_open_lower_file(struct file **lower_file, | |||
599 | int ecryptfs_close_lower_file(struct file *lower_file); | 597 | int ecryptfs_close_lower_file(struct file *lower_file); |
600 | ssize_t ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, | 598 | ssize_t ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, |
601 | size_t size); | 599 | size_t size); |
600 | ssize_t | ||
601 | ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, | ||
602 | void *value, size_t size); | ||
602 | int | 603 | int |
603 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 604 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
604 | size_t size, int flags); | 605 | size_t size, int flags); |
605 | int ecryptfs_read_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry); | 606 | int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode); |
606 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid); | 607 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid); |
607 | int ecryptfs_process_quit(uid_t uid, pid_t pid); | 608 | int ecryptfs_process_quit(uid_t uid, pid_t pid); |
608 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, | 609 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 59c846d29a8e..df70bfa176d9 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -248,7 +248,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
248 | mutex_lock(&crypt_stat->cs_mutex); | 248 | mutex_lock(&crypt_stat->cs_mutex); |
249 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) | 249 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) |
250 | || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { | 250 | || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { |
251 | rc = ecryptfs_read_metadata(ecryptfs_dentry, lower_file); | 251 | rc = ecryptfs_read_metadata(ecryptfs_dentry); |
252 | if (rc) { | 252 | if (rc) { |
253 | ecryptfs_printk(KERN_DEBUG, | 253 | ecryptfs_printk(KERN_DEBUG, |
254 | "Valid headers not found\n"); | 254 | "Valid headers not found\n"); |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index c746b5d8a336..a29dc31965fa 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -153,37 +153,30 @@ out: | |||
153 | 153 | ||
154 | /** | 154 | /** |
155 | * grow_file | 155 | * grow_file |
156 | * @ecryptfs_dentry: the ecryptfs dentry | 156 | * @ecryptfs_dentry: the eCryptfs dentry |
157 | * @lower_file: The lower file | ||
158 | * @inode: The ecryptfs inode | ||
159 | * @lower_inode: The lower inode | ||
160 | * | 157 | * |
161 | * This is the code which will grow the file to its correct size. | 158 | * This is the code which will grow the file to its correct size. |
162 | */ | 159 | */ |
163 | static int grow_file(struct dentry *ecryptfs_dentry, struct file *lower_file, | 160 | static int grow_file(struct dentry *ecryptfs_dentry) |
164 | struct inode *inode, struct inode *lower_inode) | ||
165 | { | 161 | { |
166 | int rc = 0; | 162 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; |
167 | struct file fake_file; | 163 | struct file fake_file; |
168 | struct ecryptfs_file_info tmp_file_info; | 164 | struct ecryptfs_file_info tmp_file_info; |
165 | char zero_virt[] = { 0x00 }; | ||
166 | int rc = 0; | ||
169 | 167 | ||
170 | memset(&fake_file, 0, sizeof(fake_file)); | 168 | memset(&fake_file, 0, sizeof(fake_file)); |
171 | fake_file.f_path.dentry = ecryptfs_dentry; | 169 | fake_file.f_path.dentry = ecryptfs_dentry; |
172 | memset(&tmp_file_info, 0, sizeof(tmp_file_info)); | 170 | memset(&tmp_file_info, 0, sizeof(tmp_file_info)); |
173 | ecryptfs_set_file_private(&fake_file, &tmp_file_info); | 171 | ecryptfs_set_file_private(&fake_file, &tmp_file_info); |
174 | ecryptfs_set_file_lower(&fake_file, lower_file); | 172 | ecryptfs_set_file_lower( |
175 | rc = ecryptfs_fill_zeros(&fake_file, 1); | 173 | &fake_file, |
176 | if (rc) { | 174 | ecryptfs_inode_to_private(ecryptfs_inode)->lower_file); |
177 | ecryptfs_inode_to_private(inode)->crypt_stat.flags |= | 175 | rc = ecryptfs_write(&fake_file, zero_virt, 0, 1); |
178 | ECRYPTFS_SECURITY_WARNING; | 176 | i_size_write(ecryptfs_inode, 0); |
179 | ecryptfs_printk(KERN_WARNING, "Error attempting to fill zeros " | 177 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); |
180 | "in file; rc = [%d]\n", rc); | 178 | ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= |
181 | goto out; | 179 | ECRYPTFS_NEW_FILE; |
182 | } | ||
183 | i_size_write(inode, 0); | ||
184 | rc = ecryptfs_write_inode_size_to_metadata(inode); | ||
185 | ecryptfs_inode_to_private(inode)->crypt_stat.flags |= ECRYPTFS_NEW_FILE; | ||
186 | out: | ||
187 | return rc; | 180 | return rc; |
188 | } | 181 | } |
189 | 182 | ||
@@ -197,53 +190,31 @@ out: | |||
197 | */ | 190 | */ |
198 | static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | 191 | static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) |
199 | { | 192 | { |
193 | struct ecryptfs_crypt_stat *crypt_stat = | ||
194 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | ||
200 | int rc = 0; | 195 | int rc = 0; |
201 | int lower_flags; | ||
202 | struct ecryptfs_crypt_stat *crypt_stat; | ||
203 | struct dentry *lower_dentry; | ||
204 | struct file *lower_file; | ||
205 | struct inode *inode, *lower_inode; | ||
206 | struct vfsmount *lower_mnt; | ||
207 | 196 | ||
208 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | ||
209 | ecryptfs_printk(KERN_DEBUG, "lower_dentry->d_name.name = [%s]\n", | ||
210 | lower_dentry->d_name.name); | ||
211 | inode = ecryptfs_dentry->d_inode; | ||
212 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | ||
213 | lower_flags = ((O_CREAT | O_TRUNC) & O_ACCMODE) | O_RDWR; | ||
214 | lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | ||
215 | /* Corresponding fput() at end of this function */ | ||
216 | rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt, | ||
217 | lower_flags); | ||
218 | if (rc) { | ||
219 | ecryptfs_printk(KERN_ERR, | ||
220 | "Error opening dentry; rc = [%i]\n", rc); | ||
221 | goto out; | ||
222 | } | ||
223 | lower_inode = lower_dentry->d_inode; | ||
224 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | 197 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { |
225 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); | 198 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); |
226 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | 199 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
227 | goto out_fput; | 200 | goto out; |
228 | } | 201 | } |
229 | crypt_stat->flags |= ECRYPTFS_NEW_FILE; | 202 | crypt_stat->flags |= ECRYPTFS_NEW_FILE; |
230 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); | 203 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); |
231 | rc = ecryptfs_new_file_context(ecryptfs_dentry); | 204 | rc = ecryptfs_new_file_context(ecryptfs_dentry); |
232 | if (rc) { | 205 | if (rc) { |
233 | ecryptfs_printk(KERN_DEBUG, "Error creating new file " | 206 | ecryptfs_printk(KERN_ERR, "Error creating new file " |
234 | "context\n"); | 207 | "context; rc = [%d]\n", rc); |
235 | goto out_fput; | 208 | goto out; |
236 | } | 209 | } |
237 | rc = ecryptfs_write_metadata(ecryptfs_dentry, lower_file); | 210 | rc = ecryptfs_write_metadata(ecryptfs_dentry); |
238 | if (rc) { | 211 | if (rc) { |
239 | ecryptfs_printk(KERN_DEBUG, "Error writing headers\n"); | 212 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); |
240 | goto out_fput; | 213 | goto out; |
241 | } | 214 | } |
242 | rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode); | 215 | rc = grow_file(ecryptfs_dentry); |
243 | out_fput: | ||
244 | rc = ecryptfs_close_lower_file(lower_file); | ||
245 | if (rc) | 216 | if (rc) |
246 | printk(KERN_ERR "Error closing lower_file\n"); | 217 | printk(KERN_ERR "Error growing file; rc = [%d]\n", rc); |
247 | out: | 218 | out: |
248 | return rc; | 219 | return rc; |
249 | } | 220 | } |
@@ -389,8 +360,8 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
389 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 360 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
390 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) | 361 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) |
391 | ecryptfs_set_default_sizes(crypt_stat); | 362 | ecryptfs_set_default_sizes(crypt_stat); |
392 | rc = ecryptfs_read_and_validate_header_region(page_virt, lower_dentry, | 363 | rc = ecryptfs_read_and_validate_header_region(page_virt, |
393 | nd->mnt); | 364 | dentry->d_inode); |
394 | if (rc) { | 365 | if (rc) { |
395 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry); | 366 | rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry); |
396 | if (rc) { | 367 | if (rc) { |
@@ -941,7 +912,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
941 | } | 912 | } |
942 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 913 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
943 | dentry->d_sb)->mount_crypt_stat; | 914 | dentry->d_sb)->mount_crypt_stat; |
944 | rc = ecryptfs_read_metadata(dentry, lower_file); | 915 | rc = ecryptfs_read_metadata(dentry); |
945 | if (rc) { | 916 | if (rc) { |
946 | if (!(mount_crypt_stat->flags | 917 | if (!(mount_crypt_stat->flags |
947 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | 918 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { |
@@ -1003,6 +974,24 @@ out: | |||
1003 | } | 974 | } |
1004 | 975 | ||
1005 | ssize_t | 976 | ssize_t |
977 | ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, | ||
978 | void *value, size_t size) | ||
979 | { | ||
980 | int rc = 0; | ||
981 | |||
982 | if (!lower_dentry->d_inode->i_op->getxattr) { | ||
983 | rc = -ENOSYS; | ||
984 | goto out; | ||
985 | } | ||
986 | mutex_lock(&lower_dentry->d_inode->i_mutex); | ||
987 | rc = lower_dentry->d_inode->i_op->getxattr(lower_dentry, name, value, | ||
988 | size); | ||
989 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | ||
990 | out: | ||
991 | return rc; | ||
992 | } | ||
993 | |||
994 | ssize_t | ||
1006 | ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, | 995 | ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, |
1007 | size_t size) | 996 | size_t size) |
1008 | { | 997 | { |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 9b621108d5c1..60e635eddc77 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -307,7 +307,7 @@ static int ecryptfs_readpage(struct file *file, struct page *page) | |||
307 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 307 | memset(page_virt, 0, PAGE_CACHE_SIZE); |
308 | if (page->index == 0) { | 308 | if (page->index == 0) { |
309 | rc = ecryptfs_read_xattr_region( | 309 | rc = ecryptfs_read_xattr_region( |
310 | page_virt, file->f_path.dentry); | 310 | page_virt, page->mapping->host); |
311 | set_header_info(page_virt, crypt_stat); | 311 | set_header_info(page_virt, crypt_stat); |
312 | } | 312 | } |
313 | kunmap_atomic(page_virt, KM_USER0); | 313 | kunmap_atomic(page_virt, KM_USER0); |