]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.16-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Sep 2014 19:19:00 +0000 (12:19 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Sep 2014 19:19:00 +0000 (12:19 -0700)
added patches:
cifs-fix-smb2-readdir-error-handling.patch
keys-fix-termination-condition-in-assoc-array-garbage-collection.patch
keys-fix-use-after-free-in-assoc_array_gc.patch

queue-3.16/cifs-fix-smb2-readdir-error-handling.patch [new file with mode: 0644]
queue-3.16/keys-fix-termination-condition-in-assoc-array-garbage-collection.patch [new file with mode: 0644]
queue-3.16/keys-fix-use-after-free-in-assoc_array_gc.patch [new file with mode: 0644]
queue-3.16/series

diff --git a/queue-3.16/cifs-fix-smb2-readdir-error-handling.patch b/queue-3.16/cifs-fix-smb2-readdir-error-handling.patch
new file mode 100644 (file)
index 0000000..494d154
--- /dev/null
@@ -0,0 +1,165 @@
+From 52755808d4525f4d5b86d112d36ffc7a46f3fb48 Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilovsky@samba.org>
+Date: Mon, 18 Aug 2014 20:49:57 +0400
+Subject: CIFS: Fix SMB2 readdir error handling
+
+From: Pavel Shilovsky <pshilovsky@samba.org>
+
+commit 52755808d4525f4d5b86d112d36ffc7a46f3fb48 upstream.
+
+SMB2 servers indicates the end of a directory search with
+STATUS_NO_MORE_FILE error code that is not processed now.
+This causes generic/257 xfstest to fail. Fix this by triggering
+the end of search by this error code in SMB2_query_directory.
+
+Also when negotiating CIFS protocol we tell the server to close
+the search automatically at the end and there is no need to do
+it itself. In the case of SMB2 protocol, we need to close it
+explicitly - separate close directory checks for different
+protocols.
+
+Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsglob.h     |    2 ++
+ fs/cifs/file.c         |    2 +-
+ fs/cifs/readdir.c      |    2 +-
+ fs/cifs/smb1ops.c      |    7 +++++++
+ fs/cifs/smb2maperror.c |    2 +-
+ fs/cifs/smb2ops.c      |    9 +++++++++
+ fs/cifs/smb2pdu.c      |    9 ++++-----
+ 7 files changed, 25 insertions(+), 8 deletions(-)
+
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -399,6 +399,8 @@ struct smb_version_operations {
+                       const struct cifs_fid *, u32 *);
+       int (*set_acl)(struct cifs_ntsd *, __u32, struct inode *, const char *,
+                       int);
++      /* check if we need to issue closedir */
++      bool (*dir_needs_close)(struct cifsFileInfo *);
+ };
+ struct smb_version_values {
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -762,7 +762,7 @@ int cifs_closedir(struct inode *inode, s
+       cifs_dbg(FYI, "Freeing private data in close dir\n");
+       spin_lock(&cifs_file_list_lock);
+-      if (!cfile->srch_inf.endOfSearch && !cfile->invalidHandle) {
++      if (server->ops->dir_needs_close(cfile)) {
+               cfile->invalidHandle = true;
+               spin_unlock(&cifs_file_list_lock);
+               if (server->ops->close_dir)
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -593,7 +593,7 @@ find_cifs_entry(const unsigned int xid,
+               /* close and restart search */
+               cifs_dbg(FYI, "search backing up - close and restart search\n");
+               spin_lock(&cifs_file_list_lock);
+-              if (!cfile->srch_inf.endOfSearch && !cfile->invalidHandle) {
++              if (server->ops->dir_needs_close(cfile)) {
+                       cfile->invalidHandle = true;
+                       spin_unlock(&cifs_file_list_lock);
+                       if (server->ops->close_dir)
+--- a/fs/cifs/smb1ops.c
++++ b/fs/cifs/smb1ops.c
+@@ -1009,6 +1009,12 @@ cifs_is_read_op(__u32 oplock)
+       return oplock == OPLOCK_READ;
+ }
++static bool
++cifs_dir_needs_close(struct cifsFileInfo *cfile)
++{
++      return !cfile->srch_inf.endOfSearch && !cfile->invalidHandle;
++}
++
+ struct smb_version_operations smb1_operations = {
+       .send_cancel = send_nt_cancel,
+       .compare_fids = cifs_compare_fids,
+@@ -1078,6 +1084,7 @@ struct smb_version_operations smb1_opera
+       .query_mf_symlink = cifs_query_mf_symlink,
+       .create_mf_symlink = cifs_create_mf_symlink,
+       .is_read_op = cifs_is_read_op,
++      .dir_needs_close = cifs_dir_needs_close,
+ #ifdef CONFIG_CIFS_XATTR
+       .query_all_EAs = CIFSSMBQAllEAs,
+       .set_EA = CIFSSMBSetEA,
+--- a/fs/cifs/smb2maperror.c
++++ b/fs/cifs/smb2maperror.c
+@@ -214,7 +214,7 @@ static const struct status_to_posix_erro
+       {STATUS_BREAKPOINT, -EIO, "STATUS_BREAKPOINT"},
+       {STATUS_SINGLE_STEP, -EIO, "STATUS_SINGLE_STEP"},
+       {STATUS_BUFFER_OVERFLOW, -EIO, "STATUS_BUFFER_OVERFLOW"},
+-      {STATUS_NO_MORE_FILES, -EIO, "STATUS_NO_MORE_FILES"},
++      {STATUS_NO_MORE_FILES, -ENODATA, "STATUS_NO_MORE_FILES"},
+       {STATUS_WAKE_SYSTEM_DEBUGGER, -EIO, "STATUS_WAKE_SYSTEM_DEBUGGER"},
+       {STATUS_HANDLES_CLOSED, -EIO, "STATUS_HANDLES_CLOSED"},
+       {STATUS_NO_INHERITANCE, -EIO, "STATUS_NO_INHERITANCE"},
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -1104,6 +1104,12 @@ smb3_parse_lease_buf(void *buf, unsigned
+       return le32_to_cpu(lc->lcontext.LeaseState);
+ }
++static bool
++smb2_dir_needs_close(struct cifsFileInfo *cfile)
++{
++      return !cfile->invalidHandle;
++}
++
+ struct smb_version_operations smb20_operations = {
+       .compare_fids = smb2_compare_fids,
+       .setup_request = smb2_setup_request,
+@@ -1177,6 +1183,7 @@ struct smb_version_operations smb20_oper
+       .create_lease_buf = smb2_create_lease_buf,
+       .parse_lease_buf = smb2_parse_lease_buf,
+       .clone_range = smb2_clone_range,
++      .dir_needs_close = smb2_dir_needs_close,
+ };
+ struct smb_version_operations smb21_operations = {
+@@ -1252,6 +1259,7 @@ struct smb_version_operations smb21_oper
+       .create_lease_buf = smb2_create_lease_buf,
+       .parse_lease_buf = smb2_parse_lease_buf,
+       .clone_range = smb2_clone_range,
++      .dir_needs_close = smb2_dir_needs_close,
+ };
+ struct smb_version_operations smb30_operations = {
+@@ -1330,6 +1338,7 @@ struct smb_version_operations smb30_oper
+       .parse_lease_buf = smb3_parse_lease_buf,
+       .clone_range = smb2_clone_range,
+       .validate_negotiate = smb3_validate_negotiate,
++      .dir_needs_close = smb2_dir_needs_close,
+ };
+ struct smb_version_values smb20_values = {
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -2142,6 +2142,10 @@ SMB2_query_directory(const unsigned int
+       rsp = (struct smb2_query_directory_rsp *)iov[0].iov_base;
+       if (rc) {
++              if (rc == -ENODATA && rsp->hdr.Status == STATUS_NO_MORE_FILES) {
++                      srch_inf->endOfSearch = true;
++                      rc = 0;
++              }
+               cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE);
+               goto qdir_exit;
+       }
+@@ -2179,11 +2183,6 @@ SMB2_query_directory(const unsigned int
+       else
+               cifs_dbg(VFS, "illegal search buffer type\n");
+-      if (rsp->hdr.Status == STATUS_NO_MORE_FILES)
+-              srch_inf->endOfSearch = 1;
+-      else
+-              srch_inf->endOfSearch = 0;
+-
+       return rc;
+ qdir_exit:
diff --git a/queue-3.16/keys-fix-termination-condition-in-assoc-array-garbage-collection.patch b/queue-3.16/keys-fix-termination-condition-in-assoc-array-garbage-collection.patch
new file mode 100644 (file)
index 0000000..7eff8b6
--- /dev/null
@@ -0,0 +1,108 @@
+From 95389b08d93d5c06ec63ab49bd732b0069b7c35e Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 10 Sep 2014 22:22:00 +0100
+Subject: KEYS: Fix termination condition in assoc array garbage collection
+
+From: David Howells <dhowells@redhat.com>
+
+commit 95389b08d93d5c06ec63ab49bd732b0069b7c35e upstream.
+
+This fixes CVE-2014-3631.
+
+It is possible for an associative array to end up with a shortcut node at the
+root of the tree if there are more than fan-out leaves in the tree, but they
+all crowd into the same slot in the lowest level (ie. they all have the same
+first nibble of their index keys).
+
+When assoc_array_gc() returns back up the tree after scanning some leaves, it
+can fall off of the root and crash because it assumes that the back pointer
+from a shortcut (after label ascend_old_tree) must point to a normal node -
+which isn't true of a shortcut node at the root.
+
+Should we find we're ascending rootwards over a shortcut, we should check to
+see if the backpointer is zero - and if it is, we have completed the scan.
+
+This particular bug cannot occur if the root node is not a shortcut - ie. if
+you have fewer than 17 keys in a keyring or if you have at least two keys that
+sit into separate slots (eg. a keyring and a non keyring).
+
+This can be reproduced by:
+
+       ring=`keyctl newring bar @s`
+       for ((i=1; i<=18; i++)); do last_key=`keyctl newring foo$i $ring`; done
+       keyctl timeout $last_key 2
+
+Doing this:
+
+       echo 3 >/proc/sys/kernel/keys/gc_delay
+
+first will speed things up.
+
+If we do fall off of the top of the tree, we get the following oops:
+
+BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
+IP: [<ffffffff8136cea7>] assoc_array_gc+0x2f7/0x540
+PGD dae15067 PUD cfc24067 PMD 0
+Oops: 0000 [#1] SMP
+Modules linked in: xt_nat xt_mark nf_conntrack_netbios_ns nf_conntrack_broadcast ip6t_rpfilter ip6t_REJECT xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_ni
+CPU: 0 PID: 26011 Comm: kworker/0:1 Not tainted 3.14.9-200.fc20.x86_64 #1
+Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
+Workqueue: events key_garbage_collector
+task: ffff8800918bd580 ti: ffff8800aac14000 task.ti: ffff8800aac14000
+RIP: 0010:[<ffffffff8136cea7>] [<ffffffff8136cea7>] assoc_array_gc+0x2f7/0x540
+RSP: 0018:ffff8800aac15d40  EFLAGS: 00010206
+RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff8800aaecacc0
+RDX: ffff8800daecf440 RSI: 0000000000000001 RDI: ffff8800aadc2bc0
+RBP: ffff8800aac15da8 R08: 0000000000000001 R09: 0000000000000003
+R10: ffffffff8136ccc7 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000000 R14: 0000000000000070 R15: 0000000000000001
+FS:  0000000000000000(0000) GS:ffff88011fc00000(0000) knlGS:0000000000000000
+CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
+CR2: 0000000000000018 CR3: 00000000db10d000 CR4: 00000000000006f0
+Stack:
+ ffff8800aac15d50 0000000000000011 ffff8800aac15db8 ffffffff812e2a70
+ ffff880091a00600 0000000000000000 ffff8800aadc2bc3 00000000cd42c987
+ ffff88003702df20 ffff88003702dfa0 0000000053b65c09 ffff8800aac15fd8
+Call Trace:
+ [<ffffffff812e2a70>] ? keyring_detect_cycle_iterator+0x30/0x30
+ [<ffffffff812e3e75>] keyring_gc+0x75/0x80
+ [<ffffffff812e1424>] key_garbage_collector+0x154/0x3c0
+ [<ffffffff810a67b6>] process_one_work+0x176/0x430
+ [<ffffffff810a744b>] worker_thread+0x11b/0x3a0
+ [<ffffffff810a7330>] ? rescuer_thread+0x3b0/0x3b0
+ [<ffffffff810ae1a8>] kthread+0xd8/0xf0
+ [<ffffffff810ae0d0>] ? insert_kthread_work+0x40/0x40
+ [<ffffffff816ffb7c>] ret_from_fork+0x7c/0xb0
+ [<ffffffff810ae0d0>] ? insert_kthread_work+0x40/0x40
+Code: 08 4c 8b 22 0f 84 bf 00 00 00 41 83 c7 01 49 83 e4 fc 41 83 ff 0f 4c 89 65 c0 0f 8f 5a fe ff ff 48 8b 45 c0 4d 63 cf 49 83 c1 02 <4e> 8b 34 c8 4d 85 f6 0f 84 be 00 00 00 41 f6 c6 01 0f 84 92
+RIP  [<ffffffff8136cea7>] assoc_array_gc+0x2f7/0x540
+ RSP <ffff8800aac15d40>
+CR2: 0000000000000018
+---[ end trace 1129028a088c0cbd ]---
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Acked-by: Don Zickus <dzickus@redhat.com>
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/assoc_array.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/lib/assoc_array.c
++++ b/lib/assoc_array.c
+@@ -1723,11 +1723,13 @@ ascend_old_tree:
+               shortcut = assoc_array_ptr_to_shortcut(ptr);
+               slot = shortcut->parent_slot;
+               cursor = shortcut->back_pointer;
++              if (!cursor)
++                      goto gc_complete;
+       } else {
+               slot = node->parent_slot;
+               cursor = ptr;
+       }
+-      BUG_ON(!ptr);
++      BUG_ON(!cursor);
+       node = assoc_array_ptr_to_node(cursor);
+       slot++;
+       goto continue_node;
diff --git a/queue-3.16/keys-fix-use-after-free-in-assoc_array_gc.patch b/queue-3.16/keys-fix-use-after-free-in-assoc_array_gc.patch
new file mode 100644 (file)
index 0000000..4db701b
--- /dev/null
@@ -0,0 +1,38 @@
+From 27419604f51a97d497853f14142c1059d46eb597 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Tue, 2 Sep 2014 13:52:20 +0100
+Subject: KEYS: Fix use-after-free in assoc_array_gc()
+
+From: David Howells <dhowells@redhat.com>
+
+commit 27419604f51a97d497853f14142c1059d46eb597 upstream.
+
+An edit script should be considered inaccessible by a function once it has
+called assoc_array_apply_edit() or assoc_array_cancel_edit().
+
+However, assoc_array_gc() is accessing the edit script just after the
+gc_complete: label.
+
+Reported-by: Andreea-Cristina Bernat <bernat.ada@gmail.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Andreea-Cristina Bernat <bernat.ada@gmail.com>
+cc: shemming@brocade.com
+cc: paulmck@linux.vnet.ibm.com
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/assoc_array.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/lib/assoc_array.c
++++ b/lib/assoc_array.c
+@@ -1735,7 +1735,7 @@ ascend_old_tree:
+ gc_complete:
+       edit->set[0].to = new_root;
+       assoc_array_apply_edit(edit);
+-      edit->array->nr_leaves_on_tree = nr_leaves_on_tree;
++      array->nr_leaves_on_tree = nr_leaves_on_tree;
+       return 0;
+ enomem:
index 9142039db430b83b9e859583b561e5945cad6a2e..a1a8fc8be2da189aadd1ac62088d36a14d82e9c6 100644 (file)
@@ -153,3 +153,6 @@ ib-srp-fix-deadlock-between-host-removal-and-multipathd.patch
 drm-nouveau-dis-enable-vblank-irqs-during-suspend-resume.patch
 drm-nouveau-bump-version-from-1.1.1-to-1.1.2.patch
 vfs-fix-bad-hashing-of-dentries.patch
+cifs-fix-smb2-readdir-error-handling.patch
+keys-fix-use-after-free-in-assoc_array_gc.patch
+keys-fix-termination-condition-in-assoc-array-garbage-collection.patch