96 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Regression34 * Description:5 * Helper radix_tree_iter_retry resets next_index to the current index.6 * In following radix_tree_next_slot current chunk size becomes zero.7 * This isn't checked and it tries to dereference null pointer in slot.8 *9 * Helper radix_tree_iter_resume reset slot to NULL and next_index to index + 1,10 * for tagger iteraction it also must reset cached tags in iterator to abort11 * next radix_tree_next_slot and go to slow-path into radix_tree_next_chunk.12 *13 * Running:14 * This test should run to completion immediately. The above bug would15 * cause it to segfault.16 *17 * Upstream commit:18 * Not yet19 */20#include <linux/kernel.h>21#include <linux/gfp.h>22#include <linux/slab.h>23#include <linux/radix-tree.h>24#include <stdlib.h>25#include <stdio.h>26 27#include "regression.h"28 29void regression3_test(void)30{31 RADIX_TREE(root, GFP_KERNEL);32 void *ptr0 = (void *)4ul;33 void *ptr = (void *)8ul;34 struct radix_tree_iter iter;35 void **slot;36 bool first;37 38 printv(1, "running regression test 3 (should take milliseconds)\n");39 40 radix_tree_insert(&root, 0, ptr0);41 radix_tree_tag_set(&root, 0, 0);42 43 first = true;44 radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {45 printv(2, "tagged %ld %p\n", iter.index, *slot);46 if (first) {47 radix_tree_insert(&root, 1, ptr);48 radix_tree_tag_set(&root, 1, 0);49 first = false;50 }51 if (radix_tree_deref_retry(*slot)) {52 printv(2, "retry at %ld\n", iter.index);53 slot = radix_tree_iter_retry(&iter);54 continue;55 }56 }57 radix_tree_delete(&root, 1);58 59 first = true;60 radix_tree_for_each_slot(slot, &root, &iter, 0) {61 printv(2, "slot %ld %p\n", iter.index, *slot);62 if (first) {63 radix_tree_insert(&root, 1, ptr);64 first = false;65 }66 if (radix_tree_deref_retry(*slot)) {67 printv(2, "retry at %ld\n", iter.index);68 slot = radix_tree_iter_retry(&iter);69 continue;70 }71 }72 73 radix_tree_for_each_slot(slot, &root, &iter, 0) {74 printv(2, "slot %ld %p\n", iter.index, *slot);75 if (!iter.index) {76 printv(2, "next at %ld\n", iter.index);77 slot = radix_tree_iter_resume(slot, &iter);78 }79 }80 81 radix_tree_tag_set(&root, 0, 0);82 radix_tree_tag_set(&root, 1, 0);83 radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {84 printv(2, "tagged %ld %p\n", iter.index, *slot);85 if (!iter.index) {86 printv(2, "next at %ld\n", iter.index);87 slot = radix_tree_iter_resume(slot, &iter);88 }89 }90 91 radix_tree_delete(&root, 0);92 radix_tree_delete(&root, 1);93 94 printv(1, "regression test 3 passed\n");95}96