diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-25 18:03:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-25 18:03:04 -0500 |
commit | 3074c0350b173c9e98b62685e0a61a66d9ff8728 (patch) | |
tree | 28f2cd48f1278983b1fa7d5b4a5895882ce5ca84 /fs | |
parent | f8275f9694b8adf9f3498e747ea4c3e8b984499b (diff) | |
parent | 58ded24f0fcb85bddb665baba75892f6ad0f4b8a (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs
Says Tyler:
"Tim's logging message update will be really helpful to users when
they're trying to locate a problematic file in the lower filesystem
with filename encryption enabled.
You'll recognize the fix from Li, as you commented on that.
You should also be familiar with my setattr/truncate improvements,
since you were the one that pointed them out to us (thanks again!).
Andrew noted the /dev/ecryptfs write count sanitization needed to be
improved, so I've got a fix in there for that along with some other
less important cleanups of the /dev/ecryptfs read/write code."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs:
eCryptfs: Fix oops when printing debug info in extent crypto functions
eCryptfs: Remove unused ecryptfs_read()
eCryptfs: Check inode changes in setattr
eCryptfs: Make truncate path killable
eCryptfs: Infinite loop due to overflow in ecryptfs_write()
eCryptfs: Replace miscdev read/write magic numbers
eCryptfs: Report errors in writes to /dev/ecryptfs
eCryptfs: Sanitize write counts of /dev/ecryptfs
ecryptfs: Remove unnecessary variable initialization
ecryptfs: Improve metadata read failure logging
MAINTAINERS: Update eCryptfs maintainer address
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ecryptfs/crypto.c | 54 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 5 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 48 | ||||
-rw-r--r-- | fs/ecryptfs/keystore.c | 5 | ||||
-rw-r--r-- | fs/ecryptfs/miscdev.c | 140 | ||||
-rw-r--r-- | fs/ecryptfs/read_write.c | 96 |
6 files changed, 154 insertions, 194 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 2a834255c75d..63ab24510649 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -417,17 +417,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page, | |||
417 | (unsigned long long)(extent_base + extent_offset), rc); | 417 | (unsigned long long)(extent_base + extent_offset), rc); |
418 | goto out; | 418 | goto out; |
419 | } | 419 | } |
420 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
421 | ecryptfs_printk(KERN_DEBUG, "Encrypting extent " | ||
422 | "with iv:\n"); | ||
423 | ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); | ||
424 | ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " | ||
425 | "encryption:\n"); | ||
426 | ecryptfs_dump_hex((char *) | ||
427 | (page_address(page) | ||
428 | + (extent_offset * crypt_stat->extent_size)), | ||
429 | 8); | ||
430 | } | ||
431 | rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0, | 420 | rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0, |
432 | page, (extent_offset | 421 | page, (extent_offset |
433 | * crypt_stat->extent_size), | 422 | * crypt_stat->extent_size), |
@@ -440,14 +429,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page, | |||
440 | goto out; | 429 | goto out; |
441 | } | 430 | } |
442 | rc = 0; | 431 | rc = 0; |
443 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
444 | ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16llx]; " | ||
445 | "rc = [%d]\n", | ||
446 | (unsigned long long)(extent_base + extent_offset), rc); | ||
447 | ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " | ||
448 | "encryption:\n"); | ||
449 | ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8); | ||
450 | } | ||
451 | out: | 432 | out: |
452 | return rc; | 433 | return rc; |
453 | } | 434 | } |
@@ -543,17 +524,6 @@ static int ecryptfs_decrypt_extent(struct page *page, | |||
543 | (unsigned long long)(extent_base + extent_offset), rc); | 524 | (unsigned long long)(extent_base + extent_offset), rc); |
544 | goto out; | 525 | goto out; |
545 | } | 526 | } |
546 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
547 | ecryptfs_printk(KERN_DEBUG, "Decrypting extent " | ||
548 | "with iv:\n"); | ||
549 | ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); | ||
550 | ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " | ||
551 | "decryption:\n"); | ||
552 | ecryptfs_dump_hex((char *) | ||
553 | (page_address(enc_extent_page) | ||
554 | + (extent_offset * crypt_stat->extent_size)), | ||
555 | 8); | ||
556 | } | ||
557 | rc = ecryptfs_decrypt_page_offset(crypt_stat, page, | 527 | rc = ecryptfs_decrypt_page_offset(crypt_stat, page, |
558 | (extent_offset | 528 | (extent_offset |
559 | * crypt_stat->extent_size), | 529 | * crypt_stat->extent_size), |
@@ -567,16 +537,6 @@ static int ecryptfs_decrypt_extent(struct page *page, | |||
567 | goto out; | 537 | goto out; |
568 | } | 538 | } |
569 | rc = 0; | 539 | rc = 0; |
570 | if (unlikely(ecryptfs_verbosity > 0)) { | ||
571 | ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16llx]; " | ||
572 | "rc = [%d]\n", | ||
573 | (unsigned long long)(extent_base + extent_offset), rc); | ||
574 | ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " | ||
575 | "decryption:\n"); | ||
576 | ecryptfs_dump_hex((char *)(page_address(page) | ||
577 | + (extent_offset | ||
578 | * crypt_stat->extent_size)), 8); | ||
579 | } | ||
580 | out: | 540 | out: |
581 | return rc; | 541 | return rc; |
582 | } | 542 | } |
@@ -1590,8 +1550,8 @@ int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry, | |||
1590 | */ | 1550 | */ |
1591 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) | 1551 | int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) |
1592 | { | 1552 | { |
1593 | int rc = 0; | 1553 | int rc; |
1594 | char *page_virt = NULL; | 1554 | char *page_virt; |
1595 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; | 1555 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; |
1596 | struct ecryptfs_crypt_stat *crypt_stat = | 1556 | struct ecryptfs_crypt_stat *crypt_stat = |
1597 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | 1557 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
@@ -1616,11 +1576,13 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) | |||
1616 | ecryptfs_dentry, | 1576 | ecryptfs_dentry, |
1617 | ECRYPTFS_VALIDATE_HEADER_SIZE); | 1577 | ECRYPTFS_VALIDATE_HEADER_SIZE); |
1618 | if (rc) { | 1578 | if (rc) { |
1579 | /* metadata is not in the file header, so try xattrs */ | ||
1619 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 1580 | memset(page_virt, 0, PAGE_CACHE_SIZE); |
1620 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode); | 1581 | rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode); |
1621 | if (rc) { | 1582 | if (rc) { |
1622 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " | 1583 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " |
1623 | "file header region or xattr region\n"); | 1584 | "file header region or xattr region, inode %lu\n", |
1585 | ecryptfs_inode->i_ino); | ||
1624 | rc = -EINVAL; | 1586 | rc = -EINVAL; |
1625 | goto out; | 1587 | goto out; |
1626 | } | 1588 | } |
@@ -1629,7 +1591,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) | |||
1629 | ECRYPTFS_DONT_VALIDATE_HEADER_SIZE); | 1591 | ECRYPTFS_DONT_VALIDATE_HEADER_SIZE); |
1630 | if (rc) { | 1592 | if (rc) { |
1631 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " | 1593 | printk(KERN_DEBUG "Valid eCryptfs headers not found in " |
1632 | "file xattr region either\n"); | 1594 | "file xattr region either, inode %lu\n", |
1595 | ecryptfs_inode->i_ino); | ||
1633 | rc = -EINVAL; | 1596 | rc = -EINVAL; |
1634 | } | 1597 | } |
1635 | if (crypt_stat->mount_crypt_stat->flags | 1598 | if (crypt_stat->mount_crypt_stat->flags |
@@ -1640,7 +1603,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) | |||
1640 | "crypto metadata only in the extended attribute " | 1603 | "crypto metadata only in the extended attribute " |
1641 | "region, but eCryptfs was mounted without " | 1604 | "region, but eCryptfs was mounted without " |
1642 | "xattr support enabled. eCryptfs will not treat " | 1605 | "xattr support enabled. eCryptfs will not treat " |
1643 | "this like an encrypted file.\n"); | 1606 | "this like an encrypted file, inode %lu\n", |
1607 | ecryptfs_inode->i_ino); | ||
1644 | rc = -EINVAL; | 1608 | rc = -EINVAL; |
1645 | } | 1609 | } |
1646 | } | 1610 | } |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index a9f29b12fbf2..a2362df58ae8 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -151,6 +151,11 @@ ecryptfs_get_key_payload_data(struct key *key) | |||
151 | * dentry name */ | 151 | * dentry name */ |
152 | #define ECRYPTFS_TAG_73_PACKET_TYPE 0x49 /* FEK-encrypted filename as | 152 | #define ECRYPTFS_TAG_73_PACKET_TYPE 0x49 /* FEK-encrypted filename as |
153 | * metadata */ | 153 | * metadata */ |
154 | #define ECRYPTFS_MIN_PKT_LEN_SIZE 1 /* Min size to specify packet length */ | ||
155 | #define ECRYPTFS_MAX_PKT_LEN_SIZE 2 /* Pass at least this many bytes to | ||
156 | * ecryptfs_parse_packet_length() and | ||
157 | * ecryptfs_write_packet_length() | ||
158 | */ | ||
154 | /* Constraint: ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES >= | 159 | /* Constraint: ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES >= |
155 | * ECRYPTFS_MAX_IV_BYTES */ | 160 | * ECRYPTFS_MAX_IV_BYTES */ |
156 | #define ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES 16 | 161 | #define ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES 16 |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 19a8ca4ab1dd..19892d7d2ed1 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -822,18 +822,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
822 | size_t num_zeros = (PAGE_CACHE_SIZE | 822 | size_t num_zeros = (PAGE_CACHE_SIZE |
823 | - (ia->ia_size & ~PAGE_CACHE_MASK)); | 823 | - (ia->ia_size & ~PAGE_CACHE_MASK)); |
824 | 824 | ||
825 | |||
826 | /* | ||
827 | * XXX(truncate) this should really happen at the begginning | ||
828 | * of ->setattr. But the code is too messy to that as part | ||
829 | * of a larger patch. ecryptfs is also totally missing out | ||
830 | * on the inode_change_ok check at the beginning of | ||
831 | * ->setattr while would include this. | ||
832 | */ | ||
833 | rc = inode_newsize_ok(inode, ia->ia_size); | ||
834 | if (rc) | ||
835 | goto out; | ||
836 | |||
837 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | 825 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
838 | truncate_setsize(inode, ia->ia_size); | 826 | truncate_setsize(inode, ia->ia_size); |
839 | lower_ia->ia_size = ia->ia_size; | 827 | lower_ia->ia_size = ia->ia_size; |
@@ -883,6 +871,28 @@ out: | |||
883 | return rc; | 871 | return rc; |
884 | } | 872 | } |
885 | 873 | ||
874 | static int ecryptfs_inode_newsize_ok(struct inode *inode, loff_t offset) | ||
875 | { | ||
876 | struct ecryptfs_crypt_stat *crypt_stat; | ||
877 | loff_t lower_oldsize, lower_newsize; | ||
878 | |||
879 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | ||
880 | lower_oldsize = upper_size_to_lower_size(crypt_stat, | ||
881 | i_size_read(inode)); | ||
882 | lower_newsize = upper_size_to_lower_size(crypt_stat, offset); | ||
883 | if (lower_newsize > lower_oldsize) { | ||
884 | /* | ||
885 | * The eCryptfs inode and the new *lower* size are mixed here | ||
886 | * because we may not have the lower i_mutex held and/or it may | ||
887 | * not be appropriate to call inode_newsize_ok() with inodes | ||
888 | * from other filesystems. | ||
889 | */ | ||
890 | return inode_newsize_ok(inode, lower_newsize); | ||
891 | } | ||
892 | |||
893 | return 0; | ||
894 | } | ||
895 | |||
886 | /** | 896 | /** |
887 | * ecryptfs_truncate | 897 | * ecryptfs_truncate |
888 | * @dentry: The ecryptfs layer dentry | 898 | * @dentry: The ecryptfs layer dentry |
@@ -899,6 +909,10 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
899 | struct iattr lower_ia = { .ia_valid = 0 }; | 909 | struct iattr lower_ia = { .ia_valid = 0 }; |
900 | int rc; | 910 | int rc; |
901 | 911 | ||
912 | rc = ecryptfs_inode_newsize_ok(dentry->d_inode, new_length); | ||
913 | if (rc) | ||
914 | return rc; | ||
915 | |||
902 | rc = truncate_upper(dentry, &ia, &lower_ia); | 916 | rc = truncate_upper(dentry, &ia, &lower_ia); |
903 | if (!rc && lower_ia.ia_valid & ATTR_SIZE) { | 917 | if (!rc && lower_ia.ia_valid & ATTR_SIZE) { |
904 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | 918 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); |
@@ -978,6 +992,16 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
978 | } | 992 | } |
979 | } | 993 | } |
980 | mutex_unlock(&crypt_stat->cs_mutex); | 994 | mutex_unlock(&crypt_stat->cs_mutex); |
995 | |||
996 | rc = inode_change_ok(inode, ia); | ||
997 | if (rc) | ||
998 | goto out; | ||
999 | if (ia->ia_valid & ATTR_SIZE) { | ||
1000 | rc = ecryptfs_inode_newsize_ok(inode, ia->ia_size); | ||
1001 | if (rc) | ||
1002 | goto out; | ||
1003 | } | ||
1004 | |||
981 | if (S_ISREG(inode->i_mode)) { | 1005 | if (S_ISREG(inode->i_mode)) { |
982 | rc = filemap_write_and_wait(inode->i_mapping); | 1006 | rc = filemap_write_and_wait(inode->i_mapping); |
983 | if (rc) | 1007 | if (rc) |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index ac1ad48c2376..8e3b943e330f 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -109,7 +109,7 @@ int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, | |||
109 | (*size) += ((unsigned char)(data[1]) + 192); | 109 | (*size) += ((unsigned char)(data[1]) + 192); |
110 | (*length_size) = 2; | 110 | (*length_size) = 2; |
111 | } else if (data[0] == 255) { | 111 | } else if (data[0] == 255) { |
112 | /* Five-byte length; we're not supposed to see this */ | 112 | /* If support is added, adjust ECRYPTFS_MAX_PKT_LEN_SIZE */ |
113 | ecryptfs_printk(KERN_ERR, "Five-byte packet length not " | 113 | ecryptfs_printk(KERN_ERR, "Five-byte packet length not " |
114 | "supported\n"); | 114 | "supported\n"); |
115 | rc = -EINVAL; | 115 | rc = -EINVAL; |
@@ -126,7 +126,7 @@ out: | |||
126 | /** | 126 | /** |
127 | * ecryptfs_write_packet_length | 127 | * ecryptfs_write_packet_length |
128 | * @dest: The byte array target into which to write the length. Must | 128 | * @dest: The byte array target into which to write the length. Must |
129 | * have at least 5 bytes allocated. | 129 | * have at least ECRYPTFS_MAX_PKT_LEN_SIZE bytes allocated. |
130 | * @size: The length to write. | 130 | * @size: The length to write. |
131 | * @packet_size_length: The number of bytes used to encode the packet | 131 | * @packet_size_length: The number of bytes used to encode the packet |
132 | * length is written to this address. | 132 | * length is written to this address. |
@@ -146,6 +146,7 @@ int ecryptfs_write_packet_length(char *dest, size_t size, | |||
146 | dest[1] = ((size - 192) % 256); | 146 | dest[1] = ((size - 192) % 256); |
147 | (*packet_size_length) = 2; | 147 | (*packet_size_length) = 2; |
148 | } else { | 148 | } else { |
149 | /* If support is added, adjust ECRYPTFS_MAX_PKT_LEN_SIZE */ | ||
149 | rc = -EINVAL; | 150 | rc = -EINVAL; |
150 | ecryptfs_printk(KERN_WARNING, | 151 | ecryptfs_printk(KERN_WARNING, |
151 | "Unsupported packet size: [%zd]\n", size); | 152 | "Unsupported packet size: [%zd]\n", size); |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 940a82e63dc3..349209dc6a91 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -218,6 +218,29 @@ out_unlock: | |||
218 | return rc; | 218 | return rc; |
219 | } | 219 | } |
220 | 220 | ||
221 | /* | ||
222 | * miscdevfs packet format: | ||
223 | * Octet 0: Type | ||
224 | * Octets 1-4: network byte order msg_ctx->counter | ||
225 | * Octets 5-N0: Size of struct ecryptfs_message to follow | ||
226 | * Octets N0-N1: struct ecryptfs_message (including data) | ||
227 | * | ||
228 | * Octets 5-N1 not written if the packet type does not include a message | ||
229 | */ | ||
230 | #define PKT_TYPE_SIZE 1 | ||
231 | #define PKT_CTR_SIZE 4 | ||
232 | #define MIN_NON_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE) | ||
233 | #define MIN_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE \ | ||
234 | + ECRYPTFS_MIN_PKT_LEN_SIZE) | ||
235 | /* 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES comes from tag 65 packet format */ | ||
236 | #define MAX_MSG_PKT_SIZE (PKT_TYPE_SIZE + PKT_CTR_SIZE \ | ||
237 | + ECRYPTFS_MAX_PKT_LEN_SIZE \ | ||
238 | + sizeof(struct ecryptfs_message) \ | ||
239 | + 4 + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) | ||
240 | #define PKT_TYPE_OFFSET 0 | ||
241 | #define PKT_CTR_OFFSET PKT_TYPE_SIZE | ||
242 | #define PKT_LEN_OFFSET (PKT_TYPE_SIZE + PKT_CTR_SIZE) | ||
243 | |||
221 | /** | 244 | /** |
222 | * ecryptfs_miscdev_read - format and send message from queue | 245 | * ecryptfs_miscdev_read - format and send message from queue |
223 | * @file: fs/ecryptfs/euid miscdevfs handle (ignored) | 246 | * @file: fs/ecryptfs/euid miscdevfs handle (ignored) |
@@ -237,7 +260,7 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, | |||
237 | struct ecryptfs_daemon *daemon; | 260 | struct ecryptfs_daemon *daemon; |
238 | struct ecryptfs_msg_ctx *msg_ctx; | 261 | struct ecryptfs_msg_ctx *msg_ctx; |
239 | size_t packet_length_size; | 262 | size_t packet_length_size; |
240 | char packet_length[3]; | 263 | char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE]; |
241 | size_t i; | 264 | size_t i; |
242 | size_t total_length; | 265 | size_t total_length; |
243 | uid_t euid = current_euid(); | 266 | uid_t euid = current_euid(); |
@@ -305,15 +328,8 @@ check_list: | |||
305 | packet_length_size = 0; | 328 | packet_length_size = 0; |
306 | msg_ctx->msg_size = 0; | 329 | msg_ctx->msg_size = 0; |
307 | } | 330 | } |
308 | /* miscdevfs packet format: | 331 | total_length = (PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_length_size |
309 | * Octet 0: Type | 332 | + msg_ctx->msg_size); |
310 | * Octets 1-4: network byte order msg_ctx->counter | ||
311 | * Octets 5-N0: Size of struct ecryptfs_message to follow | ||
312 | * Octets N0-N1: struct ecryptfs_message (including data) | ||
313 | * | ||
314 | * Octets 5-N1 not written if the packet type does not | ||
315 | * include a message */ | ||
316 | total_length = (1 + 4 + packet_length_size + msg_ctx->msg_size); | ||
317 | if (count < total_length) { | 333 | if (count < total_length) { |
318 | rc = 0; | 334 | rc = 0; |
319 | printk(KERN_WARNING "%s: Only given user buffer of " | 335 | printk(KERN_WARNING "%s: Only given user buffer of " |
@@ -324,9 +340,10 @@ check_list: | |||
324 | rc = -EFAULT; | 340 | rc = -EFAULT; |
325 | if (put_user(msg_ctx->type, buf)) | 341 | if (put_user(msg_ctx->type, buf)) |
326 | goto out_unlock_msg_ctx; | 342 | goto out_unlock_msg_ctx; |
327 | if (put_user(cpu_to_be32(msg_ctx->counter), (__be32 __user *)(buf + 1))) | 343 | if (put_user(cpu_to_be32(msg_ctx->counter), |
344 | (__be32 __user *)(&buf[PKT_CTR_OFFSET]))) | ||
328 | goto out_unlock_msg_ctx; | 345 | goto out_unlock_msg_ctx; |
329 | i = 5; | 346 | i = PKT_TYPE_SIZE + PKT_CTR_SIZE; |
330 | if (msg_ctx->msg) { | 347 | if (msg_ctx->msg) { |
331 | if (copy_to_user(&buf[i], packet_length, packet_length_size)) | 348 | if (copy_to_user(&buf[i], packet_length, packet_length_size)) |
332 | goto out_unlock_msg_ctx; | 349 | goto out_unlock_msg_ctx; |
@@ -391,12 +408,6 @@ out: | |||
391 | * @count: Amount of data in @buf | 408 | * @count: Amount of data in @buf |
392 | * @ppos: Pointer to offset in file (ignored) | 409 | * @ppos: Pointer to offset in file (ignored) |
393 | * | 410 | * |
394 | * miscdevfs packet format: | ||
395 | * Octet 0: Type | ||
396 | * Octets 1-4: network byte order msg_ctx->counter (0's for non-response) | ||
397 | * Octets 5-N0: Size of struct ecryptfs_message to follow | ||
398 | * Octets N0-N1: struct ecryptfs_message (including data) | ||
399 | * | ||
400 | * Returns the number of bytes read from @buf | 411 | * Returns the number of bytes read from @buf |
401 | */ | 412 | */ |
402 | static ssize_t | 413 | static ssize_t |
@@ -405,60 +416,78 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
405 | { | 416 | { |
406 | __be32 counter_nbo; | 417 | __be32 counter_nbo; |
407 | u32 seq; | 418 | u32 seq; |
408 | size_t packet_size, packet_size_length, i; | 419 | size_t packet_size, packet_size_length; |
409 | ssize_t sz = 0; | ||
410 | char *data; | 420 | char *data; |
411 | uid_t euid = current_euid(); | 421 | uid_t euid = current_euid(); |
412 | int rc; | 422 | unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE]; |
423 | ssize_t rc; | ||
413 | 424 | ||
414 | if (count == 0) | 425 | if (count == 0) { |
415 | goto out; | 426 | return 0; |
427 | } else if (count == MIN_NON_MSG_PKT_SIZE) { | ||
428 | /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */ | ||
429 | goto memdup; | ||
430 | } else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) { | ||
431 | printk(KERN_WARNING "%s: Acceptable packet size range is " | ||
432 | "[%d-%lu], but amount of data written is [%zu].", | ||
433 | __func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count); | ||
434 | return -EINVAL; | ||
435 | } | ||
436 | |||
437 | if (copy_from_user(packet_size_peek, &buf[PKT_LEN_OFFSET], | ||
438 | sizeof(packet_size_peek))) { | ||
439 | printk(KERN_WARNING "%s: Error while inspecting packet size\n", | ||
440 | __func__); | ||
441 | return -EFAULT; | ||
442 | } | ||
416 | 443 | ||
444 | rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size, | ||
445 | &packet_size_length); | ||
446 | if (rc) { | ||
447 | printk(KERN_WARNING "%s: Error parsing packet length; " | ||
448 | "rc = [%zd]\n", __func__, rc); | ||
449 | return rc; | ||
450 | } | ||
451 | |||
452 | if ((PKT_TYPE_SIZE + PKT_CTR_SIZE + packet_size_length + packet_size) | ||
453 | != count) { | ||
454 | printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__, | ||
455 | packet_size); | ||
456 | return -EINVAL; | ||
457 | } | ||
458 | |||
459 | memdup: | ||
417 | data = memdup_user(buf, count); | 460 | data = memdup_user(buf, count); |
418 | if (IS_ERR(data)) { | 461 | if (IS_ERR(data)) { |
419 | printk(KERN_ERR "%s: memdup_user returned error [%ld]\n", | 462 | printk(KERN_ERR "%s: memdup_user returned error [%ld]\n", |
420 | __func__, PTR_ERR(data)); | 463 | __func__, PTR_ERR(data)); |
421 | goto out; | 464 | return PTR_ERR(data); |
422 | } | 465 | } |
423 | sz = count; | 466 | switch (data[PKT_TYPE_OFFSET]) { |
424 | i = 0; | ||
425 | switch (data[i++]) { | ||
426 | case ECRYPTFS_MSG_RESPONSE: | 467 | case ECRYPTFS_MSG_RESPONSE: |
427 | if (count < (1 + 4 + 1 + sizeof(struct ecryptfs_message))) { | 468 | if (count < (MIN_MSG_PKT_SIZE |
469 | + sizeof(struct ecryptfs_message))) { | ||
428 | printk(KERN_WARNING "%s: Minimum acceptable packet " | 470 | printk(KERN_WARNING "%s: Minimum acceptable packet " |
429 | "size is [%zd], but amount of data written is " | 471 | "size is [%zd], but amount of data written is " |
430 | "only [%zd]. Discarding response packet.\n", | 472 | "only [%zd]. Discarding response packet.\n", |
431 | __func__, | 473 | __func__, |
432 | (1 + 4 + 1 + sizeof(struct ecryptfs_message)), | 474 | (MIN_MSG_PKT_SIZE |
433 | count); | 475 | + sizeof(struct ecryptfs_message)), count); |
476 | rc = -EINVAL; | ||
434 | goto out_free; | 477 | goto out_free; |
435 | } | 478 | } |
436 | memcpy(&counter_nbo, &data[i], 4); | 479 | memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE); |
437 | seq = be32_to_cpu(counter_nbo); | 480 | seq = be32_to_cpu(counter_nbo); |
438 | i += 4; | 481 | rc = ecryptfs_miscdev_response( |
439 | rc = ecryptfs_parse_packet_length(&data[i], &packet_size, | 482 | &data[PKT_LEN_OFFSET + packet_size_length], |
440 | &packet_size_length); | 483 | packet_size, euid, current_user_ns(), |
484 | task_pid(current), seq); | ||
441 | if (rc) { | 485 | if (rc) { |
442 | printk(KERN_WARNING "%s: Error parsing packet length; " | ||
443 | "rc = [%d]\n", __func__, rc); | ||
444 | goto out_free; | ||
445 | } | ||
446 | i += packet_size_length; | ||
447 | if ((1 + 4 + packet_size_length + packet_size) != count) { | ||
448 | printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])" | ||
449 | " + packet_size([%zd]))([%zd]) != " | ||
450 | "count([%zd]). Invalid packet format.\n", | ||
451 | __func__, packet_size_length, packet_size, | ||
452 | (1 + packet_size_length + packet_size), count); | ||
453 | goto out_free; | ||
454 | } | ||
455 | rc = ecryptfs_miscdev_response(&data[i], packet_size, | ||
456 | euid, current_user_ns(), | ||
457 | task_pid(current), seq); | ||
458 | if (rc) | ||
459 | printk(KERN_WARNING "%s: Failed to deliver miscdev " | 486 | printk(KERN_WARNING "%s: Failed to deliver miscdev " |
460 | "response to requesting operation; rc = [%d]\n", | 487 | "response to requesting operation; rc = [%zd]\n", |
461 | __func__, rc); | 488 | __func__, rc); |
489 | goto out_free; | ||
490 | } | ||
462 | break; | 491 | break; |
463 | case ECRYPTFS_MSG_HELO: | 492 | case ECRYPTFS_MSG_HELO: |
464 | case ECRYPTFS_MSG_QUIT: | 493 | case ECRYPTFS_MSG_QUIT: |
@@ -467,12 +496,13 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
467 | ecryptfs_printk(KERN_WARNING, "Dropping miscdev " | 496 | ecryptfs_printk(KERN_WARNING, "Dropping miscdev " |
468 | "message of unrecognized type [%d]\n", | 497 | "message of unrecognized type [%d]\n", |
469 | data[0]); | 498 | data[0]); |
470 | break; | 499 | rc = -EINVAL; |
500 | goto out_free; | ||
471 | } | 501 | } |
502 | rc = count; | ||
472 | out_free: | 503 | out_free: |
473 | kfree(data); | 504 | kfree(data); |
474 | out: | 505 | return rc; |
475 | return sz; | ||
476 | } | 506 | } |
477 | 507 | ||
478 | 508 | ||
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 3745f7c2b9c2..5c0106f75775 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c | |||
@@ -130,13 +130,18 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, | |||
130 | pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT); | 130 | pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT); |
131 | size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK); | 131 | size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK); |
132 | size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); | 132 | size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); |
133 | size_t total_remaining_bytes = ((offset + size) - pos); | 133 | loff_t total_remaining_bytes = ((offset + size) - pos); |
134 | |||
135 | if (fatal_signal_pending(current)) { | ||
136 | rc = -EINTR; | ||
137 | break; | ||
138 | } | ||
134 | 139 | ||
135 | if (num_bytes > total_remaining_bytes) | 140 | if (num_bytes > total_remaining_bytes) |
136 | num_bytes = total_remaining_bytes; | 141 | num_bytes = total_remaining_bytes; |
137 | if (pos < offset) { | 142 | if (pos < offset) { |
138 | /* remaining zeros to write, up to destination offset */ | 143 | /* remaining zeros to write, up to destination offset */ |
139 | size_t total_remaining_zeros = (offset - pos); | 144 | loff_t total_remaining_zeros = (offset - pos); |
140 | 145 | ||
141 | if (num_bytes > total_remaining_zeros) | 146 | if (num_bytes > total_remaining_zeros) |
142 | num_bytes = total_remaining_zeros; | 147 | num_bytes = total_remaining_zeros; |
@@ -193,15 +198,19 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, | |||
193 | } | 198 | } |
194 | pos += num_bytes; | 199 | pos += num_bytes; |
195 | } | 200 | } |
196 | if ((offset + size) > ecryptfs_file_size) { | 201 | if (pos > ecryptfs_file_size) { |
197 | i_size_write(ecryptfs_inode, (offset + size)); | 202 | i_size_write(ecryptfs_inode, pos); |
198 | if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) { | 203 | if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) { |
199 | rc = ecryptfs_write_inode_size_to_metadata( | 204 | int rc2; |
205 | |||
206 | rc2 = ecryptfs_write_inode_size_to_metadata( | ||
200 | ecryptfs_inode); | 207 | ecryptfs_inode); |
201 | if (rc) { | 208 | if (rc2) { |
202 | printk(KERN_ERR "Problem with " | 209 | printk(KERN_ERR "Problem with " |
203 | "ecryptfs_write_inode_size_to_metadata; " | 210 | "ecryptfs_write_inode_size_to_metadata; " |
204 | "rc = [%d]\n", rc); | 211 | "rc = [%d]\n", rc2); |
212 | if (!rc) | ||
213 | rc = rc2; | ||
205 | goto out; | 214 | goto out; |
206 | } | 215 | } |
207 | } | 216 | } |
@@ -273,76 +282,3 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | |||
273 | flush_dcache_page(page_for_ecryptfs); | 282 | flush_dcache_page(page_for_ecryptfs); |
274 | return rc; | 283 | return rc; |
275 | } | 284 | } |
276 | |||
277 | #if 0 | ||
278 | /** | ||
279 | * ecryptfs_read | ||
280 | * @data: The virtual address into which to write the data read (and | ||
281 | * possibly decrypted) from the lower file | ||
282 | * @offset: The offset in the decrypted view of the file from which to | ||
283 | * read into @data | ||
284 | * @size: The number of bytes to read into @data | ||
285 | * @ecryptfs_file: The eCryptfs file from which to read | ||
286 | * | ||
287 | * Read an arbitrary amount of data from an arbitrary location in the | ||
288 | * eCryptfs page cache. This is done on an extent-by-extent basis; | ||
289 | * individual extents are decrypted and read from the lower page | ||
290 | * cache (via VFS reads). This function takes care of all the | ||
291 | * address translation to locations in the lower filesystem. | ||
292 | * | ||
293 | * Returns zero on success; non-zero otherwise | ||
294 | */ | ||
295 | int ecryptfs_read(char *data, loff_t offset, size_t size, | ||
296 | struct file *ecryptfs_file) | ||
297 | { | ||
298 | struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode; | ||
299 | struct page *ecryptfs_page; | ||
300 | char *ecryptfs_page_virt; | ||
301 | loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); | ||
302 | loff_t data_offset = 0; | ||
303 | loff_t pos; | ||
304 | int rc = 0; | ||
305 | |||
306 | if ((offset + size) > ecryptfs_file_size) { | ||
307 | rc = -EINVAL; | ||
308 | printk(KERN_ERR "%s: Attempt to read data past the end of the " | ||
309 | "file; offset = [%lld]; size = [%td]; " | ||
310 | "ecryptfs_file_size = [%lld]\n", | ||
311 | __func__, offset, size, ecryptfs_file_size); | ||
312 | goto out; | ||
313 | } | ||
314 | pos = offset; | ||
315 | while (pos < (offset + size)) { | ||
316 | pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT); | ||
317 | size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK); | ||
318 | size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); | ||
319 | size_t total_remaining_bytes = ((offset + size) - pos); | ||
320 | |||
321 | if (num_bytes > total_remaining_bytes) | ||
322 | num_bytes = total_remaining_bytes; | ||
323 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, | ||
324 | ecryptfs_page_idx); | ||
325 | if (IS_ERR(ecryptfs_page)) { | ||
326 | rc = PTR_ERR(ecryptfs_page); | ||
327 | printk(KERN_ERR "%s: Error getting page at " | ||
328 | "index [%ld] from eCryptfs inode " | ||
329 | "mapping; rc = [%d]\n", __func__, | ||
330 | ecryptfs_page_idx, rc); | ||
331 | goto out; | ||
332 | } | ||
333 | ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0); | ||
334 | memcpy((data + data_offset), | ||
335 | ((char *)ecryptfs_page_virt + start_offset_in_page), | ||
336 | num_bytes); | ||
337 | kunmap_atomic(ecryptfs_page_virt, KM_USER0); | ||
338 | flush_dcache_page(ecryptfs_page); | ||
339 | SetPageUptodate(ecryptfs_page); | ||
340 | unlock_page(ecryptfs_page); | ||
341 | page_cache_release(ecryptfs_page); | ||
342 | pos += num_bytes; | ||
343 | data_offset += num_bytes; | ||
344 | } | ||
345 | out: | ||
346 | return rc; | ||
347 | } | ||
348 | #endif /* 0 */ | ||