1 // Licensed under BSD-MIT: See LICENSE.
2 #ifndef CCAN_PTR_VALID_H
3 #define CCAN_PTR_VALID_H
9 * ptr_valid_read - can I safely read from a pointer?
10 * @p: the proposed pointer.
12 * This function verifies that the pointer @p is safe to dereference for
13 * reading. It is very slow, particularly if the answer is "no".
15 * Sets errno to EFAULT on failure.
18 * ptr_valid_batch_read()
20 #define ptr_valid_read(p) \
21 ptr_valid_r((p), PTR_VALID_ALIGNOF(*(p)), sizeof(*(p)))
24 * ptr_valid_write - can I safely write to a pointer?
25 * @p: the proposed pointer.
27 * This function verifies that the pointer @p is safe to dereference
28 * for writing (and reading). It is very slow, particularly if the
31 * Sets errno to EFAULT on failure.
34 * ptr_valid_batch_write()
36 #define ptr_valid_write(p) \
37 ptr_valid_w((p), PTR_VALID_ALIGNOF(*(p)), sizeof(*(p)))
40 * ptr_valid_string - can I safely read a string?
41 * @p: the proposed string.
43 * This function verifies that the pointer @p is safe to dereference
44 * up to a nul character. It is very slow, particularly if the answer
47 * Sets errno to EFAULT on failure.
50 * ptr_valid_batch_string()
52 bool ptr_valid_string(const char *p);
55 * ptr_valid - generic pointer check function
56 * @p: the proposed pointer.
57 * @align: the alignment requirements of the pointer.
58 * @size: the size of the region @p should point to
59 * @write: true if @p should be writable as well as readable.
61 * This function verifies that the pointer @p is safe to dereference.
62 * It is very slow, particularly if the answer is "no".
64 * Sets errno to EFAULT on failure.
69 bool ptr_valid(const void *p, size_t align, size_t size, bool write);
72 * struct ptr_valid_batch - pointer to store state for batch ptr ops
76 struct ptr_valid_batch {
77 unsigned int num_maps;
78 struct ptr_valid_map *maps;
80 int to_child, from_child;
86 * ptr_valid_batch_start - prepare for a batch of ptr_valid checks.
87 * @batch: an uninitialized ptr_valid_batch structure.
89 * This initializes @batch; this same @batch pointer can be reused
90 * until the memory map changes (eg. via mmap(), munmap() or even
91 * malloc() and free()).
93 * This is useful to check many pointers, because otherwise it can be
98 * struct linked *next;
102 * static bool check_linked_carefully(struct linked *head)
104 * struct ptr_valid_batch batch;
105 * struct linked *old = head;
108 * // If this fails, we can't check. Assume OK.
109 * if (!ptr_valid_batch_start(&batch))
113 * if (!ptr_valid_batch_read(&batch, head))
115 * if (!ptr_valid_batch_string(&batch, head->str))
117 * // Loop detection; move old at half speed of head.
126 * ptr_valid_batch_end(&batch);
130 * ptr_valid_batch_end(&batch);
135 * ptr_valid_batch_stop()
137 bool ptr_valid_batch_start(struct ptr_valid_batch *batch);
140 * ptr_valid_batch_read - can I safely read from a pointer?
141 * @batch: the batch initialized by ptr_valid_batch_start().
142 * @p: the proposed pointer.
144 * Batched version of ptr_valid_read().
146 #define ptr_valid_batch_read(batch, p) \
147 ptr_valid_batch_r((batch), \
148 (p), PTR_VALID_ALIGNOF(*(p)), sizeof(*(p)))
151 * ptr_valid_batch_write - can I safely write to a pointer?
152 * @batch: the batch initialized by ptr_valid_batch_start().
153 * @p: the proposed pointer.
155 * Batched version of ptr_valid_write().
157 #define ptr_valid_batch_write(batch, p) \
158 ptr_valid_batch_w((batch), \
159 (p), PTR_VALID_ALIGNOF(*(p)), sizeof(*(p)))
162 * ptr_valid_batch_string - can I safely read a string?
163 * @batch: the batch initialized by ptr_valid_batch_start().
164 * @p: the proposed string.
166 * Batched version of ptr_valid_string().
168 bool ptr_valid_batch_string(struct ptr_valid_batch *batch, const char *p);
171 * ptr_valid_batch - generic batched pointer check function
172 * @batch: the batch initialized by ptr_valid_batch_start().
173 * @p: the proposed pointer.
174 * @align: the alignment requirements of the pointer.
175 * @size: the size of the region @p should point to
176 * @write: true if @p should be writable as well as readable.
178 * Batched version of ptr_valid().
180 bool ptr_valid_batch(struct ptr_valid_batch *batch,
181 const void *p, size_t alignment, size_t size, bool write);
184 * ptr_valid_batch_end - end a batch of ptr_valid checks.
185 * @batch: a ptr_valid_batch structure.
187 * This is used after all checks are complete.
190 * ptr_valid_batch_start()
192 void ptr_valid_batch_end(struct ptr_valid_batch *batch);
195 /* These wrappers get constness correct. */
196 static inline bool ptr_valid_r(const void *p, size_t align, size_t size)
198 return ptr_valid(p, align, size, false);
201 static inline bool ptr_valid_w(void *p, size_t align, size_t size)
203 return ptr_valid(p, align, size, true);
206 static inline bool ptr_valid_batch_r(struct ptr_valid_batch *batch,
207 const void *p, size_t align, size_t size)
209 return ptr_valid_batch(batch, p, align, size, false);
212 static inline bool ptr_valid_batch_w(struct ptr_valid_batch *batch,
213 void *p, size_t align, size_t size)
215 return ptr_valid_batch(batch, p, align, size, true);
218 struct ptr_valid_map {
219 const char *start, *end;
224 #define PTR_VALID_ALIGNOF(var) __alignof__(var)
226 /* Can't check this... */
227 #define PTR_VALID_ALIGNOF(var) 1
229 #endif /* CCAN_PTR_VALID_H */