aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/radix-tree/regression3.c
diff options
context:
space:
mode:
authorKonstantin Khlebnikov <koct9i@gmail.com>2016-03-17 17:22:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-17 18:09:34 -0400
commit2d6f45b802af7a15a0e455bcfad4009aa5e7b66b (patch)
tree168ed52e0dd19c10b2178015f66fe2e877e44f19 /tools/testing/radix-tree/regression3.c
parent7165092fe5ca70bae722ac6cd78421cfd0eec18d (diff)
radix-tree tests: add regression3 test
After calling radix_tree_iter_retry(), 'slot' will be set to NULL. This can cause radix_tree_next_slot() to dereference the NULL pointer. Add Konstantin Khlebnikov's test to the regression framework. Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com> Reported-by: Konstantin Khlebnikov <koct9i@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'tools/testing/radix-tree/regression3.c')
-rw-r--r--tools/testing/radix-tree/regression3.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/tools/testing/radix-tree/regression3.c b/tools/testing/radix-tree/regression3.c
new file mode 100644
index 000000000000..17d3ba5f4a0a
--- /dev/null
+++ b/tools/testing/radix-tree/regression3.c
@@ -0,0 +1,86 @@
1/*
2 * Regression3
3 * Description:
4 * Helper radix_tree_iter_retry resets next_index to the current index.
5 * In following radix_tree_next_slot current chunk size becomes zero.
6 * This isn't checked and it tries to dereference null pointer in slot.
7 *
8 * Running:
9 * This test should run to completion immediately. The above bug would
10 * cause it to segfault.
11 *
12 * Upstream commit:
13 * Not yet
14 */
15#include <linux/kernel.h>
16#include <linux/gfp.h>
17#include <linux/slab.h>
18#include <linux/radix-tree.h>
19#include <stdlib.h>
20#include <stdio.h>
21
22#include "regression.h"
23
24void regression3_test(void)
25{
26 RADIX_TREE(root, GFP_KERNEL);
27 void *ptr = (void *)4ul;
28 struct radix_tree_iter iter;
29 void **slot;
30 bool first;
31
32 printf("running regression test 3 (should take milliseconds)\n");
33
34 radix_tree_insert(&root, 0, ptr);
35 radix_tree_tag_set(&root, 0, 0);
36
37 first = true;
38 radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {
39// printk("tagged %ld %p\n", iter.index, *slot);
40 if (first) {
41 radix_tree_insert(&root, 1, ptr);
42 radix_tree_tag_set(&root, 1, 0);
43 first = false;
44 }
45 if (radix_tree_deref_retry(*slot)) {
46// printk("retry %ld\n", iter.index);
47 slot = radix_tree_iter_retry(&iter);
48 continue;
49 }
50 }
51 radix_tree_delete(&root, 1);
52
53 first = true;
54 radix_tree_for_each_slot(slot, &root, &iter, 0) {
55// printk("slot %ld %p\n", iter.index, *slot);
56 if (first) {
57 radix_tree_insert(&root, 1, ptr);
58 first = false;
59 }
60 if (radix_tree_deref_retry(*slot)) {
61// printk("retry %ld\n", iter.index);
62 slot = radix_tree_iter_retry(&iter);
63 continue;
64 }
65 }
66 radix_tree_delete(&root, 1);
67
68 first = true;
69 radix_tree_for_each_contig(slot, &root, &iter, 0) {
70// printk("contig %ld %p\n", iter.index, *slot);
71 if (first) {
72 radix_tree_insert(&root, 1, ptr);
73 first = false;
74 }
75 if (radix_tree_deref_retry(*slot)) {
76// printk("retry %ld\n", iter.index);
77 slot = radix_tree_iter_retry(&iter);
78 continue;
79 }
80 }
81
82 radix_tree_delete(&root, 0);
83 radix_tree_delete(&root, 1);
84
85 printf("regression test 3 passed\n");
86}