From: Konstantin Khlebnikov Date: Fri, 5 Feb 2016 23:37:01 +0000 (-0800) Subject: radix-tree: fix oops after radix_tree_iter_retry X-Git-Tag: v4.1.12-92~150^2~233 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=96d1aa1f8064414f2bca9d61bed910530ddcbb4e;p=users%2Fjedix%2Flinux-maple.git radix-tree: fix oops after radix_tree_iter_retry Orabug: 23330822 [ Upstream commit 732042821cfa106b3c20b9780e4c60fee9d68900 ] Helper radix_tree_iter_retry() resets next_index to the current index. In following radix_tree_next_slot current chunk size becomes zero. This isn't checked and it tries to dereference null pointer in slot. Tagged iterator is fine because retry happens only at slot 0 where tag bitmask in iter->tags is filled with single bit. Fixes: 46437f9a554f ("radix-tree: fix race in gang lookup") Signed-off-by: Konstantin Khlebnikov Cc: Matthew Wilcox Cc: Hugh Dickins Cc: Ohad Ben-Cohen Cc: Jeremiah Mahler Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Sasha Levin (cherry picked from commit 42362e1f5a73d36fcaf3eb4950dfc17f633ea0d3) Signed-off-by: Dan Duval --- diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 1a2b2276ffb3..5d5174b59802 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -391,7 +391,7 @@ void **radix_tree_iter_retry(struct radix_tree_iter *iter) * @iter: pointer to radix tree iterator * Returns: current chunk size */ -static __always_inline unsigned +static __always_inline long radix_tree_chunk_size(struct radix_tree_iter *iter) { return iter->next_index - iter->index; @@ -425,9 +425,9 @@ radix_tree_next_slot(void **slot, struct radix_tree_iter *iter, unsigned flags) return slot + offset + 1; } } else { - unsigned size = radix_tree_chunk_size(iter) - 1; + long size = radix_tree_chunk_size(iter); - while (size--) { + while (--size > 0) { slot++; iter->index++; if (likely(*slot))