regression3.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. * Helper radix_tree_iter_next reset slot to NULL and next_index to index + 1,
  9. * for tagger iteraction it also must reset cached tags in iterator to abort
  10. * next radix_tree_next_slot and go to slow-path into radix_tree_next_chunk.
  11. *
  12. * Running:
  13. * This test should run to completion immediately. The above bug would
  14. * cause it to segfault.
  15. *
  16. * Upstream commit:
  17. * Not yet
  18. */
  19. #include <linux/kernel.h>
  20. #include <linux/gfp.h>
  21. #include <linux/slab.h>
  22. #include <linux/radix-tree.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include "regression.h"
  26. void regression3_test(void)
  27. {
  28. RADIX_TREE(root, GFP_KERNEL);
  29. void *ptr0 = (void *)4ul;
  30. void *ptr = (void *)8ul;
  31. struct radix_tree_iter iter;
  32. void **slot;
  33. bool first;
  34. printf("running regression test 3 (should take milliseconds)\n");
  35. radix_tree_insert(&root, 0, ptr0);
  36. radix_tree_tag_set(&root, 0, 0);
  37. first = true;
  38. radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {
  39. printf("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. printf("retry at %ld\n", iter.index);
  47. slot = radix_tree_iter_retry(&iter);
  48. continue;
  49. }
  50. }
  51. radix_tree_delete(&root, 1);
  52. first = true;
  53. radix_tree_for_each_slot(slot, &root, &iter, 0) {
  54. printf("slot %ld %p\n", iter.index, *slot);
  55. if (first) {
  56. radix_tree_insert(&root, 1, ptr);
  57. first = false;
  58. }
  59. if (radix_tree_deref_retry(*slot)) {
  60. printk("retry at %ld\n", iter.index);
  61. slot = radix_tree_iter_retry(&iter);
  62. continue;
  63. }
  64. }
  65. radix_tree_delete(&root, 1);
  66. first = true;
  67. radix_tree_for_each_contig(slot, &root, &iter, 0) {
  68. printk("contig %ld %p\n", iter.index, *slot);
  69. if (first) {
  70. radix_tree_insert(&root, 1, ptr);
  71. first = false;
  72. }
  73. if (radix_tree_deref_retry(*slot)) {
  74. printk("retry at %ld\n", iter.index);
  75. slot = radix_tree_iter_retry(&iter);
  76. continue;
  77. }
  78. }
  79. radix_tree_for_each_slot(slot, &root, &iter, 0) {
  80. printf("slot %ld %p\n", iter.index, *slot);
  81. if (!iter.index) {
  82. printf("next at %ld\n", iter.index);
  83. slot = radix_tree_iter_next(&iter);
  84. }
  85. }
  86. radix_tree_for_each_contig(slot, &root, &iter, 0) {
  87. printf("contig %ld %p\n", iter.index, *slot);
  88. if (!iter.index) {
  89. printf("next at %ld\n", iter.index);
  90. slot = radix_tree_iter_next(&iter);
  91. }
  92. }
  93. radix_tree_tag_set(&root, 0, 0);
  94. radix_tree_tag_set(&root, 1, 0);
  95. radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {
  96. printf("tagged %ld %p\n", iter.index, *slot);
  97. if (!iter.index) {
  98. printf("next at %ld\n", iter.index);
  99. slot = radix_tree_iter_next(&iter);
  100. }
  101. }
  102. radix_tree_delete(&root, 0);
  103. radix_tree_delete(&root, 1);
  104. printf("regression test 3 passed\n");
  105. }