mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
eCryptfs: Prevent file create race condition
The file creation path prematurely called d_instantiate() and unlock_new_inode() before the eCryptfs inode info was fully allocated and initialized and before the eCryptfs metadata was written to the lower file. This could result in race conditions in subsequent file and inode operations leading to unexpected error conditions or a null pointer dereference while attempting to use the unallocated memory. https://launchpad.net/bugs/813146 Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Cc: stable@kernel.org
This commit is contained in:
parent
6fe4c6d466
commit
b59db43ad4
3 changed files with 46 additions and 33 deletions
|
@ -967,7 +967,7 @@ static void ecryptfs_set_default_crypt_stat_vals(
|
|||
|
||||
/**
|
||||
* ecryptfs_new_file_context
|
||||
* @ecryptfs_dentry: The eCryptfs dentry
|
||||
* @ecryptfs_inode: The eCryptfs inode
|
||||
*
|
||||
* If the crypto context for the file has not yet been established,
|
||||
* this is where we do that. Establishing a new crypto context
|
||||
|
@ -984,13 +984,13 @@ static void ecryptfs_set_default_crypt_stat_vals(
|
|||
*
|
||||
* Returns zero on success; non-zero otherwise
|
||||
*/
|
||||
int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry)
|
||||
int ecryptfs_new_file_context(struct inode *ecryptfs_inode)
|
||||
{
|
||||
struct ecryptfs_crypt_stat *crypt_stat =
|
||||
&ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
|
||||
&ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
|
||||
struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
|
||||
&ecryptfs_superblock_to_private(
|
||||
ecryptfs_dentry->d_sb)->mount_crypt_stat;
|
||||
ecryptfs_inode->i_sb)->mount_crypt_stat;
|
||||
int cipher_name_len;
|
||||
int rc = 0;
|
||||
|
||||
|
@ -1299,12 +1299,12 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max,
|
|||
}
|
||||
|
||||
static int
|
||||
ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry,
|
||||
ecryptfs_write_metadata_to_contents(struct inode *ecryptfs_inode,
|
||||
char *virt, size_t virt_len)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt,
|
||||
rc = ecryptfs_write_lower(ecryptfs_inode, virt,
|
||||
0, virt_len);
|
||||
if (rc < 0)
|
||||
printk(KERN_ERR "%s: Error attempting to write header "
|
||||
|
@ -1338,7 +1338,8 @@ static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask,
|
|||
|
||||
/**
|
||||
* ecryptfs_write_metadata
|
||||
* @ecryptfs_dentry: The eCryptfs dentry
|
||||
* @ecryptfs_dentry: The eCryptfs dentry, which should be negative
|
||||
* @ecryptfs_inode: The newly created eCryptfs inode
|
||||
*
|
||||
* Write the file headers out. This will likely involve a userspace
|
||||
* callout, in which the session key is encrypted with one or more
|
||||
|
@ -1348,10 +1349,11 @@ static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask,
|
|||
*
|
||||
* Returns zero on success; non-zero on error
|
||||
*/
|
||||
int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
|
||||
int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
|
||||
struct inode *ecryptfs_inode)
|
||||
{
|
||||
struct ecryptfs_crypt_stat *crypt_stat =
|
||||
&ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
|
||||
&ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
|
||||
unsigned int order;
|
||||
char *virt;
|
||||
size_t virt_len;
|
||||
|
@ -1391,7 +1393,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
|
|||
rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, virt,
|
||||
size);
|
||||
else
|
||||
rc = ecryptfs_write_metadata_to_contents(ecryptfs_dentry, virt,
|
||||
rc = ecryptfs_write_metadata_to_contents(ecryptfs_inode, virt,
|
||||
virt_len);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: Error writing metadata out to lower file; "
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue