summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-27 16:18:22 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-27 16:18:22 -0800
commit23702d4c026f2c3544c9b32bc97208d5b7a31a6f (patch)
tree29f69dc40d655db7a53f6a41acbc894a20dd5446
parent4fc06ddbef136c998293df7c7216f8fd2f821a6f (diff)
downloadlongterm-queue-2.6.32-23702d4c026f2c3544c9b32bc97208d5b7a31a6f.tar.gz
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
-rw-r--r--queue-2.6.32/cdrom-use-copy_to_user-without-the-underscores.patch54
-rw-r--r--queue-2.6.32/ecryptfs-clear-i_nlink-in-rmdir.patch35
-rw-r--r--queue-2.6.32/ecryptfs-remove-extra-d_delete-in-ecryptfs_rmdir.patch34
-rw-r--r--queue-2.6.32/ecryptfs-use-notify_change-for-truncating-lower-inodes.patch235
-rw-r--r--queue-2.6.32/series4
5 files changed, 362 insertions, 0 deletions
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 <dan.carpenter@oracle.com>
+Date: Mon, 6 Feb 2012 10:20:45 +0100
+Subject: cdrom: use copy_to_user() without the underscores
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+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 <dan.carpenter@oracle.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <tyhicks@linux.vnet.ibm.com>
+Date: Fri, 29 Apr 2011 16:26:27 -0500
+Subject: eCryptfs: Clear i_nlink in rmdir
+
+From: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
+
+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 <tyhicks@linux.vnet.ibm.com>
+Signed-off-by: Colin King <colin.king@canonical.com>
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <tyhicks@linux.vnet.ibm.com>
+Date: Tue, 12 Apr 2011 11:21:36 -0500
+Subject: eCryptfs: Remove extra d_delete in ecryptfs_rmdir
+
+From: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
+
+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 <tyhicks@linux.vnet.ibm.com>
+Signed-off-by: Colin King <colin.king@canonical.com>
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <tyhicks@linux.vnet.ibm.com>
+Date: Wed, 14 Oct 2009 16:18:27 -0500
+Subject: eCryptfs: Use notify_change for truncating lower inodes
+
+From: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
+
+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 <hch@lst.de>
+Acked-by: Dustin Kirkland <kirkland@canonical.com>
+Cc: ecryptfs-devel@lists.launchpad.net
+Cc: linux-fsdevel@vger.kernel.org
+Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ 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