Code cleanups and improved buffer handling during page crypto operations

- Remove redundant code by merging some encrypt and decrypt functions
 - Get rid of a helper page allocation during page decryption by using in-place
   decryption
 - Better use of entire pages during page crypto operations
 - Several code cleanups
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIbBAABCgAGBQJR3Z1JAAoJENaSAD2qAscK+jAP92NR3W17njuPFJBHCROsS481
 tyhzy2W/LlNK1njnS6SRP3O3Icv3adiJRtMZePV7bpCH3yD/JoYZ6VHQBNV7msHW
 VuEwE6eqCkKl3NLunhwd4+m5R9qijJYGfYEzTve/RNASDU7/LPcTUF8OQ5dIB0wA
 J6IMGGZSpsFa8ymN01YzmUEmOUx1IBR2aYBT8Og4Ke117ywDYqxS0ghd1rb953sS
 7H8wnNcijs1DLGe71SZnKMVCYwO32GWarxDBAa0KsabcyY4Yr43O3ov/CsIAAA7B
 Q1Dn7KNNSOCu9G6fHrnuMOTncGnNPLhIe6Yc0PCZ7ykVstpzlNkKJ628IEonsJaJ
 4bYc3bqq4KH7rqMxjA+1GoLehpJWJzqwfiFI1fWLlYMmO2ky126rJUgSNBHQe9+M
 iWl+ZrYokSsNWBcUsIq7SJFaLIhWDNcb+Wl7RiTNBBwoBaZclrNuWKIyeWPhH+9/
 +/K3LBaggujzVpE743wgJhY60sfdHZmaRAD9agEbcG773JePXBg9OkiUp/hKSe8s
 UaGkfmwAlz8u6mR1eJCuFDCqwJKByyT4vObuOFroh7NgOHaQZghlnO4HwuOjzp6U
 wTUiMVslFY9WAsEWxdDhaCXxB8IrjHz3YZGIt8PU2eT6ucQU+HLvkkxqtzSYm9/7
 BBfryWZKwR7T50JdehI=
 =mRpN
 -----END PGP SIGNATURE-----

Merge tag 'ecryptfs-3.11-rc1-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs

Pull eCryptfs updates from Tyler Hicks:
 "Code cleanups and improved buffer handling during page crypto
  operations:
   - Remove redundant code by merging some encrypt and decrypt functions
   - Get rid of a helper page allocation during page decryption by using
     in-place decryption
   - Better use of entire pages during page crypto operations
   - Several code cleanups"

* tag 'ecryptfs-3.11-rc1-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs:
  Use ecryptfs_dentry_to_lower_path in a couple of places
  eCryptfs: Make extent and scatterlist crypt function parameters similar
  eCryptfs: Collapse crypt_page_offset() into crypt_extent()
  eCryptfs: Merge ecryptfs_encrypt_extent() and ecryptfs_decrypt_extent()
  eCryptfs: Combine page_offset crypto functions
  eCryptfs: Combine encrypt_scatterlist() and decrypt_scatterlist()
  eCryptfs: Decrypt pages in-place
  eCryptfs: Accept one offset parameter in page offset crypto functions
  eCryptfs: Simplify lower file offset calculation
  eCryptfs: Read/write entire page during page IO
  eCryptfs: Use entire helper page during page crypto operations
  eCryptfs: Cocci spatch "memdup.spatch"
This commit is contained in:
Linus Torvalds 2013-07-11 10:20:18 -07:00
commit 746919d266
4 changed files with 86 additions and 270 deletions

View file

