linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, David Howells <dhowells@redhat.com>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 4.4 11/20] assoc_array: Fix a buggy node-splitting case
Date: Tue, 31 Oct 2017 10:55:27 +0100	[thread overview]
Message-ID: <20171031095510.755397059@linuxfoundation.org> (raw)
In-Reply-To: <20171031095510.079198256@linuxfoundation.org>

4.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: David Howells <dhowells@redhat.com>

commit ea6789980fdaa610d7eb63602c746bf6ec70cd2b upstream.

This fixes CVE-2017-12193.

Fix a case in the assoc_array implementation in which a new leaf is
added that needs to go into a node that happens to be full, where the
existing leaves in that node cluster together at that level to the
exclusion of new leaf.

What needs to happen is that the existing leaves get moved out to a new
node, N1, at level + 1 and the existing node needs replacing with one,
N0, that has pointers to the new leaf and to N1.

The code that tries to do this gets this wrong in two ways:

 (1) The pointer that should've pointed from N0 to N1 is set to point
     recursively to N0 instead.

 (2) The backpointer from N0 needs to be set correctly in the case N0 is
     either the root node or reached through a shortcut.

Fix this by removing this path and using the split_node path instead,
which achieves the same end, but in a more general way (thanks to Eric
Biggers for spotting the redundancy).

The problem manifests itself as:

  BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
  IP: assoc_array_apply_edit+0x59/0xe5

Fixes: 3cb989501c26 ("Add a generic associative array implementation.")
Reported-and-tested-by: WU Fan <u3536072@connect.hku.hk>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 lib/assoc_array.c |   51 +++++++++++++++++----------------------------------
 1 file changed, 17 insertions(+), 34 deletions(-)

--- a/lib/assoc_array.c
+++ b/lib/assoc_array.c
@@ -598,21 +598,31 @@ static bool assoc_array_insert_into_term
 		if ((edit->segment_cache[ASSOC_ARRAY_FAN_OUT] ^ base_seg) == 0)
 			goto all_leaves_cluster_together;
 
-		/* Otherwise we can just insert a new node ahead of the old
-		 * one.
+		/* Otherwise all the old leaves cluster in the same slot, but
+		 * the new leaf wants to go into a different slot - so we
+		 * create a new node (n0) to hold the new leaf and a pointer to
+		 * a new node (n1) holding all the old leaves.
+		 *
+		 * This can be done by falling through to the node splitting
+		 * path.
 		 */
-		goto present_leaves_cluster_but_not_new_leaf;
+		pr_devel("present leaves cluster but not new leaf\n");
 	}
 
 split_node:
 	pr_devel("split node\n");
 
-	/* We need to split the current node; we know that the node doesn't
-	 * simply contain a full set of leaves that cluster together (it
-	 * contains meta pointers and/or non-clustering leaves).
+	/* We need to split the current node.  The node must contain anything
+	 * from a single leaf (in the one leaf case, this leaf will cluster
+	 * with the new leaf) and the rest meta-pointers, to all leaves, some
+	 * of which may cluster.
+	 *
+	 * It won't contain the case in which all the current leaves plus the
+	 * new leaves want to cluster in the same slot.
 	 *
 	 * We need to expel at least two leaves out of a set consisting of the
-	 * leaves in the node and the new leaf.
+	 * leaves in the node and the new leaf.  The current meta pointers can
+	 * just be copied as they shouldn't cluster with any of the leaves.
 	 *
 	 * We need a new node (n0) to replace the current one and a new node to
 	 * take the expelled nodes (n1).
@@ -717,33 +727,6 @@ found_slot_for_multiple_occupancy:
 	pr_devel("<--%s() = ok [split node]\n", __func__);
 	return true;
 
-present_leaves_cluster_but_not_new_leaf:
-	/* All the old leaves cluster in the same slot, but the new leaf wants
-	 * to go into a different slot, so we create a new node to hold the new
-	 * leaf and a pointer to a new node holding all the old leaves.
-	 */
-	pr_devel("present leaves cluster but not new leaf\n");
-
-	new_n0->back_pointer = node->back_pointer;
-	new_n0->parent_slot = node->parent_slot;
-	new_n0->nr_leaves_on_branch = node->nr_leaves_on_branch;
-	new_n1->back_pointer = assoc_array_node_to_ptr(new_n0);
-	new_n1->parent_slot = edit->segment_cache[0];
-	new_n1->nr_leaves_on_branch = node->nr_leaves_on_branch;
-	edit->adjust_count_on = new_n0;
-
-	for (i = 0; i < ASSOC_ARRAY_FAN_OUT; i++)
-		new_n1->slots[i] = node->slots[i];
-
-	new_n0->slots[edit->segment_cache[0]] = assoc_array_node_to_ptr(new_n0);
-	edit->leaf_p = &new_n0->slots[edit->segment_cache[ASSOC_ARRAY_FAN_OUT]];
-
-	edit->set[0].ptr = &assoc_array_ptr_to_node(node->back_pointer)->slots[node->parent_slot];
-	edit->set[0].to = assoc_array_node_to_ptr(new_n0);
-	edit->excised_meta[0] = assoc_array_node_to_ptr(node);
-	pr_devel("<--%s() = ok [insert node before]\n", __func__);
-	return true;
-
 all_leaves_cluster_together:
 	/* All the leaves, new and old, want to cluster together in this node
 	 * in the same slot, so we have to replace this node with a shortcut to

  parent reply	other threads:[~2017-10-31  9:55 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-31  9:55 [PATCH 4.4 00/20] 4.4.96-stable review Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 01/20] workqueue: replace pool->manager_arb mutex with a flag Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 02/20] ALSA: hda/realtek - Add support for ALC236/ALC3204 Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 03/20] ALSA: hda - fix headset mic problem for Dell machines with alc236 Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 04/20] ceph: unlock dangling spinlock in try_flush_caps() Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 05/20] usb: xhci: Handle error condition in xhci_stop_device() Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 06/20] spi: uapi: spidev: add missing ioctl header Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 07/20] fuse: fix READDIRPLUS skipping an entry Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 08/20] xen/gntdev: avoid out of bounds access in case of partial gntdev_mmap() Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 09/20] Input: elan_i2c - add ELAN0611 to the ACPI table Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 10/20] Input: gtco - fix potential out-of-bound access Greg Kroah-Hartman
2017-10-31  9:55 ` Greg Kroah-Hartman [this message]
2017-10-31  9:55 ` [PATCH 4.4 12/20] scsi: zfcp: fix erp_action use-before-initialize in REC action trace Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 13/20] scsi: sg: Re-fix off by one in sg_fill_request_table() Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 14/20] can: sun4i: fix loopback mode Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 15/20] can: kvaser_usb: Correct return value in printout Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 16/20] can: kvaser_usb: Ignore CMD_FLUSH_QUEUE_REPLY messages Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 17/20] regulator: fan53555: fix I2C device ids Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 18/20] x86/microcode/intel: Disable late loading on model 79 Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 19/20] ecryptfs: fix dereference of NULL user_key_payload Greg Kroah-Hartman
2017-10-31  9:55 ` [PATCH 4.4 20/20] [PATCH] Revert "drm: bridge: add DT bindings for TI ths8135" Greg Kroah-Hartman
2017-10-31 17:19 ` [PATCH 4.4 00/20] 4.4.96-stable review Guenter Roeck
2017-10-31 20:04 ` Shuah Khan
2017-10-31 21:33 ` Tom Gall
2017-11-01 15:22   ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171031095510.755397059@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=dhowells@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).