regression3.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. #include "regression.h"
  22. void regression3_test(void)
  23. {
  24. RADIX_TREE(root, GFP_KERNEL);
  25. void *ptr = (void *)4ul;
  26. struct radix_tree_iter iter;
  27. void **slot;
  28. bool first;
  29. printf("running regression test 3 (should take milliseconds)\n");
  30. radix_tree_insert(&root, 0, ptr);
  31. radix_tree_tag_set(&root, 0, 0);
  32. first = true;
  33. radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) {
  34. // printk("tagged %ld %p\n", iter.index, *slot);
  35. if (first) {
  36. radix_tree_insert(&root, 1, ptr);
  37. radix_tree_tag_set(&root, 1, 0);
  38. first = false;
  39. }
  40. if (radix_tree_deref_retry(*slot)) {
  41. // printk("retry %ld\n", iter.index);
  42. slot = radix_tree_iter_retry(&iter);
  43. continue;
  44. }
  45. }
  46. radix_tree_delete(&root, 1);
  47. first = true;
  48. radix_tree_for_each_slot(slot, &root, &iter, 0) {
  49. // printk("slot %ld %p\n", iter.index, *slot);
  50. if (first) {
  51. radix_tree_insert(&root, 1, ptr);
  52. first = false;
  53. }
  54. if (radix_tree_deref_retry(*slot)) {
  55. // printk("retry %ld\n", iter.index);
  56. slot = radix_tree_iter_retry(&iter);
  57. continue;
  58. }
  59. }
  60. radix_tree_delete(&root, 1);
  61. first = true;
  62. radix_tree_for_each_contig(slot, &root, &iter, 0) {
  63. // printk("contig %ld %p\n", iter.index, *slot);
  64. if (first) {
  65. radix_tree_insert(&root, 1, ptr);
  66. first = false;
  67. }
  68. if (radix_tree_deref_retry(*slot)) {
  69. // printk("retry %ld\n", iter.index);
  70. slot = radix_tree_iter_retry(&iter);
  71. continue;
  72. }
  73. }
  74. radix_tree_delete(&root, 0);
  75. radix_tree_delete(&root, 1);
  76. printf("regression test 3 passed\n");
  77. }