]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0-stable patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 26 Jan 2012 18:19:57 +0000 (10:19 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 26 Jan 2012 18:19:57 +0000 (10:19 -0800)
added patches:
alsa-hda-fix-silent-outputs-from-docking-station-jacks-of-dell-laptops.patch
drm-fix-authentication-kernel-crash.patch
drm-radeon-kms-add-an-msi-quirk-for-dell-rs690.patch
ecryptfs-check-inode-changes-in-setattr.patch
ecryptfs-fix-oops-when-printing-debug-info-in-extent-crypto-functions.patch
ecryptfs-improve-metadata-read-failure-logging.patch
ecryptfs-make-truncate-path-killable.patch
ecryptfs-sanitize-write-counts-of-dev-ecryptfs.patch
xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch

queue-3.0/alsa-hda-fix-silent-outputs-from-docking-station-jacks-of-dell-laptops.patch [new file with mode: 0644]
queue-3.0/drm-fix-authentication-kernel-crash.patch [new file with mode: 0644]
queue-3.0/drm-radeon-kms-add-an-msi-quirk-for-dell-rs690.patch [new file with mode: 0644]
queue-3.0/ecryptfs-check-inode-changes-in-setattr.patch [new file with mode: 0644]
queue-3.0/ecryptfs-fix-oops-when-printing-debug-info-in-extent-crypto-functions.patch [new file with mode: 0644]
queue-3.0/ecryptfs-improve-metadata-read-failure-logging.patch [new file with mode: 0644]
queue-3.0/ecryptfs-make-truncate-path-killable.patch [new file with mode: 0644]
queue-3.0/ecryptfs-sanitize-write-counts-of-dev-ecryptfs.patch [new file with mode: 0644]
queue-3.0/series [new file with mode: 0644]
queue-3.0/xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch [new file with mode: 0644]

diff --git a/queue-3.0/alsa-hda-fix-silent-outputs-from-docking-station-jacks-of-dell-laptops.patch b/queue-3.0/alsa-hda-fix-silent-outputs-from-docking-station-jacks-of-dell-laptops.patch
new file mode 100644 (file)
index 0000000..d9e2984
--- /dev/null
@@ -0,0 +1,61 @@
+From b4ead019afc201f71c39cd0dfcaafed4a97b3dd2 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 23 Jan 2012 18:23:36 +0100
+Subject: ALSA: hda - Fix silent outputs from docking-station jacks of Dell laptops
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit b4ead019afc201f71c39cd0dfcaafed4a97b3dd2 upstream.
+
+The recent change of the power-widget handling for IDT codecs caused
+the silent output from the docking-station line-out jack.  This was
+partially fixed by the commit f2cbba7602383cd9cdd21f0a5d0b8bd1aad47b33
+"ALSA: hda - Fix the lost power-setup of seconary pins after PM resume".
+But the line-out on the docking-station is still silent when booted
+with the jack plugged even by this fix.
+
+The remainig bug is that the power-widget is set off in stac92xx_init()
+because the pins in cfg->line_out_pins[] aren't checked there properly
+but only hp_pins[] are checked in is_nid_hp_pin().
+
+This patch fixes the problem by checking both HP and line-out pins
+and leaving the power-map correctly.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=42637
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/hda/patch_sigmatel.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -4162,13 +4162,15 @@ static int enable_pin_detect(struct hda_
+       return 1;
+ }
+-static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
++static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
+ {
+       int i;
+       for (i = 0; i < cfg->hp_outs; i++)
+               if (cfg->hp_pins[i] == nid)
+                       return 1; /* nid is a HP-Out */
+-
++      for (i = 0; i < cfg->line_outs; i++)
++              if (cfg->line_out_pins[i] == nid)
++                      return 1; /* nid is a line-Out */
+       return 0; /* nid is not a HP-Out */
+ };
+@@ -4354,7 +4356,7 @@ static int stac92xx_init(struct hda_code
+                       continue;
+               }
+-              if (is_nid_hp_pin(cfg, nid))
++              if (is_nid_out_jack_pin(cfg, nid))
+                       continue; /* already has an unsol event */
+               pinctl = snd_hda_codec_read(codec, nid, 0,
diff --git a/queue-3.0/drm-fix-authentication-kernel-crash.patch b/queue-3.0/drm-fix-authentication-kernel-crash.patch
new file mode 100644 (file)
index 0000000..aca8630
--- /dev/null
@@ -0,0 +1,85 @@
+From 598781d71119827b454fd75d46f84755bca6f0c6 Mon Sep 17 00:00:00 2001
+From: Thomas Hellstrom <thellstrom@vmware.com>
+Date: Tue, 24 Jan 2012 18:54:21 +0100
+Subject: drm: Fix authentication kernel crash
+
+From: Thomas Hellstrom <thellstrom@vmware.com>
+
+commit 598781d71119827b454fd75d46f84755bca6f0c6 upstream.
+
+If the master tries to authenticate a client using drm_authmagic and
+that client has already closed its drm file descriptor,
+either wilfully or because it was terminated, the
+call to drm_authmagic will dereference a stale pointer into kmalloc'ed memory
+and corrupt it.
+
+Typically this results in a hard system hang.
+
+This patch fixes that problem by removing any authentication tokens
+(struct drm_magic_entry) open for a file descriptor when that file
+descriptor is closed.
+
+Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/drm_auth.c |    6 +++++-
+ drivers/gpu/drm/drm_fops.c |    5 +++++
+ include/drm/drmP.h         |    1 +
+ 3 files changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/drm_auth.c
++++ b/drivers/gpu/drm/drm_auth.c
+@@ -101,7 +101,7 @@ static int drm_add_magic(struct drm_mast
+  * Searches and unlinks the entry in drm_device::magiclist with the magic
+  * number hash key, while holding the drm_device::struct_mutex lock.
+  */
+-static int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
++int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
+ {
+       struct drm_magic_entry *pt;
+       struct drm_hash_item *hash;
+@@ -136,6 +136,8 @@ static int drm_remove_magic(struct drm_m
+  * If there is a magic number in drm_file::magic then use it, otherwise
+  * searches an unique non-zero magic number and add it associating it with \p
+  * file_priv.
++ * This ioctl needs protection by the drm_global_mutex, which protects
++ * struct drm_file::magic and struct drm_magic_entry::priv.
+  */
+ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
+ {
+@@ -173,6 +175,8 @@ int drm_getmagic(struct drm_device *dev,
+  * \return zero if authentication successed, or a negative number otherwise.
+  *
+  * Checks if \p file_priv is associated with the magic number passed in \arg.
++ * This ioctl needs protection by the drm_global_mutex, which protects
++ * struct drm_file::magic and struct drm_magic_entry::priv.
+  */
+ int drm_authmagic(struct drm_device *dev, void *data,
+                 struct drm_file *file_priv)
+--- a/drivers/gpu/drm/drm_fops.c
++++ b/drivers/gpu/drm/drm_fops.c
+@@ -486,6 +486,11 @@ int drm_release(struct inode *inode, str
+                 (long)old_encode_dev(file_priv->minor->device),
+                 dev->open_count);
++      /* Release any auth tokens that might point to this file_priv,
++         (do that under the drm_global_mutex) */
++      if (file_priv->magic)
++              (void) drm_remove_magic(file_priv->master, file_priv->magic);
++
+       /* if the master has gone away we can't do anything with the lock */
+       if (file_priv->minor->master)
+               drm_master_release(dev, filp);
+--- a/include/drm/drmP.h
++++ b/include/drm/drmP.h
+@@ -1323,6 +1323,7 @@ extern int drm_getmagic(struct drm_devic
+                       struct drm_file *file_priv);
+ extern int drm_authmagic(struct drm_device *dev, void *data,
+                        struct drm_file *file_priv);
++extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic);
+ /* Cache management (drm_cache.c) */
+ void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
diff --git a/queue-3.0/drm-radeon-kms-add-an-msi-quirk-for-dell-rs690.patch b/queue-3.0/drm-radeon-kms-add-an-msi-quirk-for-dell-rs690.patch
new file mode 100644 (file)
index 0000000..47f7806
--- /dev/null
@@ -0,0 +1,36 @@
+From 44517c44496062180a6376cc704b33129441ce60 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Sun, 15 Jan 2012 08:51:12 -0500
+Subject: drm/radeon/kms: Add an MSI quirk for Dell RS690
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 44517c44496062180a6376cc704b33129441ce60 upstream.
+
+Interrupts only work with MSIs.
+https://bugs.freedesktop.org/show_bug.cgi?id=37679
+
+Reported-by: Dmitry Podgorny <pasis.uax@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/radeon/radeon_irq_kms.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
++++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
+@@ -134,6 +134,12 @@ static bool radeon_msi_ok(struct radeon_
+       /* Dell RS690 only seems to work with MSIs. */
+       if ((rdev->pdev->device == 0x791f) &&
+           (rdev->pdev->subsystem_vendor == 0x1028) &&
++          (rdev->pdev->subsystem_device == 0x01fc))
++              return true;
++
++      /* Dell RS690 only seems to work with MSIs. */
++      if ((rdev->pdev->device == 0x791f) &&
++          (rdev->pdev->subsystem_vendor == 0x1028) &&
+           (rdev->pdev->subsystem_device == 0x01fd))
+               return true;
diff --git a/queue-3.0/ecryptfs-check-inode-changes-in-setattr.patch b/queue-3.0/ecryptfs-check-inode-changes-in-setattr.patch
new file mode 100644 (file)
index 0000000..25ff39c
--- /dev/null
@@ -0,0 +1,120 @@
+From a261a03904849c3df50bd0300efb7fb3f865137d Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@canonical.com>
+Date: Thu, 19 Jan 2012 20:33:44 -0600
+Subject: eCryptfs: Check inode changes in setattr
+
+From: Tyler Hicks <tyhicks@canonical.com>
+
+commit a261a03904849c3df50bd0300efb7fb3f865137d upstream.
+
+Most filesystems call inode_change_ok() very early in ->setattr(), but
+eCryptfs didn't call it at all. It allowed the lower filesystem to make
+the call in its ->setattr() function. Then, eCryptfs would copy the
+appropriate inode attributes from the lower inode to the eCryptfs inode.
+
+This patch changes that and actually calls inode_change_ok() on the
+eCryptfs inode, fairly early in ecryptfs_setattr(). Ideally, the call
+would happen earlier in ecryptfs_setattr(), but there are some possible
+inode initialization steps that must happen first.
+
+Since the call was already being made on the lower inode, the change in
+functionality should be minimal, except for the case of a file extending
+truncate call. In that case, inode_newsize_ok() was never being
+called on the eCryptfs inode. Rather than inode_newsize_ok() catching
+maximum file size errors early on, eCryptfs would encrypt zeroed pages
+and write them to the lower filesystem until the lower filesystem's
+write path caught the error in generic_write_checks(). This patch
+introduces a new function, called ecryptfs_inode_newsize_ok(), which
+checks if the new lower file size is within the appropriate limits when
+the truncate operation will be growing the lower file.
+
+In summary this change prevents eCryptfs truncate operations (and the
+resulting page encryptions), which would exceed the lower filesystem
+limits or FSIZE rlimits, from ever starting.
+
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Reviewed-by: Li Wang <liwang@nudt.edu.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ecryptfs/inode.c |   48 ++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 36 insertions(+), 12 deletions(-)
+
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -854,18 +854,6 @@ static int truncate_upper(struct dentry
+               size_t num_zeros = (PAGE_CACHE_SIZE
+                                   - (ia->ia_size & ~PAGE_CACHE_MASK));
+-
+-              /*
+-               * XXX(truncate) this should really happen at the begginning
+-               * of ->setattr.  But the code is too messy to that as part
+-               * of a larger patch.  ecryptfs is also totally missing out
+-               * on the inode_change_ok check at the beginning of
+-               * ->setattr while would include this.
+-               */
+-              rc = inode_newsize_ok(inode, ia->ia_size);
+-              if (rc)
+-                      goto out;
+-
+               if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
+                       truncate_setsize(inode, ia->ia_size);
+                       lower_ia->ia_size = ia->ia_size;
+@@ -915,6 +903,28 @@ out:
+       return rc;
+ }
++static int ecryptfs_inode_newsize_ok(struct inode *inode, loff_t offset)
++{
++      struct ecryptfs_crypt_stat *crypt_stat;
++      loff_t lower_oldsize, lower_newsize;
++
++      crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
++      lower_oldsize = upper_size_to_lower_size(crypt_stat,
++                                               i_size_read(inode));
++      lower_newsize = upper_size_to_lower_size(crypt_stat, offset);
++      if (lower_newsize > lower_oldsize) {
++              /*
++               * The eCryptfs inode and the new *lower* size are mixed here
++               * because we may not have the lower i_mutex held and/or it may
++               * not be appropriate to call inode_newsize_ok() with inodes
++               * from other filesystems.
++               */
++              return inode_newsize_ok(inode, lower_newsize);
++      }
++
++      return 0;
++}
++
+ /**
+  * ecryptfs_truncate
+  * @dentry: The ecryptfs layer dentry
+@@ -931,6 +941,10 @@ int ecryptfs_truncate(struct dentry *den
+       struct iattr lower_ia = { .ia_valid = 0 };
+       int rc;
++      rc = ecryptfs_inode_newsize_ok(dentry->d_inode, new_length);
++      if (rc)
++              return 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);
+@@ -1012,6 +1026,16 @@ static int ecryptfs_setattr(struct dentr
+               }
+       }
+       mutex_unlock(&crypt_stat->cs_mutex);
++
++      rc = inode_change_ok(inode, ia);
++      if (rc)
++              goto out;
++      if (ia->ia_valid & ATTR_SIZE) {
++              rc = ecryptfs_inode_newsize_ok(inode, ia->ia_size);
++              if (rc)
++                      goto out;
++      }
++
+       if (S_ISREG(inode->i_mode)) {
+               rc = filemap_write_and_wait(inode->i_mapping);
+               if (rc)
diff --git a/queue-3.0/ecryptfs-fix-oops-when-printing-debug-info-in-extent-crypto-functions.patch b/queue-3.0/ecryptfs-fix-oops-when-printing-debug-info-in-extent-crypto-functions.patch
new file mode 100644 (file)
index 0000000..f2ba8d6
--- /dev/null
@@ -0,0 +1,101 @@
+From 58ded24f0fcb85bddb665baba75892f6ad0f4b8a Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@canonical.com>
+Date: Tue, 24 Jan 2012 10:02:22 -0600
+Subject: eCryptfs: Fix oops when printing debug info in extent crypto functions
+
+From: Tyler Hicks <tyhicks@canonical.com>
+
+commit 58ded24f0fcb85bddb665baba75892f6ad0f4b8a upstream.
+
+If pages passed to the eCryptfs extent-based crypto functions are not
+mapped and the module parameter ecryptfs_verbosity=1 was specified at
+loading time, a NULL pointer dereference will occur.
+
+Note that this wouldn't happen on a production system, as you wouldn't
+pass ecryptfs_verbosity=1 on a production system. It leaks private
+information to the system logs and is for debugging only.
+
+The debugging info printed in these messages is no longer very useful
+and rather than doing a kmap() in these debugging paths, it will be
+better to simply remove the debugging paths completely.
+
+https://launchpad.net/bugs/913651
+
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Reported-by: Daniel DeFreez
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ecryptfs/crypto.c |   40 ----------------------------------------
+ 1 file changed, 40 deletions(-)
+
+--- a/fs/ecryptfs/crypto.c
++++ b/fs/ecryptfs/crypto.c
+@@ -417,17 +417,6 @@ static int ecryptfs_encrypt_extent(struc
+                       (unsigned long long)(extent_base + extent_offset), rc);
+               goto out;
+       }
+-      if (unlikely(ecryptfs_verbosity > 0)) {
+-              ecryptfs_printk(KERN_DEBUG, "Encrypting extent "
+-                              "with iv:\n");
+-              ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
+-              ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
+-                              "encryption:\n");
+-              ecryptfs_dump_hex((char *)
+-                                (page_address(page)
+-                                 + (extent_offset * crypt_stat->extent_size)),
+-                                8);
+-      }
+       rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0,
+                                         page, (extent_offset
+                                                * crypt_stat->extent_size),
+@@ -440,14 +429,6 @@ static int ecryptfs_encrypt_extent(struc
+               goto out;
+       }
+       rc = 0;
+-      if (unlikely(ecryptfs_verbosity > 0)) {
+-              ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16llx]; "
+-                      "rc = [%d]\n",
+-                      (unsigned long long)(extent_base + extent_offset), rc);
+-              ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
+-                              "encryption:\n");
+-              ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8);
+-      }
+ out:
+       return rc;
+ }
+@@ -543,17 +524,6 @@ static int ecryptfs_decrypt_extent(struc
+                       (unsigned long long)(extent_base + extent_offset), rc);
+               goto out;
+       }
+-      if (unlikely(ecryptfs_verbosity > 0)) {
+-              ecryptfs_printk(KERN_DEBUG, "Decrypting extent "
+-                              "with iv:\n");
+-              ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
+-              ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
+-                              "decryption:\n");
+-              ecryptfs_dump_hex((char *)
+-                                (page_address(enc_extent_page)
+-                                 + (extent_offset * crypt_stat->extent_size)),
+-                                8);
+-      }
+       rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
+                                         (extent_offset
+                                          * crypt_stat->extent_size),
+@@ -567,16 +537,6 @@ static int ecryptfs_decrypt_extent(struc
+               goto out;
+       }
+       rc = 0;
+-      if (unlikely(ecryptfs_verbosity > 0)) {
+-              ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16llx]; "
+-                      "rc = [%d]\n",
+-                      (unsigned long long)(extent_base + extent_offset), rc);
+-              ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
+-                              "decryption:\n");
+-              ecryptfs_dump_hex((char *)(page_address(page)
+-                                         + (extent_offset
+-                                            * crypt_stat->extent_size)), 8);
+-      }
+ out:
+       return rc;
+ }
diff --git a/queue-3.0/ecryptfs-improve-metadata-read-failure-logging.patch b/queue-3.0/ecryptfs-improve-metadata-read-failure-logging.patch
new file mode 100644 (file)
index 0000000..89f46ad
--- /dev/null
@@ -0,0 +1,56 @@
+From 30373dc0c87ffef68d5628e77d56ffb1fa22e1ee Mon Sep 17 00:00:00 2001
+From: Tim Gardner <tim.gardner@canonical.com>
+Date: Thu, 12 Jan 2012 16:31:55 +0100
+Subject: ecryptfs: Improve metadata read failure logging
+
+From: Tim Gardner <tim.gardner@canonical.com>
+
+commit 30373dc0c87ffef68d5628e77d56ffb1fa22e1ee upstream.
+
+Print inode on metadata read failure. The only real
+way of dealing with metadata read failures is to delete
+the underlying file system file. Having the inode
+allows one to 'find . -inum INODE`.
+
+[tyhicks@canonical.com: Removed some minor not-for-stable parts]
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ecryptfs/crypto.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/fs/ecryptfs/crypto.c
++++ b/fs/ecryptfs/crypto.c
+@@ -1618,7 +1618,8 @@ int ecryptfs_read_metadata(struct dentry
+               rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
+               if (rc) {
+                       printk(KERN_DEBUG "Valid eCryptfs headers not found in "
+-                             "file header region or xattr region\n");
++                             "file header region or xattr region, inode %lu\n",
++                              ecryptfs_inode->i_ino);
+                       rc = -EINVAL;
+                       goto out;
+               }
+@@ -1627,7 +1628,8 @@ int ecryptfs_read_metadata(struct dentry
+                                               ECRYPTFS_DONT_VALIDATE_HEADER_SIZE);
+               if (rc) {
+                       printk(KERN_DEBUG "Valid eCryptfs headers not found in "
+-                             "file xattr region either\n");
++                             "file xattr region either, inode %lu\n",
++                              ecryptfs_inode->i_ino);
+                       rc = -EINVAL;
+               }
+               if (crypt_stat->mount_crypt_stat->flags
+@@ -1638,7 +1640,8 @@ int ecryptfs_read_metadata(struct dentry
+                              "crypto metadata only in the extended attribute "
+                              "region, but eCryptfs was mounted without "
+                              "xattr support enabled. eCryptfs will not treat "
+-                             "this like an encrypted file.\n");
++                             "this like an encrypted file, inode %lu\n",
++                              ecryptfs_inode->i_ino);
+                       rc = -EINVAL;
+               }
+       }
diff --git a/queue-3.0/ecryptfs-make-truncate-path-killable.patch b/queue-3.0/ecryptfs-make-truncate-path-killable.patch
new file mode 100644 (file)
index 0000000..ac2e3f5
--- /dev/null
@@ -0,0 +1,69 @@
+From 5e6f0d769017cc49207ef56996e42363ec26c1f0 Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@canonical.com>
+Date: Wed, 18 Jan 2012 18:30:04 -0600
+Subject: eCryptfs: Make truncate path killable
+
+From: Tyler Hicks <tyhicks@canonical.com>
+
+commit 5e6f0d769017cc49207ef56996e42363ec26c1f0 upstream.
+
+ecryptfs_write() handles the truncation of eCryptfs inodes. It grabs a
+page, zeroes out the appropriate portions, and then encrypts the page
+before writing it to the lower filesystem. It was unkillable and due to
+the lack of sparse file support could result in tying up a large portion
+of system resources, while encrypting pages of zeros, with no way for
+the truncate operation to be stopped from userspace.
+
+This patch adds the ability for ecryptfs_write() to detect a pending
+fatal signal and return as gracefully as possible. The intent is to
+leave the lower file in a useable state, while still allowing a user to
+break out of the encryption loop. If a pending fatal signal is detected,
+the eCryptfs inode size is updated to reflect the modified inode size
+and then -EINTR is returned.
+
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ecryptfs/read_write.c |   19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/fs/ecryptfs/read_write.c
++++ b/fs/ecryptfs/read_write.c
+@@ -132,6 +132,11 @@ int ecryptfs_write(struct inode *ecryptf
+               size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
+               size_t total_remaining_bytes = ((offset + size) - pos);
++              if (fatal_signal_pending(current)) {
++                      rc = -EINTR;
++                      break;
++              }
++
+               if (num_bytes > total_remaining_bytes)
+                       num_bytes = total_remaining_bytes;
+               if (pos < offset) {
+@@ -193,15 +198,19 @@ int ecryptfs_write(struct inode *ecryptf
+               }
+               pos += num_bytes;
+       }
+-      if ((offset + size) > ecryptfs_file_size) {
+-              i_size_write(ecryptfs_inode, (offset + size));
++      if (pos > ecryptfs_file_size) {
++              i_size_write(ecryptfs_inode, pos);
+               if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) {
+-                      rc = ecryptfs_write_inode_size_to_metadata(
++                      int rc2;
++
++                      rc2 = ecryptfs_write_inode_size_to_metadata(
+                                                               ecryptfs_inode);
+-                      if (rc) {
++                      if (rc2) {
+                               printk(KERN_ERR "Problem with "
+                                      "ecryptfs_write_inode_size_to_metadata; "
+-                                     "rc = [%d]\n", rc);
++                                     "rc = [%d]\n", rc2);
++                              if (!rc)
++                                      rc = rc2;
+                               goto out;
+                       }
+               }
diff --git a/queue-3.0/ecryptfs-sanitize-write-counts-of-dev-ecryptfs.patch b/queue-3.0/ecryptfs-sanitize-write-counts-of-dev-ecryptfs.patch
new file mode 100644 (file)
index 0000000..3e20654
--- /dev/null
@@ -0,0 +1,101 @@
+From db10e556518eb9d21ee92ff944530d84349684f4 Mon Sep 17 00:00:00 2001
+From: Tyler Hicks <tyhicks@canonical.com>
+Date: Thu, 12 Jan 2012 11:30:44 +0100
+Subject: eCryptfs: Sanitize write counts of /dev/ecryptfs
+
+From: Tyler Hicks <tyhicks@canonical.com>
+
+commit db10e556518eb9d21ee92ff944530d84349684f4 upstream.
+
+A malicious count value specified when writing to /dev/ecryptfs may
+result in a a very large kernel memory allocation.
+
+This patch peeks at the specified packet payload size, adds that to the
+size of the packet headers and compares the result with the write count
+value. The resulting maximum memory allocation size is approximately 532
+bytes.
+
+Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
+Reported-by: Sasha Levin <levinsasha928@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/ecryptfs/miscdev.c |   56 +++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 38 insertions(+), 18 deletions(-)
+
+--- a/fs/ecryptfs/miscdev.c
++++ b/fs/ecryptfs/miscdev.c
+@@ -409,11 +409,47 @@ ecryptfs_miscdev_write(struct file *file
+       ssize_t sz = 0;
+       char *data;
+       uid_t euid = current_euid();
++      unsigned char packet_size_peek[3];
+       int rc;
+-      if (count == 0)
++      if (count == 0) {
+               goto out;
++      } else if (count == (1 + 4)) {
++              /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */
++              goto memdup;
++      } else if (count < (1 + 4 + 1)
++                 || count > (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
++                             + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)) {
++              printk(KERN_WARNING "%s: Acceptable packet size range is "
++                     "[%d-%lu], but amount of data written is [%zu].",
++                     __func__, (1 + 4 + 1),
++                     (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
++                      + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES), count);
++              return -EINVAL;
++      }
++
++      if (copy_from_user(packet_size_peek, (buf + 1 + 4),
++                         sizeof(packet_size_peek))) {
++              printk(KERN_WARNING "%s: Error while inspecting packet size\n",
++                     __func__);
++              return -EFAULT;
++      }
++      rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size,
++                                        &packet_size_length);
++      if (rc) {
++              printk(KERN_WARNING "%s: Error parsing packet length; "
++                     "rc = [%d]\n", __func__, rc);
++              return rc;
++      }
++
++      if ((1 + 4 + packet_size_length + packet_size) != count) {
++              printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__,
++                     packet_size);
++              return -EINVAL;
++      }
++
++memdup:
+       data = memdup_user(buf, count);
+       if (IS_ERR(data)) {
+               printk(KERN_ERR "%s: memdup_user returned error [%ld]\n",
+@@ -435,23 +471,7 @@ ecryptfs_miscdev_write(struct file *file
+               }
+               memcpy(&counter_nbo, &data[i], 4);
+               seq = be32_to_cpu(counter_nbo);
+-              i += 4;
+-              rc = ecryptfs_parse_packet_length(&data[i], &packet_size,
+-                                                &packet_size_length);
+-              if (rc) {
+-                      printk(KERN_WARNING "%s: Error parsing packet length; "
+-                             "rc = [%d]\n", __func__, rc);
+-                      goto out_free;
+-              }
+-              i += packet_size_length;
+-              if ((1 + 4 + packet_size_length + packet_size) != count) {
+-                      printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])"
+-                             " + packet_size([%zd]))([%zd]) != "
+-                             "count([%zd]). Invalid packet format.\n",
+-                             __func__, packet_size_length, packet_size,
+-                             (1 + packet_size_length + packet_size), count);
+-                      goto out_free;
+-              }
++              i += 4 + packet_size_length;
+               rc = ecryptfs_miscdev_response(&data[i], packet_size,
+                                              euid, current_user_ns(),
+                                              task_pid(current), seq);
diff --git a/queue-3.0/series b/queue-3.0/series
new file mode 100644 (file)
index 0000000..945daa6
--- /dev/null
@@ -0,0 +1,9 @@
+alsa-hda-fix-silent-outputs-from-docking-station-jacks-of-dell-laptops.patch
+ecryptfs-sanitize-write-counts-of-dev-ecryptfs.patch
+ecryptfs-improve-metadata-read-failure-logging.patch
+ecryptfs-make-truncate-path-killable.patch
+ecryptfs-check-inode-changes-in-setattr.patch
+ecryptfs-fix-oops-when-printing-debug-info-in-extent-crypto-functions.patch
+drm-radeon-kms-add-an-msi-quirk-for-dell-rs690.patch
+drm-fix-authentication-kernel-crash.patch
+xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch
diff --git a/queue-3.0/xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch b/queue-3.0/xfs-fix-missing-xfs_iunlock-on-error-recovery-path-in-xfs_readlink.patch
new file mode 100644 (file)
index 0000000..2d5c0ce
--- /dev/null
@@ -0,0 +1,35 @@
+From 9b025eb3a89e041bab6698e3858706be2385d692 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 11 Jan 2012 18:52:10 +0000
+Subject: xfs: Fix missing xfs_iunlock() on error recovery path in xfs_readlink()
+
+From: Jan Kara <jack@suse.cz>
+
+commit 9b025eb3a89e041bab6698e3858706be2385d692 upstream.
+
+Commit b52a360b forgot to call xfs_iunlock() when it detected corrupted
+symplink and bailed out. Fix it by jumping to 'out' instead of doing return.
+
+CC: Carlos Maiolino <cmaiolino@redhat.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Alex Elder <elder@kernel.org>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Ben Myers <bpm@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/xfs/xfs_vnodeops.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/xfs/xfs_vnodeops.c
++++ b/fs/xfs/xfs_vnodeops.c
+@@ -554,7 +554,8 @@ xfs_readlink(
+                        __func__, (unsigned long long) ip->i_ino,
+                        (long long) pathlen);
+               ASSERT(0);
+-              return XFS_ERROR(EFSCORRUPTED);
++              error = XFS_ERROR(EFSCORRUPTED);
++              goto out;
+       }