Re: [PATCH 4/11] eCryptfs: Replace encrypt, decrypt, and inode size write
In message <[EMAIL PROTECTED]>, Michael Halcrow writes: > On Wed, Sep 19, 2007 at 10:46:26PM -0700, Andrew Morton wrote: > (from ecryptfs_encrypt_page()): > > > + enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER); > > > > I'd have thought that alloc_page() would be nicer. After all, we _are_ > > treating it as a page, and not as a random piece of memry. > > > > > + if (!enc_extent_virt) { > > > + rc = -ENOMEM; > > > + ecryptfs_printk(KERN_ERR, "Error allocating memory for " > > > + "encrypted extent\n"); > > > + goto out; > > > + } > > > + enc_extent_page = virt_to_page(enc_extent_virt); > > > > And then we don't need this. > > If neither kmap() nor kmap_atomic() can be safely used to get a > virtual address to pass to vfs_write(), then I do not know what my > other options are here. kmap_atomic is intended for short-lived code sections, where you may not sleep, so you can't do a vfs_read/write in b/t kmap/kunmap_atomic. Erez. - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/11] eCryptfs: Replace encrypt, decrypt, and inode size write
On Wed, Sep 19, 2007 at 10:46:26PM -0700, Andrew Morton wrote: (from ecryptfs_encrypt_page()): > > + enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER); > > I'd have thought that alloc_page() would be nicer. After all, we _are_ > treating it as a page, and not as a random piece of memry. > > > + if (!enc_extent_virt) { > > + rc = -ENOMEM; > > + ecryptfs_printk(KERN_ERR, "Error allocating memory for " > > + "encrypted extent\n"); > > + goto out; > > + } > > + enc_extent_page = virt_to_page(enc_extent_virt); > > And then we don't need this. If neither kmap() nor kmap_atomic() can be safely used to get a virtual address to pass to vfs_write(), then I do not know what my other options are here. - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/11] eCryptfs: Replace encrypt, decrypt, and inode size write
On Mon, 17 Sep 2007 16:47:10 -0500 Michael Halcrow <[EMAIL PROTECTED]> wrote: > Replace page encryption and decryption routines and inode size write > routine with versions that utilize the read_write.c functions. > > Signed-off-by: Michael Halcrow <[EMAIL PROTECTED]> > --- > fs/ecryptfs/crypto.c | 427 ++-- > fs/ecryptfs/ecryptfs_kernel.h | 14 +- > fs/ecryptfs/inode.c | 12 +- > fs/ecryptfs/mmap.c| 131 - > fs/ecryptfs/read_write.c | 12 +- > 5 files changed, 290 insertions(+), 306 deletions(-) > > diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c > index 5d8a553..b829d3c 100644 > --- a/fs/ecryptfs/crypto.c > +++ b/fs/ecryptfs/crypto.c > @@ -467,8 +467,91 @@ out: > } > > /** > + * ecryptfs_lower_offset_for_extent > + * > + * Convert an eCryptfs page index into a lower byte offset > + */ > +void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, > + struct ecryptfs_crypt_stat *crypt_stat) > +{ > + (*offset) = ((crypt_stat->extent_size > + * crypt_stat->num_header_extents_at_front) > + + (crypt_stat->extent_size * extent_num)); > +} > + > +/** > + * ecryptfs_encrypt_extent > + * @enc_extent_page: Allocated page into which to encrypt the data in > + * @page > + * @crypt_stat: crypt_stat containing cryptographic context for the > + * encryption operation > + * @page: Page containing plaintext data extent to encrypt > + * @extent_offset: Page extent offset for use in generating IV > + * > + * Encrypts one extent of data. > + * > + * Return zero on success; non-zero otherwise > + */ > +static int ecryptfs_encrypt_extent(struct page *enc_extent_page, > +struct ecryptfs_crypt_stat *crypt_stat, > +struct page *page, > +unsigned long extent_offset) > +{ > + unsigned long extent_base; > + char extent_iv[ECRYPTFS_MAX_IV_BYTES]; > + int rc; > + > + extent_base = (page->index > +* (PAGE_CACHE_SIZE / crypt_stat->extent_size)); I think this is vulnerable to overflow on 32-bit machines? > + rc = ecryptfs_derive_iv(extent_iv, crypt_stat, > + (extent_base + extent_offset)); > + if (rc) { > + ecryptfs_printk(KERN_ERR, "Error attempting to " > + "derive IV for extent [0x%.16x]; " > + "rc = [%d]\n", (extent_base + extent_offset), > + rc); > + goto out; > + } > + if (unlikely(ecryptfs_verbosity > 0)) { > + ecryptfs_printk(KERN_DEBUG, "Encrypting extent " > + "with iv:\n"); > + ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); > + ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " > + "encryption:\n"); > + ecryptfs_dump_hex((char *) > + (page_address(page) > ++ (extent_offset * crypt_stat->extent_size)), > + 8); > + } > + rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0, > + page, (extent_offset > + * crypt_stat->extent_size), maybe that is too, dunno. > + crypt_stat->extent_size, extent_iv); > + if (rc < 0) { > + printk(KERN_ERR "%s: Error attempting to encrypt page with " > +"page->index = [%ld], extent_offset = [%ld]; " > +"rc = [%d]\n", __FUNCTION__, page->index, extent_offset, > +rc); > + goto out; > + } > + rc = 0; > + if (unlikely(ecryptfs_verbosity > 0)) { > + ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; " > + "rc = [%d]\n", (extent_base + extent_offset), > + rc); > + ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " > + "encryption:\n"); > + ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8); > + } > +out: > + return rc; > +} > + > +/** > * ecryptfs_encrypt_page > - * @ctx: The context of the page > + * @page: Page mapped from the eCryptfs inode for the file; contains > + *decrypted content that needs to be encrypted (to a temporary > + *page; not in place) and written out to the lower file > * > * Encrypt an eCryptfs page. This is done on a per-extent basis. Note > * that eCryptfs pages may straddle the lower pages -- for instance, > @@ -478,128 +561,121 @@ out: > * file, 24K of page 0 of the lower file will be read and decrypted, > * and then 8K of page 1 of the lower file will be read and decrypted.
[PATCH 4/11] eCryptfs: Replace encrypt, decrypt, and inode size write
Replace page encryption and decryption routines and inode size write routine with versions that utilize the read_write.c functions. Signed-off-by: Michael Halcrow <[EMAIL PROTECTED]> --- fs/ecryptfs/crypto.c | 427 ++-- fs/ecryptfs/ecryptfs_kernel.h | 14 +- fs/ecryptfs/inode.c | 12 +- fs/ecryptfs/mmap.c| 131 - fs/ecryptfs/read_write.c | 12 +- 5 files changed, 290 insertions(+), 306 deletions(-) diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 5d8a553..b829d3c 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -467,8 +467,91 @@ out: } /** + * ecryptfs_lower_offset_for_extent + * + * Convert an eCryptfs page index into a lower byte offset + */ +void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, + struct ecryptfs_crypt_stat *crypt_stat) +{ + (*offset) = ((crypt_stat->extent_size + * crypt_stat->num_header_extents_at_front) ++ (crypt_stat->extent_size * extent_num)); +} + +/** + * ecryptfs_encrypt_extent + * @enc_extent_page: Allocated page into which to encrypt the data in + * @page + * @crypt_stat: crypt_stat containing cryptographic context for the + * encryption operation + * @page: Page containing plaintext data extent to encrypt + * @extent_offset: Page extent offset for use in generating IV + * + * Encrypts one extent of data. + * + * Return zero on success; non-zero otherwise + */ +static int ecryptfs_encrypt_extent(struct page *enc_extent_page, + struct ecryptfs_crypt_stat *crypt_stat, + struct page *page, + unsigned long extent_offset) +{ + unsigned long extent_base; + char extent_iv[ECRYPTFS_MAX_IV_BYTES]; + int rc; + + extent_base = (page->index + * (PAGE_CACHE_SIZE / crypt_stat->extent_size)); + rc = ecryptfs_derive_iv(extent_iv, crypt_stat, + (extent_base + extent_offset)); + if (rc) { + ecryptfs_printk(KERN_ERR, "Error attempting to " + "derive IV for extent [0x%.16x]; " + "rc = [%d]\n", (extent_base + extent_offset), + rc); + goto out; + } + if (unlikely(ecryptfs_verbosity > 0)) { + ecryptfs_printk(KERN_DEBUG, "Encrypting extent " + "with iv:\n"); + ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); + ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " + "encryption:\n"); + ecryptfs_dump_hex((char *) + (page_address(page) + + (extent_offset * crypt_stat->extent_size)), + 8); + } + rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0, + page, (extent_offset +* crypt_stat->extent_size), + crypt_stat->extent_size, extent_iv); + if (rc < 0) { + printk(KERN_ERR "%s: Error attempting to encrypt page with " + "page->index = [%ld], extent_offset = [%ld]; " + "rc = [%d]\n", __FUNCTION__, page->index, extent_offset, + rc); + goto out; + } + rc = 0; + if (unlikely(ecryptfs_verbosity > 0)) { + ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; " + "rc = [%d]\n", (extent_base + extent_offset), + rc); + ecryptfs_printk(KERN_DEBUG, "First 8 bytes after " + "encryption:\n"); + ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8); + } +out: + return rc; +} + +/** * ecryptfs_encrypt_page - * @ctx: The context of the page + * @page: Page mapped from the eCryptfs inode for the file; contains + *decrypted content that needs to be encrypted (to a temporary + *page; not in place) and written out to the lower file * * Encrypt an eCryptfs page. This is done on a per-extent basis. Note * that eCryptfs pages may straddle the lower pages -- for instance, @@ -478,128 +561,121 @@ out: * file, 24K of page 0 of the lower file will be read and decrypted, * and then 8K of page 1 of the lower file will be read and decrypted. * - * The actual operations performed on each page depends on the - * contents of the ecryptfs_page_crypt_context struct. - * * Returns zero on success; negative on error */ -int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx) +int ecryptfs_encrypt_page(struct page