diff options
author | Paul Gortmaker <paul.gortmaker@windriver.com> | 2018-02-23 13:56:45 -0500 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2018-02-28 16:19:31 -0500 |
commit | 970f842fde372eba690f7a154635a67531cda804 (patch) | |
tree | f02d37e9c4e7db9aac9cf26d551cdedf2f35b5d5 | |
parent | 2b30f5c8dcf09ff6f4211fb8d65a951d2d92a3f0 (diff) | |
download | longterm-queue-4.8-970f842fde372eba690f7a154635a67531cda804.tar.gz |
add CVE-2017-12193 fix
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r-- | queue/assoc_array-Fix-a-buggy-node-splitting-case.patch | 121 | ||||
-rw-r--r-- | queue/series | 2 |
2 files changed, 123 insertions, 0 deletions
diff --git a/queue/assoc_array-Fix-a-buggy-node-splitting-case.patch b/queue/assoc_array-Fix-a-buggy-node-splitting-case.patch new file mode 100644 index 0000000..3b7fc0e --- /dev/null +++ b/queue/assoc_array-Fix-a-buggy-node-splitting-case.patch @@ -0,0 +1,121 @@ +From ea6789980fdaa610d7eb63602c746bf6ec70cd2b Mon Sep 17 00:00:00 2001 +From: David Howells <dhowells@redhat.com> +Date: Wed, 11 Oct 2017 23:32:27 +0100 +Subject: [PATCH] assoc_array: Fix a buggy node-splitting case + +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> +Cc: stable@vger.kernel.org [v3.13-rc1+] +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +diff --git a/lib/assoc_array.c b/lib/assoc_array.c +index 155c55d8db5f..4e53be8bc590 100644 +--- a/lib/assoc_array.c ++++ b/lib/assoc_array.c +@@ -598,21 +598,31 @@ static bool assoc_array_insert_into_terminal_node(struct assoc_array_edit *edit, + 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 +-- +2.15.0 + diff --git a/queue/series b/queue/series new file mode 100644 index 0000000..9aa0e96 --- /dev/null +++ b/queue/series @@ -0,0 +1,2 @@ +# v4.14-rc7~7 +assoc_array-Fix-a-buggy-node-splitting-case.patch |