regression3.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Regression3
  4. * 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 abort
  11. * 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 would
  15. * cause it to segfault.
  16. *
  17. * Upstream commit:
  18. * Not yet
  19. */
  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. #include "regression.h"
  27. void regression3_test(void)
  28. {
  29. RADIX_TREE(root, GFP_KERNEL);
  30. void *ptr0 = (void *)4ul;
  31. void *ptr = (void *)8ul;
  32. struct radix_tree_iter iter;
  33. void **slot;
  34. bool first;
  35. printv(1, "running regression test 3 (should take milliseconds)\n");
  36. radix_tree_insert(&root, 0, ptr0);
  37. radix_tree_tag_set(&root, 0, 0);
  38. first = true;
  39. radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {
  40. printv(2, "tagged %ld %p\n", iter.index, *slot);
  41. if (first) {
  42. radix_tree_insert(&root, 1, ptr);
  43. radix_tree_tag_set(&root, 1, 0);
  44. first = false;
  45. }
  46. if (radix_tree_deref_retry(*slot)) {
  47. printv(2, "retry at %ld\n", iter.index);
  48. slot = radix_tree_iter_retry(&iter);
  49. continue;
  50. }
  51. }
  52. radix_tree_delete(&root, 1);
  53. first = true;
  54. radix_tree_for_each_slot(slot, &root, &iter, 0) {
  55. printv(2, "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. printv(2, "retry at %ld\n", iter.index);
  62. slot = radix_tree_iter_retry(&iter);
  63. continue;
  64. }
  65. }
  66. radix_tree_for_each_slot(slot, &root, &iter, 0) {
  67. printv(2, "slot %ld %p\n", iter.index, *slot);
  68. if (!iter.index) {
  69. printv(2, "next at %ld\n", iter.index);
  70. slot = radix_tree_iter_resume(slot, &iter);
  71. }
  72. }
  73. radix_tree_tag_set(&root, 0, 0);
  74. radix_tree_tag_set(&root, 1, 0);
  75. radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {
  76. printv(2, "tagged %ld %p\n", iter.index, *slot);
  77. if (!iter.index) {
  78. printv(2, "next at %ld\n", iter.index);
  79. slot = radix_tree_iter_resume(slot, &iter);
  80. }
  81. }
  82. radix_tree_delete(&root, 0);
  83. radix_tree_delete(&root, 1);
  84. printv(1, "regression test 3 passed\n");
  85. }