From 23702d4c026f2c3544c9b32bc97208d5b7a31a6f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 27 Feb 2012 16:18:22 -0800 Subject: 2.6.32-stable patches added patches: cdrom-use-copy_to_user-without-the-underscores.patch ecryptfs-clear-i_nlink-in-rmdir.patch ecryptfs-remove-extra-d_delete-in-ecryptfs_rmdir.patch ecryptfs-use-notify_change-for-truncating-lower-inodes.patch --- ...-use-copy_to_user-without-the-underscores.patch | 54 +++++ queue-2.6.32/ecryptfs-clear-i_nlink-in-rmdir.patch | 35 +++ ...s-remove-extra-d_delete-in-ecryptfs_rmdir.patch | 34 +++ ...notify_change-for-truncating-lower-inodes.patch | 235 +++++++++++++++++++++ queue-2.6.32/series | 4 + 5 files changed, 362 insertions(+) create mode 100644 queue-2.6.32/cdrom-use-copy_to_user-without-the-underscores.patch create mode 100644 queue-2.6.32/ecryptfs-clear-i_nlink-in-rmdir.patch create mode 100644 queue-2.6.32/ecryptfs-remove-extra-d_delete-in-ecryptfs_rmdir.patch create mode 100644 queue-2.6.32/ecryptfs-use-notify_change-for-truncating-lower-inodes.patch diff --git a/queue-2.6.32/cdrom-use-copy_to_user-without-the-underscores.patch b/queue-2.6.32/cdrom-use-copy_to_user-without-the-underscores.patch new file mode 100644 index 0000000..eba6a33 --- /dev/null +++ b/queue-2.6.32/cdrom-use-copy_to_user-without-the-underscores.patch @@ -0,0 +1,54 @@ +From 822bfa51ce44f2c63c300fdb76dc99c4d5a5ca9f Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 6 Feb 2012 10:20:45 +0100 +Subject: cdrom: use copy_to_user() without the underscores + +From: Dan Carpenter + +commit 822bfa51ce44f2c63c300fdb76dc99c4d5a5ca9f upstream. + +"nframes" comes from the user and "nframes * CD_FRAMESIZE_RAW" can wrap +on 32 bit systems. That would have been ok if we used the same wrapped +value for the copy, but we use a shifted value. We should just use the +checked version of copy_to_user() because it's not going to make a +difference to the speed. + +Signed-off-by: Dan Carpenter +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cdrom/cdrom.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/drivers/cdrom/cdrom.c ++++ b/drivers/cdrom/cdrom.c +@@ -2057,11 +2057,6 @@ static int cdrom_read_cdda_old(struct cd + if (!nr) + return -ENOMEM; + +- if (!access_ok(VERIFY_WRITE, ubuf, nframes * CD_FRAMESIZE_RAW)) { +- ret = -EFAULT; +- goto out; +- } +- + cgc.data_direction = CGC_DATA_READ; + while (nframes > 0) { + if (nr > nframes) +@@ -2070,7 +2065,7 @@ static int cdrom_read_cdda_old(struct cd + ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW); + if (ret) + break; +- if (__copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) { ++ if (copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) { + ret = -EFAULT; + break; + } +@@ -2078,7 +2073,6 @@ static int cdrom_read_cdda_old(struct cd + nframes -= nr; + lba += nr; + } +-out: + kfree(cgc.buffer); + return ret; + } diff --git a/queue-2.6.32/ecryptfs-clear-i_nlink-in-rmdir.patch b/queue-2.6.32/ecryptfs-clear-i_nlink-in-rmdir.patch new file mode 100644 index 0000000..4e73fc6 --- /dev/null +++ b/queue-2.6.32/ecryptfs-clear-i_nlink-in-rmdir.patch @@ -0,0 +1,35 @@ +From 07850552b92b3637fa56767b5e460b4238014447 Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Fri, 29 Apr 2011 16:26:27 -0500 +Subject: eCryptfs: Clear i_nlink in rmdir + +From: Tyler Hicks + +commit 07850552b92b3637fa56767b5e460b4238014447 upstream. + +eCryptfs wasn't clearing the eCryptfs inode's i_nlink after a successful +vfs_rmdir() on the lower directory. This resulted in the inode evict and +destroy paths to be missed. + +https://bugs.launchpad.net/ecryptfs/+bug/723518 + +Signed-off-by: Tyler Hicks +Signed-off-by: Colin King +Signed-off-by: Tim Gardner +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/inode.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -575,6 +575,8 @@ static int ecryptfs_rmdir(struct inode * + dget(lower_dentry); + rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); + dput(lower_dentry); ++ if (!rc && dentry->d_inode) ++ clear_nlink(dentry->d_inode); + fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); + dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; + unlock_dir(lower_dir_dentry); diff --git a/queue-2.6.32/ecryptfs-remove-extra-d_delete-in-ecryptfs_rmdir.patch b/queue-2.6.32/ecryptfs-remove-extra-d_delete-in-ecryptfs_rmdir.patch new file mode 100644 index 0000000..cfc4870 --- /dev/null +++ b/queue-2.6.32/ecryptfs-remove-extra-d_delete-in-ecryptfs_rmdir.patch @@ -0,0 +1,34 @@ +From 35ffa948b2f7bdf79e488cd496232935d095087a Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Tue, 12 Apr 2011 11:21:36 -0500 +Subject: eCryptfs: Remove extra d_delete in ecryptfs_rmdir + +From: Tyler Hicks + +commit 35ffa948b2f7bdf79e488cd496232935d095087a upstream. + +vfs_rmdir() already calls d_delete() on the lower dentry. That was being +duplicated in ecryptfs_rmdir() and caused a NULL pointer dereference +when NFSv3 was the lower filesystem. + +BugLink: http://bugs.launchpad.net/bugs/723518 +Signed-off-by: Tyler Hicks +Signed-off-by: Colin King +Signed-off-by: Tim Gardner +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/inode.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -575,8 +575,6 @@ static int ecryptfs_rmdir(struct inode * + dget(lower_dentry); + rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); + dput(lower_dentry); +- if (!rc) +- d_delete(lower_dentry); + fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); + dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; + unlock_dir(lower_dir_dentry); diff --git a/queue-2.6.32/ecryptfs-use-notify_change-for-truncating-lower-inodes.patch b/queue-2.6.32/ecryptfs-use-notify_change-for-truncating-lower-inodes.patch new file mode 100644 index 0000000..a40074d --- /dev/null +++ b/queue-2.6.32/ecryptfs-use-notify_change-for-truncating-lower-inodes.patch @@ -0,0 +1,235 @@ +From 5f3ef64f4da1c587cdcfaaac72311225b7df094c Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Wed, 14 Oct 2009 16:18:27 -0500 +Subject: eCryptfs: Use notify_change for truncating lower inodes + +From: Tyler Hicks + +commit 5f3ef64f4da1c587cdcfaaac72311225b7df094c upstream. + +When truncating inodes in the lower filesystem, eCryptfs directly +invoked vmtruncate(). As Christoph Hellwig pointed out, vmtruncate() is +a filesystem helper function, but filesystems may need to do more than +just a call to vmtruncate(). + +This patch moves the lower inode truncation out of ecryptfs_truncate() +and renames the function to truncate_upper(). truncate_upper() updates +an iattr for the lower inode to indicate if the lower inode needs to be +truncated upon return. ecryptfs_setattr() then calls notify_change(), +using the updated iattr for the lower inode, to complete the truncation. + +For eCryptfs functions needing to truncate, ecryptfs_truncate() is +reintroduced as a simple way to truncate the upper inode to a specified +size and then truncate the lower inode accordingly. + +https://bugs.launchpad.net/bugs/451368 + +Reported-by: Christoph Hellwig +Acked-by: Dustin Kirkland +Cc: ecryptfs-devel@lists.launchpad.net +Cc: linux-fsdevel@vger.kernel.org +Signed-off-by: Tyler Hicks +Signed-off-by: Colin Ian King +Signed-off-by: Tim Gardner +Signed-off-by: Greg Kroah-Hartman + + +--- + fs/ecryptfs/inode.c | 99 +++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 67 insertions(+), 32 deletions(-) + +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -758,18 +758,23 @@ upper_size_to_lower_size(struct ecryptfs + } + + /** +- * ecryptfs_truncate ++ * truncate_upper + * @dentry: The ecryptfs layer dentry +- * @new_length: The length to expand the file to ++ * @ia: Address of the ecryptfs inode's attributes ++ * @lower_ia: Address of the lower inode's attributes + * + * Function to handle truncations modifying the size of the file. Note + * that the file sizes are interpolated. When expanding, we are simply +- * writing strings of 0's out. When truncating, we need to modify the +- * underlying file size according to the page index interpolations. ++ * writing strings of 0's out. When truncating, we truncate the upper ++ * inode and update the lower_ia according to the page index ++ * interpolations. If ATTR_SIZE is set in lower_ia->ia_valid upon return, ++ * the caller must use lower_ia in a call to notify_change() to perform ++ * the truncation of the lower inode. + * + * Returns zero on success; non-zero otherwise + */ +-int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) ++static int truncate_upper(struct dentry *dentry, struct iattr *ia, ++ struct iattr *lower_ia) + { + int rc = 0; + struct inode *inode = dentry->d_inode; +@@ -780,8 +785,10 @@ int ecryptfs_truncate(struct dentry *den + loff_t lower_size_before_truncate; + loff_t lower_size_after_truncate; + +- if (unlikely((new_length == i_size))) ++ if (unlikely((ia->ia_size == i_size))) { ++ lower_ia->ia_valid &= ~ATTR_SIZE; + goto out; ++ } + crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; + /* Set up a fake ecryptfs file, this is used to interface with + * the file in the underlying filesystem so that the +@@ -801,28 +808,30 @@ int ecryptfs_truncate(struct dentry *den + &fake_ecryptfs_file, + ecryptfs_inode_to_private(dentry->d_inode)->lower_file); + /* Switch on growing or shrinking file */ +- if (new_length > i_size) { ++ if (ia->ia_size > i_size) { + char zero[] = { 0x00 }; + ++ lower_ia->ia_valid &= ~ATTR_SIZE; + /* Write a single 0 at the last position of the file; + * this triggers code that will fill in 0's throughout + * the intermediate portion of the previous end of the + * file and the new and of the file */ + rc = ecryptfs_write(&fake_ecryptfs_file, zero, +- (new_length - 1), 1); +- } else { /* new_length < i_size_read(inode) */ +- /* We're chopping off all the pages down do the page +- * in which new_length is located. Fill in the end of +- * that page from (new_length & ~PAGE_CACHE_MASK) to ++ (ia->ia_size - 1), 1); ++ } else { /* ia->ia_size < i_size_read(inode) */ ++ /* We're chopping off all the pages down to the page ++ * in which ia->ia_size is located. Fill in the end of ++ * that page from (ia->ia_size & ~PAGE_CACHE_MASK) to + * PAGE_CACHE_SIZE with zeros. */ + size_t num_zeros = (PAGE_CACHE_SIZE +- - (new_length & ~PAGE_CACHE_MASK)); ++ - (ia->ia_size & ~PAGE_CACHE_MASK)); + + if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { +- rc = vmtruncate(inode, new_length); ++ rc = vmtruncate(inode, ia->ia_size); + if (rc) + goto out_free; +- rc = vmtruncate(lower_dentry->d_inode, new_length); ++ lower_ia->ia_size = ia->ia_size; ++ lower_ia->ia_valid |= ATTR_SIZE; + goto out_free; + } + if (num_zeros) { +@@ -834,7 +843,7 @@ int ecryptfs_truncate(struct dentry *den + goto out_free; + } + rc = ecryptfs_write(&fake_ecryptfs_file, zeros_virt, +- new_length, num_zeros); ++ ia->ia_size, num_zeros); + kfree(zeros_virt); + if (rc) { + printk(KERN_ERR "Error attempting to zero out " +@@ -843,7 +852,7 @@ int ecryptfs_truncate(struct dentry *den + goto out_free; + } + } +- vmtruncate(inode, new_length); ++ vmtruncate(inode, ia->ia_size); + rc = ecryptfs_write_inode_size_to_metadata(inode); + if (rc) { + printk(KERN_ERR "Problem with " +@@ -856,10 +865,12 @@ int ecryptfs_truncate(struct dentry *den + lower_size_before_truncate = + upper_size_to_lower_size(crypt_stat, i_size); + lower_size_after_truncate = +- upper_size_to_lower_size(crypt_stat, new_length); +- if (lower_size_after_truncate < lower_size_before_truncate) +- vmtruncate(lower_dentry->d_inode, +- lower_size_after_truncate); ++ upper_size_to_lower_size(crypt_stat, ia->ia_size); ++ if (lower_size_after_truncate < lower_size_before_truncate) { ++ lower_ia->ia_size = lower_size_after_truncate; ++ lower_ia->ia_valid |= ATTR_SIZE; ++ } else ++ lower_ia->ia_valid &= ~ATTR_SIZE; + } + out_free: + if (ecryptfs_file_to_private(&fake_ecryptfs_file)) +@@ -869,6 +880,33 @@ out: + return rc; + } + ++/** ++ * ecryptfs_truncate ++ * @dentry: The ecryptfs layer dentry ++ * @new_length: The length to expand the file to ++ * ++ * Simple function that handles the truncation of an eCryptfs inode and ++ * its corresponding lower inode. ++ * ++ * Returns zero on success; non-zero otherwise ++ */ ++int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) ++{ ++ struct iattr ia = { .ia_valid = ATTR_SIZE, .ia_size = new_length }; ++ struct iattr lower_ia = { .ia_valid = 0 }; ++ int rc; ++ ++ rc = truncate_upper(dentry, &ia, &lower_ia); ++ if (!rc && lower_ia.ia_valid & ATTR_SIZE) { ++ struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); ++ ++ mutex_lock(&lower_dentry->d_inode->i_mutex); ++ rc = notify_change(lower_dentry, &lower_ia); ++ mutex_unlock(&lower_dentry->d_inode->i_mutex); ++ } ++ return rc; ++} ++ + static int + ecryptfs_permission(struct inode *inode, int mask) + { +@@ -891,6 +929,7 @@ static int ecryptfs_setattr(struct dentr + { + int rc = 0; + struct dentry *lower_dentry; ++ struct iattr lower_ia; + struct inode *inode; + struct inode *lower_inode; + struct ecryptfs_crypt_stat *crypt_stat; +@@ -929,15 +968,11 @@ static int ecryptfs_setattr(struct dentr + } + } + mutex_unlock(&crypt_stat->cs_mutex); ++ memcpy(&lower_ia, ia, sizeof(lower_ia)); ++ if (ia->ia_valid & ATTR_FILE) ++ lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); + if (ia->ia_valid & ATTR_SIZE) { +- ecryptfs_printk(KERN_DEBUG, +- "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n", +- ia->ia_valid, ATTR_SIZE); +- rc = ecryptfs_truncate(dentry, ia->ia_size); +- /* ecryptfs_truncate handles resizing of the lower file */ +- ia->ia_valid &= ~ATTR_SIZE; +- ecryptfs_printk(KERN_DEBUG, "ia->ia_valid = [%x]\n", +- ia->ia_valid); ++ rc = truncate_upper(dentry, ia, &lower_ia); + if (rc < 0) + goto out; + } +@@ -946,11 +981,11 @@ static int ecryptfs_setattr(struct dentr + * mode change is for clearing setuid/setgid bits. Allow lower fs + * to interpret this in its own way. + */ +- if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) +- ia->ia_valid &= ~ATTR_MODE; ++ if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) ++ lower_ia.ia_valid &= ~ATTR_MODE; + + mutex_lock(&lower_dentry->d_inode->i_mutex); +- rc = notify_change(lower_dentry, ia); ++ rc = notify_change(lower_dentry, &lower_ia); + mutex_unlock(&lower_dentry->d_inode->i_mutex); + out: + fsstack_copy_attr_all(inode, lower_inode, NULL); diff --git a/queue-2.6.32/series b/queue-2.6.32/series index 0d62152..6c7fca1 100644 --- a/queue-2.6.32/series +++ b/queue-2.6.32/series @@ -21,3 +21,7 @@ usb-added-kamstrup-vid-pids-to-cp210x-serial-driver.patch usb-fix-handoff-when-bios-disables-host-pci-device.patch xhci-fix-encoding-for-hs-bulk-control-nak-rate.patch hdpvr-fix-race-conditon-during-start-of-streaming.patch +ecryptfs-use-notify_change-for-truncating-lower-inodes.patch +ecryptfs-remove-extra-d_delete-in-ecryptfs_rmdir.patch +ecryptfs-clear-i_nlink-in-rmdir.patch +cdrom-use-copy_to_user-without-the-underscores.patch -- cgit 1.2.3-korg