@ -37,16 +37,8 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include "ecryptfs_kernel.h" #include "ecryptfs_kernel.h"
static int #define DECRYPT 0
ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat, #define ENCRYPT 1
struct page *dst_page, int dst_offset,
struct page *src_page, int src_offset, int size,
unsigned char *iv);
static int
ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
struct page *dst_page, int dst_offset,
struct page *src_page, int src_offset, int size,
unsigned char *iv);
/** /**
* ecryptfs_to_hex * ecryptfs_to_hex
@ -336,19 +328,20 @@ static void extent_crypt_complete(struct crypto_async_request *req, int rc)
} }
/** /**
* encrypt_scatterlist * crypt_scatterlist
* @crypt_stat: Pointer to the crypt_stat struct to initialize. * @crypt_stat: Pointer to the crypt_stat struct to initialize.
* @dest_sg: Destination of encrypted data * @dst_sg: Destination of the data after performing the crypto operation
* @src_sg: Data to be encrypted * @src_sg: Data to be encrypted or decrypted
* @size: Length of data to be encrypted * @size: Length of data
* @iv: iv to use during encryption * @iv: IV to use
* @op: ENCRYPT or DECRYPT to indicate the desired operation
* *
* Returns the number of bytes encrypted; negative value on error * Returns the number of bytes encrypted or decrypted; negative value on error
*/ */
static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
struct scatterlist *dest_sg, struct scatterlist *dst_sg,
struct scatterlist *src_sg, int size, struct scatterlist *src_sg, int size,
unsigned char *iv) unsigned char *iv, int op)
{ {
struct ablkcipher_request *req = NULL; struct ablkcipher_request *req = NULL;
struct extent_crypt_result ecr; struct extent_crypt_result ecr;
@ -391,9 +384,9 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
crypt_stat->flags |= ECRYPTFS_KEY_SET; crypt_stat->flags |= ECRYPTFS_KEY_SET;
} }
mutex_unlock(&crypt_stat->cs_tfm_mutex); mutex_unlock(&crypt_stat->cs_tfm_mutex);
ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size); ablkcipher_request_set_crypt(req, src_sg, dst_sg, size, iv);
ablkcipher_request_set_crypt(req, src_sg, dest_sg, size, iv); rc = op == ENCRYPT ? crypto_ablkcipher_encrypt(req) :
rc = crypto_ablkcipher_encrypt(req); crypto_ablkcipher_decrypt(req);
if (rc == -EINPROGRESS || rc == -EBUSY) { if (rc == -EINPROGRESS || rc == -EBUSY) {
struct extent_crypt_result *ecr = req->base.data; struct extent_crypt_result *ecr = req->base.data;
@ -407,41 +400,43 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
} }
/** /**
* ecryptfs_lower_offset_for_extent * lower_offset_for_page
* *
* Convert an eCryptfs page index into a lower byte offset * Convert an eCryptfs page index into a lower byte offset
*/ */
static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, static loff_t lower_offset_for_page(struct ecryptfs_crypt_stat *crypt_stat,
struct ecryptfs_crypt_stat *crypt_stat) struct page *page)
{ {
(*offset) = ecryptfs_lower_header_size(crypt_stat) return ecryptfs_lower_header_size(crypt_stat) +
+ (crypt_stat->extent_size * extent_num); (page->index << PAGE_CACHE_SHIFT);
} }
/** /**
* ecryptfs_encrypt_extent * crypt_extent
* @enc_extent_page: Allocated page into which to encrypt the data in
* @page
* @crypt_stat: crypt_stat containing cryptographic context for the * @crypt_stat: crypt_stat containing cryptographic context for the
* encryption operation * encryption operation
* @page: Page containing plaintext data extent to encrypt * @dst_page: The page to write the result into
* @src_page: The page to read from
* @extent_offset: Page extent offset for use in generating IV * @extent_offset: Page extent offset for use in generating IV
* @op: ENCRYPT or DECRYPT to indicate the desired operation
* *
* Encrypts one extent of data. * Encrypts or decrypts one extent of data.
* *
* Return zero on success; non-zero otherwise * Return zero on success; non-zero otherwise
*/ */
static int ecryptfs_encrypt_extent(struct page *enc_extent_page, static int crypt_extent(struct ecryptfs_crypt_stat *crypt_stat,
struct ecryptfs_crypt_stat *crypt_stat, struct page *dst_page,
struct page *page, struct page *src_page,
unsigned long extent_offset) unsigned long extent_offset, int op)
{ {
pgoff_t page_index = op == ENCRYPT ? src_page->index : dst_page->index;
loff_t extent_base; loff_t extent_base;
char extent_iv[ECRYPTFS_MAX_IV_BYTES]; char extent_iv[ECRYPTFS_MAX_IV_BYTES];
struct scatterlist src_sg, dst_sg;
size_t extent_size = crypt_stat->extent_size;
int rc; int rc;
extent_base = (((loff_t)page->index) extent_base = (((loff_t)page_index) * (PAGE_CACHE_SIZE / extent_size));
* (PAGE_CACHE_SIZE / crypt_stat->extent_size));
rc = ecryptfs_derive_iv(extent_iv, crypt_stat, rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
(extent_base + extent_offset)); (extent_base + extent_offset));
if (rc) { if (rc) {
@ -450,15 +445,21 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
(unsigned long long)(extent_base + extent_offset), rc); (unsigned long long)(extent_base + extent_offset), rc);
goto out; goto out;
} }
rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0,
page, (extent_offset sg_init_table(&src_sg, 1);
* crypt_stat->extent_size), sg_init_table(&dst_sg, 1);
crypt_stat->extent_size, extent_iv);
sg_set_page(&src_sg, src_page, extent_size,
extent_offset * extent_size);
sg_set_page(&dst_sg, dst_page, extent_size,
extent_offset * extent_size);
rc = crypt_scatterlist(crypt_stat, &dst_sg, &src_sg, extent_size,
extent_iv, op);
if (rc < 0) { if (rc < 0) {
printk(KERN_ERR "%s: Error attempting to encrypt page with " printk(KERN_ERR "%s: Error attempting to crypt page with "
"page->index = [%ld], extent_offset = [%ld]; " "page_index = [%ld], extent_offset = [%ld]; "
"rc = [%d]\n", __func__, page->index, extent_offset, "rc = [%d]\n", __func__, page_index, extent_offset, rc);
rc);
goto out; goto out;
} }
rc = 0; rc = 0;
@ -489,6 +490,7 @@ int ecryptfs_encrypt_page(struct page *page)
char *enc_extent_virt; char *enc_extent_virt;
struct page *enc_extent_page = NULL; struct page *enc_extent_page = NULL;
loff_t extent_offset; loff_t extent_offset;
loff_t lower_offset;
int rc = 0; int rc = 0;
ecryptfs_inode = page->mapping->host; ecryptfs_inode = page->mapping->host;
@ -502,78 +504,38 @@ int ecryptfs_encrypt_page(struct page *page)
"encrypted extent\n"); "encrypted extent\n");
goto out; goto out;
} }
enc_extent_virt = kmap(enc_extent_page);
for (extent_offset = 0; for (extent_offset = 0;
extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size); extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size);
extent_offset++) { extent_offset++) {
loff_t offset; rc = crypt_extent(crypt_stat, enc_extent_page, page,
extent_offset, ENCRYPT);
rc = ecryptfs_encrypt_extent(enc_extent_page, crypt_stat, page,
extent_offset);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error encrypting extent; " printk(KERN_ERR "%s: Error encrypting extent; "
"rc = [%d]\n", __func__, rc); "rc = [%d]\n", __func__, rc);
goto out; goto out;
} }
ecryptfs_lower_offset_for_extent( }
&offset, ((((loff_t)page->index)
* (PAGE_CACHE_SIZE lower_offset = lower_offset_for_page(crypt_stat, page);
/ crypt_stat->extent_size)) enc_extent_virt = kmap(enc_extent_page);
+ extent_offset), crypt_stat); rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt, lower_offset,
rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt, PAGE_CACHE_SIZE);
offset, crypt_stat->extent_size); kunmap(enc_extent_page);
if (rc < 0) { if (rc < 0) {
ecryptfs_printk(KERN_ERR, "Error attempting " ecryptfs_printk(KERN_ERR,
"to write lower page; rc = [%d]" "Error attempting to write lower page; rc = [%d]\n",
"\n", rc); rc);
goto out; goto out;
}
} }
rc = 0; rc = 0;
out: out:
if (enc_extent_page) { if (enc_extent_page) {
kunmap(enc_extent_page);
__free_page(enc_extent_page); __free_page(enc_extent_page);
} }
return rc; return rc;
} }
static int ecryptfs_decrypt_extent(struct page *page,
struct ecryptfs_crypt_stat *crypt_stat,
struct page *enc_extent_page,
unsigned long extent_offset)
{
loff_t extent_base;
char extent_iv[ECRYPTFS_MAX_IV_BYTES];
int rc;
extent_base = (((loff_t)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%.16llx]; rc = [%d]\n",
(unsigned long long)(extent_base + extent_offset), rc);
goto out;
}
rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
(extent_offset
* crypt_stat->extent_size),
enc_extent_page, 0,
crypt_stat->extent_size, extent_iv);
if (rc < 0) {
printk(KERN_ERR "%s: Error attempting to decrypt to page with "
"page->index = [%ld], extent_offset = [%ld]; "
"rc = [%d]\n", __func__, page->index, extent_offset,
rc);
goto out;
}
rc = 0;
out:
return rc;
}
/** /**
* ecryptfs_decrypt_page * ecryptfs_decrypt_page
* @page: Page mapped from the eCryptfs inode for the file; data read * @page: Page mapped from the eCryptfs inode for the file; data read
@ -594,43 +556,33 @@ int ecryptfs_decrypt_page(struct page *page)
{ {
struct inode *ecryptfs_inode; struct inode *ecryptfs_inode;
struct ecryptfs_crypt_stat *crypt_stat; struct ecryptfs_crypt_stat *crypt_stat;
char *enc_extent_virt; char *page_virt;
struct page *enc_extent_page = NULL;
unsigned long extent_offset; unsigned long extent_offset;
loff_t lower_offset;
int rc = 0; int rc = 0;
ecryptfs_inode = page->mapping->host; ecryptfs_inode = page->mapping->host;
crypt_stat = crypt_stat =
&(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat); &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)); BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED));
enc_extent_page = alloc_page(GFP_USER);
if (!enc_extent_page) { lower_offset = lower_offset_for_page(crypt_stat, page);
rc = -ENOMEM; page_virt = kmap(page);
ecryptfs_printk(KERN_ERR, "Error allocating memory for " rc = ecryptfs_read_lower(page_virt, lower_offset, PAGE_CACHE_SIZE,
"encrypted extent\n"); ecryptfs_inode);
kunmap(page);
if (rc < 0) {
ecryptfs_printk(KERN_ERR,
"Error attempting to read lower page; rc = [%d]\n",
rc);
goto out; goto out;
} }
enc_extent_virt = kmap(enc_extent_page);
for (extent_offset = 0; for (extent_offset = 0;
extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size); extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size);
extent_offset++) { extent_offset++) {
loff_t offset; rc = crypt_extent(crypt_stat, page, page,
extent_offset, DECRYPT);
ecryptfs_lower_offset_for_extent(
&offset, ((page->index * (PAGE_CACHE_SIZE
/ crypt_stat->extent_size))
+ extent_offset), crypt_stat);
rc = ecryptfs_read_lower(enc_extent_virt, offset,
crypt_stat->extent_size,
ecryptfs_inode);
if (rc < 0) {
ecryptfs_printk(KERN_ERR, "Error attempting "
"to read lower page; rc = [%d]"
"\n", rc);
goto out;
}
rc = ecryptfs_decrypt_extent(page, crypt_stat, enc_extent_page,
extent_offset);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error encrypting extent; " printk(KERN_ERR "%s: Error encrypting extent; "
"rc = [%d]\n", __func__, rc); "rc = [%d]\n", __func__, rc);
@ -638,142 +590,9 @@ int ecryptfs_decrypt_page(struct page *page)
} }
} }
out: out:
if (enc_extent_page) {
kunmap(enc_extent_page);
__free_page(enc_extent_page);
}
return rc; return rc;
} }
/**
* decrypt_scatterlist
* @crypt_stat: Cryptographic context
* @dest_sg: The destination scatterlist to decrypt into
* @src_sg: The source scatterlist to decrypt from
* @size: The number of bytes to decrypt
* @iv: The initialization vector to use for the decryption
*
* Returns the number of bytes decrypted; negative value on error
*/
static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
struct scatterlist *dest_sg,
struct scatterlist *src_sg, int size,
unsigned char *iv)
{
struct ablkcipher_request *req = NULL;
struct extent_crypt_result ecr;
int rc = 0;
BUG_ON(!crypt_stat || !crypt_stat->tfm
|| !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED));
if (unlikely(ecryptfs_verbosity > 0)) {
ecryptfs_printk(KERN_DEBUG, "Key size [%zd]; key:\n",
crypt_stat->key_size);
ecryptfs_dump_hex(crypt_stat->key,
crypt_stat->key_size);
}
init_completion(&ecr.completion);
mutex_lock(&crypt_stat->cs_tfm_mutex);
req = ablkcipher_request_alloc(crypt_stat->tfm, GFP_NOFS);
if (!req) {
mutex_unlock(&crypt_stat->cs_tfm_mutex);
rc = -ENOMEM;
goto out;
}
ablkcipher_request_set_callback(req,
CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
extent_crypt_complete, &ecr);
/* Consider doing this once, when the file is opened */
if (!(crypt_stat->flags & ECRYPTFS_KEY_SET)) {
rc = crypto_ablkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
crypt_stat->key_size);
if (rc) {
ecryptfs_printk(KERN_ERR,
"Error setting key; rc = [%d]\n",
rc);
mutex_unlock(&crypt_stat->cs_tfm_mutex);
rc = -EINVAL;
goto out;
}
crypt_stat->flags |= ECRYPTFS_KEY_SET;
}
mutex_unlock(&crypt_stat->cs_tfm_mutex);
ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size);
ablkcipher_request_set_crypt(req, src_sg, dest_sg, size, iv);
rc = crypto_ablkcipher_decrypt(req);
if (rc == -EINPROGRESS || rc == -EBUSY) {
struct extent_crypt_result *ecr = req->base.data;
wait_for_completion(&ecr->completion);
rc = ecr->rc;
INIT_COMPLETION(ecr->completion);
}
out:
ablkcipher_request_free(req);
return rc;
}
/**
* ecryptfs_encrypt_page_offset
* @crypt_stat: The cryptographic context
* @dst_page: The page to encrypt into
* @dst_offset: The offset in the page to encrypt into
* @src_page: The page to encrypt from
* @src_offset: The offset in the page to encrypt from
* @size: The number of bytes to encrypt
* @iv: The initialization vector to use for the encryption
*
* Returns the number of bytes encrypted
*/
static int
ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
struct page *dst_page, int dst_offset,
struct page *src_page, int src_offset, int size,
unsigned char *iv)
{
struct scatterlist src_sg, dst_sg;
sg_init_table(&src_sg, 1);
sg_init_table(&dst_sg, 1);
sg_set_page(&src_sg, src_page, size, src_offset);
sg_set_page(&dst_sg, dst_page, size, dst_offset);
return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
}
/**
* ecryptfs_decrypt_page_offset
* @crypt_stat: The cryptographic context
* @dst_page: The page to decrypt into
* @dst_offset: The offset in the page to decrypt into
* @src_page: The page to decrypt from
* @src_offset: The offset in the page to decrypt from
* @size: The number of bytes to decrypt
* @iv: The initialization vector to use for the decryption
*
* Returns the number of bytes decrypted
*/
static int
ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
struct page *dst_page, int dst_offset,
struct page *src_page, int src_offset, int size,
unsigned char *iv)
{
struct scatterlist src_sg, dst_sg;
sg_init_table(&src_sg, 1);
sg_set_page(&src_sg, src_page, size, src_offset);
sg_init_table(&dst_sg, 1);
sg_set_page(&dst_sg, dst_page, size, dst_offset);
return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
}
#define ECRYPTFS_MAX_SCATTERLIST_LEN 4 #define ECRYPTFS_MAX_SCATTERLIST_LEN 4
/** /**

View file

@ -49,7 +49,7 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb,
unsigned long nr_segs, loff_t pos) unsigned long nr_segs, loff_t pos)
{ {
ssize_t rc; ssize_t rc;
struct path lower; struct path *path;
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
rc = generic_file_aio_read(iocb, iov, nr_segs, pos); rc = generic_file_aio_read(iocb, iov, nr_segs, pos);
@ -60,9 +60,8 @@ static ssize_t ecryptfs_read_update_atime(struct kiocb *iocb,
if (-EIOCBQUEUED == rc) if (-EIOCBQUEUED == rc)
rc = wait_on_sync_kiocb(iocb); rc = wait_on_sync_kiocb(iocb);
if (rc >= 0) { if (rc >= 0) {
lower.dentry = ecryptfs_dentry_to_lower(file->f_path.dentry); path = ecryptfs_dentry_to_lower_path(file->f_path.dentry);
lower.mnt = ecryptfs_dentry_to_lower_mnt(file->f_path.dentry); touch_atime(path);
touch_atime(&lower);
} }
return rc; return rc;
} }

View file

@ -120,16 +120,15 @@ static int ecryptfs_init_lower_file(struct dentry *dentry,
struct file **lower_file) struct file **lower_file)
{ {
const struct cred *cred = current_cred(); const struct cred *cred = current_cred();
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); struct path *path = ecryptfs_dentry_to_lower_path(dentry);
struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
int rc; int rc;
rc = ecryptfs_privileged_open(lower_file, lower_dentry, lower_mnt, rc = ecryptfs_privileged_open(lower_file, path->dentry, path->mnt,
cred); cred);
if (rc) { if (rc) {
printk(KERN_ERR "Error opening lower file " printk(KERN_ERR "Error opening lower file "
"for lower_dentry [0x%p] and lower_mnt [0x%p]; " "for lower_dentry [0x%p] and lower_mnt [0x%p]; "
"rc = [%d]\n", lower_dentry, lower_mnt, rc); "rc = [%d]\n", path->dentry, path->mnt, rc);
(*lower_file) = NULL; (*lower_file) = NULL;
} }
return rc; return rc;

View file

@ -247,14 +247,13 @@ int ecryptfs_process_response(struct ecryptfs_daemon *daemon,
goto unlock; goto unlock;
} }
msg_size = (sizeof(*msg) + msg->data_len); msg_size = (sizeof(*msg) + msg->data_len);
msg_ctx->msg = kmalloc(msg_size, GFP_KERNEL); msg_ctx->msg = kmemdup(msg, msg_size, GFP_KERNEL);
if (!msg_ctx->msg) { if (!msg_ctx->msg) {
rc = -ENOMEM; rc = -ENOMEM;
printk(KERN_ERR "%s: Failed to allocate [%zd] bytes of " printk(KERN_ERR "%s: Failed to allocate [%zd] bytes of "
"GFP_KERNEL memory\n", __func__, msg_size); "GFP_KERNEL memory\n", __func__, msg_size);
goto unlock; goto unlock;
} }
memcpy(msg_ctx->msg, msg, msg_size);
msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE; msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE;
wake_up_process(msg_ctx->task); wake_up_process(msg_ctx->task);
rc = 0; rc = 0;