shadow.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include <linux/kmemcheck.h>
  2. #include <linux/module.h>
  3. #include <linux/mm.h>
  4. #include <linux/module.h>
  5. #include <asm/page.h>
  6. #include <asm/pgtable.h>
  7. #include "pte.h"
  8. #include "shadow.h"
  9. /*
  10. * Return the shadow address for the given address. Returns NULL if the
  11. * address is not tracked.
  12. *
  13. * We need to be extremely careful not to follow any invalid pointers,
  14. * because this function can be called for *any* possible address.
  15. */
  16. void *kmemcheck_shadow_lookup(unsigned long address)
  17. {
  18. pte_t *pte;
  19. struct page *page;
  20. if (!virt_addr_valid(address))
  21. return NULL;
  22. pte = kmemcheck_pte_lookup(address);
  23. if (!pte)
  24. return NULL;
  25. page = virt_to_page(address);
  26. if (!page->shadow)
  27. return NULL;
  28. return page->shadow + (address & (PAGE_SIZE - 1));
  29. }
  30. static void mark_shadow(void *address, unsigned int n,
  31. enum kmemcheck_shadow status)
  32. {
  33. unsigned long addr = (unsigned long) address;
  34. unsigned long last_addr = addr + n - 1;
  35. unsigned long page = addr & PAGE_MASK;
  36. unsigned long last_page = last_addr & PAGE_MASK;
  37. unsigned int first_n;
  38. void *shadow;
  39. /* If the memory range crosses a page boundary, stop there. */
  40. if (page == last_page)
  41. first_n = n;
  42. else
  43. first_n = page + PAGE_SIZE - addr;
  44. shadow = kmemcheck_shadow_lookup(addr);
  45. if (shadow)
  46. memset(shadow, status, first_n);
  47. addr += first_n;
  48. n -= first_n;
  49. /* Do full-page memset()s. */
  50. while (n >= PAGE_SIZE) {
  51. shadow = kmemcheck_shadow_lookup(addr);
  52. if (shadow)
  53. memset(shadow, status, PAGE_SIZE);
  54. addr += PAGE_SIZE;
  55. n -= PAGE_SIZE;
  56. }
  57. /* Do the remaining page, if any. */
  58. if (n > 0) {
  59. shadow = kmemcheck_shadow_lookup(addr);
  60. if (shadow)
  61. memset(shadow, status, n);
  62. }
  63. }
  64. void kmemcheck_mark_unallocated(void *address, unsigned int n)
  65. {
  66. mark_shadow(address, n, KMEMCHECK_SHADOW_UNALLOCATED);
  67. }
  68. void kmemcheck_mark_uninitialized(void *address, unsigned int n)
  69. {
  70. mark_shadow(address, n, KMEMCHECK_SHADOW_UNINITIALIZED);
  71. }
  72. /*
  73. * Fill the shadow memory of the given address such that the memory at that
  74. * address is marked as being initialized.
  75. */
  76. void kmemcheck_mark_initialized(void *address, unsigned int n)
  77. {
  78. mark_shadow(address, n, KMEMCHECK_SHADOW_INITIALIZED);
  79. }
  80. EXPORT_SYMBOL_GPL(kmemcheck_mark_initialized);
  81. void kmemcheck_mark_freed(void *address, unsigned int n)
  82. {
  83. mark_shadow(address, n, KMEMCHECK_SHADOW_FREED);
  84. }
  85. void kmemcheck_mark_unallocated_pages(struct page *p, unsigned int n)
  86. {
  87. unsigned int i;
  88. for (i = 0; i < n; ++i)
  89. kmemcheck_mark_unallocated(page_address(&p[i]), PAGE_SIZE);
  90. }
  91. void kmemcheck_mark_uninitialized_pages(struct page *p, unsigned int n)
  92. {
  93. unsigned int i;
  94. for (i = 0; i < n; ++i)
  95. kmemcheck_mark_uninitialized(page_address(&p[i]), PAGE_SIZE);
  96. }
  97. void kmemcheck_mark_initialized_pages(struct page *p, unsigned int n)
  98. {
  99. unsigned int i;
  100. for (i = 0; i < n; ++i)
  101. kmemcheck_mark_initialized(page_address(&p[i]), PAGE_SIZE);
  102. }
  103. enum kmemcheck_shadow kmemcheck_shadow_test(void *shadow, unsigned int size)
  104. {
  105. uint8_t *x;
  106. unsigned int i;
  107. x = shadow;
  108. #ifdef CONFIG_KMEMCHECK_PARTIAL_OK
  109. /*
  110. * Make sure _some_ bytes are initialized. Gcc frequently generates
  111. * code to access neighboring bytes.
  112. */
  113. for (i = 0; i < size; ++i) {
  114. if (x[i] == KMEMCHECK_SHADOW_INITIALIZED)
  115. return x[i];
  116. }
  117. #else
  118. /* All bytes must be initialized. */
  119. for (i = 0; i < size; ++i) {
  120. if (x[i] != KMEMCHECK_SHADOW_INITIALIZED)
  121. return x[i];
  122. }
  123. #endif
  124. return x[0];
  125. }
  126. void kmemcheck_shadow_set(void *shadow, unsigned int size)
  127. {
  128. uint8_t *x;
  129. unsigned int i;
  130. x = shadow;
  131. for (i = 0; i < size; ++i)
  132. x[i] = KMEMCHECK_SHADOW_INITIALIZED;
  133. }