FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Ubuntu > Ubuntu Kernel Team

 
 
LinkBack Thread Tools
 
Old 07-20-2011, 08:58 AM
Stefan Bader
 
Default Maverick SRU: eCryptfs: Handle failed metadata read in lookup

On 20.07.2011 01:57, Tim Gardner wrote:
> The following changes since commit 5b3cf6d032af94a1b06761eaae41430c718afa8b:
> Dan Rosenberg (1):
> dccp: handle invalid feature options length, CVE-2011-1770
>
> are available in the git repository at:
>
> git://kernel.ubuntu.com/rtg/ubuntu-maverick.git ecryptfs-lp509180
>
> Tim Gardner (1):
> eCryptfs: Handle failed metadata read in lookup
>
> fs/ecryptfs/crypto.c | 21 +++++++++++++++++++++
> fs/ecryptfs/ecryptfs_kernel.h | 2 ++
> fs/ecryptfs/file.c | 3 ++-
> fs/ecryptfs/inode.c | 18 +++---------------
> 4 files changed, 28 insertions(+), 16 deletions(-)
>
> From cf37175cfcacf9443e50aa050deb450b6a336249 Mon Sep 17 00:00:00 2001
> From: Tim Gardner <tim.gardner@canonical.com>
> Date: Fri, 15 Jul 2011 12:02:40 -0600
> Subject: [PATCH] eCryptfs: Handle failed metadata read in lookup
>
> When failing to read the lower file's crypto metadata during a lookup,
> eCryptfs must continue on without throwing an error. For example, there
> may be a plaintext file in the lower mount point that the user wants to
> delete through the eCryptfs mount.
>
> If an error is encountered while reading the metadata in lookup(), the
> eCryptfs inode's size could be incorrect. We must be sure to reread the
> plaintext inode size from the metadata when performing an open() or
> setattr(). The metadata is already being read in those paths, so this
> adds minimal performance overhead.
>
> This patch introduces a flag which will track whether or not the
> plaintext inode size has been read so that an incorrect i_size can be
> fixed in the open() or setattr() paths.
>
> https://bugs.launchpad.net/bugs/509180
>
> Cc: <stable@kernel.org>
> Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
>
> (backported from 3aeb86ea4cd15f728147a3bd5469a205ada8c767)
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
> fs/ecryptfs/crypto.c | 21 +++++++++++++++++++++
> fs/ecryptfs/ecryptfs_kernel.h | 2 ++
> fs/ecryptfs/file.c | 3 ++-
> fs/ecryptfs/inode.c | 18 +++---------------
> 4 files changed, 28 insertions(+), 16 deletions(-)
>
> diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
> index 1cc0876..0f13aaa 100644
> --- a/fs/ecryptfs/crypto.c
> +++ b/fs/ecryptfs/crypto.c
> @@ -1454,6 +1454,25 @@ static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
> crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
> }
>
> +void ecryptfs_i_size_init(const char *page_virt, struct inode *inode)
> +{
> + struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
> + struct ecryptfs_crypt_stat *crypt_stat;
> + u64 file_size;
> +
> + crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
> + mount_crypt_stat =
> + &ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat;
> + if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
> + file_size = i_size_read(ecryptfs_inode_to_lower(inode));
> + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
> + file_size += crypt_stat->metadata_size;
> + } else
> + file_size = get_unaligned_be64(page_virt);
> + i_size_write(inode, (loff_t)file_size);
> + crypt_stat->flags |= ECRYPTFS_I_SIZE_INITIALIZED;
> +}
> +
> /**
> * ecryptfs_read_headers_virt
> * @page_virt: The virtual address into which to read the headers
> @@ -1484,6 +1503,8 @@ static int ecryptfs_read_headers_virt(char *page_virt,
> rc = -EINVAL;
> goto out;
> }
> + if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED))
> + ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode);
> offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
> rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset),
> &bytes_read);
> diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
> index 0032a9f..ed9958a 100644
> --- a/fs/ecryptfs/ecryptfs_kernel.h
> +++ b/fs/ecryptfs/ecryptfs_kernel.h
> @@ -271,6 +271,7 @@ struct ecryptfs_crypt_stat {
> #define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00001000
> #define ECRYPTFS_ENCFN_USE_FEK 0x00002000
> #define ECRYPTFS_UNLINK_SIGS 0x00004000
> +#define ECRYPTFS_I_SIZE_INITIALIZED 0x00008000
> u32 flags;
> unsigned int file_version;
> size_t iv_bytes;
> @@ -629,6 +630,7 @@ struct ecryptfs_open_req {
> int ecryptfs_interpose(struct dentry *hidden_dentry,
> struct dentry *this_dentry, struct super_block *sb,
> u32 flags);
> +void ecryptfs_i_size_init(const char *page_virt, struct inode *inode);
> int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
> struct dentry *lower_dentry,
> struct inode *ecryptfs_dir_inode,
> diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
> index 622c951..58c518b 100644
> --- a/fs/ecryptfs/file.c
> +++ b/fs/ecryptfs/file.c
> @@ -238,7 +238,8 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
> goto out_free;
> }
> rc = 0;
> - crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
> + crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
> + | ECRYPTFS_ENCRYPTED);
> mutex_unlock(&crypt_stat->cs_mutex);
> goto out;
> }
> diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
> index 1681c62..57edfd7 100644
> --- a/fs/ecryptfs/inode.c
> +++ b/fs/ecryptfs/inode.c
> @@ -249,10 +249,8 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
> struct dentry *lower_dir_dentry;
> struct vfsmount *lower_mnt;
> struct inode *lower_inode;
> - struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
> struct ecryptfs_crypt_stat *crypt_stat;
> char *page_virt = NULL;
> - u64 file_size;
> int rc = 0;
>
> lower_dir_dentry = lower_dentry->d_parent;
> @@ -329,18 +327,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
> }
> crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
> }
> - mount_crypt_stat = &ecryptfs_superblock_to_private(
> - ecryptfs_dentry->d_sb)->mount_crypt_stat;
> - if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
> - if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
> - file_size = (crypt_stat->metadata_size
> - + i_size_read(lower_dentry->d_inode));
> - else
> - file_size = i_size_read(lower_dentry->d_inode);
> - } else {
> - file_size = get_unaligned_be64(page_virt);
> - }
> - i_size_write(ecryptfs_dentry->d_inode, (loff_t)file_size);
> + ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode);
> out_free_kmem:
> kmem_cache_free(ecryptfs_header_cache_2, page_virt);
> goto out;
> @@ -944,7 +931,8 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
> goto out;
> }
> rc = 0;
> - crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
> + crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
> + | ECRYPTFS_ENCRYPTED);
> }
> }
> mutex_unlock(&crypt_stat->cs_mutex);

Acked-by: Stefan Bader <stefan.bader@canonical.com>

[probably with the same suggestion as 2.6.32 but 2.6.35.y seems less well kept
up to date]

--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team
 
Old 07-20-2011, 05:29 PM
Leann Ogasawara
 
Default Maverick SRU: eCryptfs: Handle failed metadata read in lookup

On Tue, 2011-07-19 at 17:57 -0600, Tim Gardner wrote:
> The following changes since commit 5b3cf6d032af94a1b06761eaae41430c718afa8b:
> Dan Rosenberg (1):
> dccp: handle invalid feature options length, CVE-2011-1770
>
> are available in the git repository at:
>
> git://kernel.ubuntu.com/rtg/ubuntu-maverick.git ecryptfs-lp509180
>
> Tim Gardner (1):
> eCryptfs: Handle failed metadata read in lookup
>
> fs/ecryptfs/crypto.c | 21 +++++++++++++++++++++
> fs/ecryptfs/ecryptfs_kernel.h | 2 ++
> fs/ecryptfs/file.c | 3 ++-
> fs/ecryptfs/inode.c | 18 +++---------------
> 4 files changed, 28 insertions(+), 16 deletions(-)
>
> From cf37175cfcacf9443e50aa050deb450b6a336249 Mon Sep 17 00:00:00 2001
> From: Tim Gardner <tim.gardner@canonical.com>
> Date: Fri, 15 Jul 2011 12:02:40 -0600
> Subject: [PATCH] eCryptfs: Handle failed metadata read in lookup
>
> When failing to read the lower file's crypto metadata during a lookup,
> eCryptfs must continue on without throwing an error. For example, there
> may be a plaintext file in the lower mount point that the user wants to
> delete through the eCryptfs mount.
>
> If an error is encountered while reading the metadata in lookup(), the
> eCryptfs inode's size could be incorrect. We must be sure to reread the
> plaintext inode size from the metadata when performing an open() or
> setattr(). The metadata is already being read in those paths, so this
> adds minimal performance overhead.
>
> This patch introduces a flag which will track whether or not the
> plaintext inode size has been read so that an incorrect i_size can be
> fixed in the open() or setattr() paths.
>
> https://bugs.launchpad.net/bugs/509180
>
> Cc: <stable@kernel.org>
> Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
>
> (backported from 3aeb86ea4cd15f728147a3bd5469a205ada8c767)
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>

Acked-by: Leann Ogasawara <leann.ogasawara@canonical.com>

> ---
> fs/ecryptfs/crypto.c | 21 +++++++++++++++++++++
> fs/ecryptfs/ecryptfs_kernel.h | 2 ++
> fs/ecryptfs/file.c | 3 ++-
> fs/ecryptfs/inode.c | 18 +++---------------
> 4 files changed, 28 insertions(+), 16 deletions(-)
>
> diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
> index 1cc0876..0f13aaa 100644
> --- a/fs/ecryptfs/crypto.c
> +++ b/fs/ecryptfs/crypto.c
> @@ -1454,6 +1454,25 @@ static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
> crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
> }
>
> +void ecryptfs_i_size_init(const char *page_virt, struct inode *inode)
> +{
> + struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
> + struct ecryptfs_crypt_stat *crypt_stat;
> + u64 file_size;
> +
> + crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
> + mount_crypt_stat =
> + &ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat;
> + if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
> + file_size = i_size_read(ecryptfs_inode_to_lower(inode));
> + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
> + file_size += crypt_stat->metadata_size;
> + } else
> + file_size = get_unaligned_be64(page_virt);
> + i_size_write(inode, (loff_t)file_size);
> + crypt_stat->flags |= ECRYPTFS_I_SIZE_INITIALIZED;
> +}
> +
> /**
> * ecryptfs_read_headers_virt
> * @page_virt: The virtual address into which to read the headers
> @@ -1484,6 +1503,8 @@ static int ecryptfs_read_headers_virt(char *page_virt,
> rc = -EINVAL;
> goto out;
> }
> + if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED))
> + ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode);
> offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
> rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset),
> &bytes_read);
> diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
> index 0032a9f..ed9958a 100644
> --- a/fs/ecryptfs/ecryptfs_kernel.h
> +++ b/fs/ecryptfs/ecryptfs_kernel.h
> @@ -271,6 +271,7 @@ struct ecryptfs_crypt_stat {
> #define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00001000
> #define ECRYPTFS_ENCFN_USE_FEK 0x00002000
> #define ECRYPTFS_UNLINK_SIGS 0x00004000
> +#define ECRYPTFS_I_SIZE_INITIALIZED 0x00008000
> u32 flags;
> unsigned int file_version;
> size_t iv_bytes;
> @@ -629,6 +630,7 @@ struct ecryptfs_open_req {
> int ecryptfs_interpose(struct dentry *hidden_dentry,
> struct dentry *this_dentry, struct super_block *sb,
> u32 flags);
> +void ecryptfs_i_size_init(const char *page_virt, struct inode *inode);
> int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
> struct dentry *lower_dentry,
> struct inode *ecryptfs_dir_inode,
> diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
> index 622c951..58c518b 100644
> --- a/fs/ecryptfs/file.c
> +++ b/fs/ecryptfs/file.c
> @@ -238,7 +238,8 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
> goto out_free;
> }
> rc = 0;
> - crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
> + crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
> + | ECRYPTFS_ENCRYPTED);
> mutex_unlock(&crypt_stat->cs_mutex);
> goto out;
> }
> diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
> index 1681c62..57edfd7 100644
> --- a/fs/ecryptfs/inode.c
> +++ b/fs/ecryptfs/inode.c
> @@ -249,10 +249,8 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
> struct dentry *lower_dir_dentry;
> struct vfsmount *lower_mnt;
> struct inode *lower_inode;
> - struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
> struct ecryptfs_crypt_stat *crypt_stat;
> char *page_virt = NULL;
> - u64 file_size;
> int rc = 0;
>
> lower_dir_dentry = lower_dentry->d_parent;
> @@ -329,18 +327,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
> }
> crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
> }
> - mount_crypt_stat = &ecryptfs_superblock_to_private(
> - ecryptfs_dentry->d_sb)->mount_crypt_stat;
> - if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
> - if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
> - file_size = (crypt_stat->metadata_size
> - + i_size_read(lower_dentry->d_inode));
> - else
> - file_size = i_size_read(lower_dentry->d_inode);
> - } else {
> - file_size = get_unaligned_be64(page_virt);
> - }
> - i_size_write(ecryptfs_dentry->d_inode, (loff_t)file_size);
> + ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode);
> out_free_kmem:
> kmem_cache_free(ecryptfs_header_cache_2, page_virt);
> goto out;
> @@ -944,7 +931,8 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
> goto out;
> }
> rc = 0;
> - crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
> + crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
> + | ECRYPTFS_ENCRYPTED);
> }
> }
> mutex_unlock(&crypt_stat->cs_mutex);
> --
> 1.7.0.4
>
>



--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team
 

Thread Tools




All times are GMT. The time now is 01:15 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org