ptr_valid.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // Licensed under BSD-MIT: See LICENSE.
  2. #ifndef CCAN_PTR_VALID_H
  3. #define CCAN_PTR_VALID_H
  4. #include "config.h"
  5. #include <stdbool.h>
  6. #include <stdlib.h>
  7. /**
  8. * ptr_valid_read - can I safely read from a pointer?
  9. * @p: the proposed pointer.
  10. *
  11. * This function verifies that the pointer @p is safe to dereference for
  12. * reading. It is very slow, particularly if the answer is "no".
  13. *
  14. * Sets errno to EFAULT on failure.
  15. *
  16. * See Also:
  17. * ptr_valid_batch_read()
  18. */
  19. #define ptr_valid_read(p) \
  20. ptr_valid_r((p), PTR_VALID_ALIGNOF(*(p)), sizeof(*(p)))
  21. /**
  22. * ptr_valid_write - can I safely write to a pointer?
  23. * @p: the proposed pointer.
  24. *
  25. * This function verifies that the pointer @p is safe to dereference
  26. * for writing (and reading). It is very slow, particularly if the
  27. * answer is "no".
  28. *
  29. * Sets errno to EFAULT on failure.
  30. *
  31. * See Also:
  32. * ptr_valid_batch_write()
  33. */
  34. #define ptr_valid_write(p) \
  35. ptr_valid_w((p), PTR_VALID_ALIGNOF(*(p)), sizeof(*(p)))
  36. /**
  37. * ptr_valid_string - can I safely read a string?
  38. * @p: the proposed string.
  39. *
  40. * This function verifies that the pointer @p is safe to dereference
  41. * up to a nul character. It is very slow, particularly if the answer
  42. * is "no".
  43. *
  44. * Sets errno to EFAULT on failure.
  45. *
  46. * See Also:
  47. * ptr_valid_batch_string()
  48. */
  49. bool ptr_valid_string(const char *p);
  50. /**
  51. * ptr_valid - generic pointer check function
  52. * @p: the proposed pointer.
  53. * @align: the alignment requirements of the pointer.
  54. * @size: the size of the region @p should point to
  55. * @write: true if @p should be writable as well as readable.
  56. *
  57. * This function verifies that the pointer @p is safe to dereference.
  58. * It is very slow, particularly if the answer is "no".
  59. *
  60. * Sets errno to EFAULT on failure.
  61. *
  62. * See Also:
  63. * ptr_valid_batch()
  64. */
  65. bool ptr_valid(const void *p, size_t align, size_t size, bool write);
  66. /**
  67. * struct ptr_valid_batch - pointer to store state for batch ptr ops
  68. *
  69. * Treat as private.
  70. */
  71. struct ptr_valid_batch {
  72. unsigned int num_maps;
  73. struct ptr_valid_map *maps;
  74. int child_pid;
  75. int to_child, from_child;
  76. void *last;
  77. bool last_ok;
  78. };
  79. /**
  80. * ptr_valid_batch_start - prepare for a batch of ptr_valid checks.
  81. * @batch: an uninitialized ptr_valid_batch structure.
  82. *
  83. * This initializes @batch; this same @batch pointer can be reused
  84. * until the memory map changes (eg. via mmap(), munmap() or even
  85. * malloc() and free()).
  86. *
  87. * This is useful to check many pointers, because otherwise it can be
  88. * extremely slow.
  89. *
  90. * Example:
  91. * struct linked {
  92. * struct linked *next;
  93. * const char *str;
  94. * };
  95. *
  96. * static bool check_linked_carefully(struct linked *head)
  97. * {
  98. * struct ptr_valid_batch batch;
  99. * struct linked *old = head;
  100. * bool half = true;
  101. *
  102. * // If this fails, we can't check. Assume OK.
  103. * if (!ptr_valid_batch_start(&batch))
  104. * return true;
  105. *
  106. * while (head) {
  107. * if (!ptr_valid_batch_read(&batch, head))
  108. * goto fail;
  109. * if (!ptr_valid_batch_string(&batch, head->str))
  110. * goto fail;
  111. * // Loop detection; move old at half speed of head.
  112. * if (half)
  113. * old = old->next;
  114. * half = !half;
  115. * if (head == old) {
  116. * errno = ELOOP;
  117. * goto fail;
  118. * }
  119. * }
  120. * ptr_valid_batch_end(&batch);
  121. * return true;
  122. *
  123. * fail:
  124. * ptr_valid_batch_end(&batch);
  125. * return false;
  126. * }
  127. *
  128. * See Also:
  129. * ptr_valid_batch_stop()
  130. */
  131. bool ptr_valid_batch_start(struct ptr_valid_batch *batch);
  132. /**
  133. * ptr_valid_batch_read - can I safely read from a pointer?
  134. * @batch: the batch initialized by ptr_valid_batch_start().
  135. * @p: the proposed pointer.
  136. *
  137. * Batched version of ptr_valid_read().
  138. */
  139. #define ptr_valid_batch_read(batch, p) \
  140. ptr_valid_batch_r((batch), \
  141. (p), PTR_VALID_ALIGNOF(*(p)), sizeof(*(p)))
  142. /**
  143. * ptr_valid_batch_write - can I safely write to a pointer?
  144. * @batch: the batch initialized by ptr_valid_batch_start().
  145. * @p: the proposed pointer.
  146. *
  147. * Batched version of ptr_valid_write().
  148. */
  149. #define ptr_valid_batch_write(batch, p) \
  150. ptr_valid_batch_w((batch), \
  151. (p), PTR_VALID_ALIGNOF(*(p)), sizeof(*(p)))
  152. /**
  153. * ptr_valid_batch_string - can I safely read a string?
  154. * @batch: the batch initialized by ptr_valid_batch_start().
  155. * @p: the proposed string.
  156. *
  157. * Batched version of ptr_valid_string().
  158. */
  159. bool ptr_valid_batch_string(struct ptr_valid_batch *batch, const char *p);
  160. /**
  161. * ptr_valid_batch - generic batched pointer check function
  162. * @batch: the batch initialized by ptr_valid_batch_start().
  163. * @p: the proposed pointer.
  164. * @align: the alignment requirements of the pointer.
  165. * @size: the size of the region @p should point to
  166. * @write: true if @p should be writable as well as readable.
  167. *
  168. * Batched version of ptr_valid().
  169. */
  170. bool ptr_valid_batch(struct ptr_valid_batch *batch,
  171. const void *p, size_t alignment, size_t size, bool write);
  172. /**
  173. * ptr_valid_batch_end - end a batch of ptr_valid checks.
  174. * @batch: a ptr_valid_batch structure.
  175. *
  176. * This is used after all checks are complete.
  177. *
  178. * See Also:
  179. * ptr_valid_batch_start()
  180. */
  181. void ptr_valid_batch_end(struct ptr_valid_batch *batch);
  182. /* These wrappers get constness correct. */
  183. static inline bool ptr_valid_r(const void *p, size_t align, size_t size)
  184. {
  185. return ptr_valid(p, align, size, false);
  186. }
  187. static inline bool ptr_valid_w(void *p, size_t align, size_t size)
  188. {
  189. return ptr_valid(p, align, size, true);
  190. }
  191. static inline bool ptr_valid_batch_r(struct ptr_valid_batch *batch,
  192. const void *p, size_t align, size_t size)
  193. {
  194. return ptr_valid_batch(batch, p, align, size, false);
  195. }
  196. static inline bool ptr_valid_batch_w(struct ptr_valid_batch *batch,
  197. void *p, size_t align, size_t size)
  198. {
  199. return ptr_valid_batch(batch, p, align, size, true);
  200. }
  201. struct ptr_valid_map {
  202. const char *start, *end;
  203. bool is_write;
  204. };
  205. #if HAVE_ALIGNOF
  206. #define PTR_VALID_ALIGNOF(var) __alignof__(var)
  207. #else
  208. /* Can't check this... */
  209. #define PTR_VALID_ALIGNOF(var) 1
  210. #endif
  211. #endif /* CCAN_PTR_VALID_H */