From: Michael Halcrow The MD5 TFM for an inode might be manipulated concurrently if two separate reads on the same file occur. The crypt_stat struct for the same inode may be manipulated concurrently if two open events on the same inode occur. This patch adds mutex locks to resolve these issues. Signed-off-by: Michael Halcrow Signed-off-by: Andrew Morton --- fs/ecryptfs/crypto.c | 2 ++ fs/ecryptfs/file.c | 6 ++++++ 2 files changed, 8 insertions(+) diff -puN fs/ecryptfs/crypto.c~ecryptfs-crypto-functions-mutex-fixes fs/ecryptfs/crypto.c --- a/fs/ecryptfs/crypto.c~ecryptfs-crypto-functions-mutex-fixes +++ a/fs/ecryptfs/crypto.c @@ -86,6 +86,7 @@ int ecryptfs_calculate_md5(char *dst, st int rc = 0; struct scatterlist sg; + mutex_lock(&crypt_stat->cs_md5_tfm_mutex); sg_init_one(&sg, (u8 *)src, len); if (!crypt_stat->md5_tfm) { crypt_stat->md5_tfm = @@ -100,6 +101,7 @@ int ecryptfs_calculate_md5(char *dst, st crypto_digest_init(crypt_stat->md5_tfm); crypto_digest_update(crypt_stat->md5_tfm, &sg, 1); crypto_digest_final(crypt_stat->md5_tfm, dst); + mutex_unlock(&crypt_stat->cs_md5_tfm_mutex); out: return rc; } diff -puN fs/ecryptfs/file.c~ecryptfs-crypto-functions-mutex-fixes fs/ecryptfs/file.c --- a/fs/ecryptfs/file.c~ecryptfs-crypto-functions-mutex-fixes +++ a/fs/ecryptfs/file.c @@ -225,12 +225,14 @@ static int ecryptfs_open(struct inode *i } lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; + mutex_lock(&crypt_stat->cs_mutex); if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) { ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n"); /* Policy code enabled in future release */ ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED); ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); } + mutex_unlock(&crypt_stat->cs_mutex); /* This mntget & dget is undone via fput when the file is released */ dget(lower_dentry); lower_flags = file->f_flags; @@ -256,10 +258,12 @@ static int ecryptfs_open(struct inode *i rc = 0; goto out; } + mutex_lock(&crypt_stat->cs_mutex); if (i_size_read(lower_inode) == 0) { ecryptfs_printk(KERN_EMERG, "Zero-length lower file; " "ecryptfs_create() had a problem?\n"); rc = -ENOENT; + mutex_unlock(&crypt_stat->cs_mutex); goto out_puts; } else if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED) @@ -276,9 +280,11 @@ static int ecryptfs_open(struct inode *i * as-is to userspace. For release 0.1, we are * going to default to -EIO. */ rc = -EIO; + mutex_unlock(&crypt_stat->cs_mutex); goto out_puts; } } + mutex_unlock(&crypt_stat->cs_mutex); ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = [0x%.16x] " "size: [0x%.16x]\n", inode, inode->i_ino, i_size_read(inode)); _