xref: /freebsd/contrib/unbound/util/fptr_wlist.h (revision 814bd1ed438f7dfc5bedcb1f3e772a46fe7026bb)
1 /*
2  * util/fptr_wlist.h - function pointer whitelists.
3  *
4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 /**
37  * \file
38  *
39  * This file contains functions that check function pointers.
40  * The functions contain a whitelist of known good callback values.
41  * Any other values lead to an error.
42  *
43  * This prevent heap overflow based exploits, where the callback pointer
44  * is overwritten by a buffer overflow (apart from this defense, buffer
45  * overflows should be fixed of course).
46  *
47  * Function pointers are used in
48  * 	o network code callbacks.
49  * 	o rbtree, lruhash, region data manipulation
50  *		in lruhash, the assertions are before the critical regions.
51  *		in other places, assertions are before the callback.
52  * 	o module operations.
53  */
54 
55 #ifndef UTIL_FPTR_WLIST_H
56 #define UTIL_FPTR_WLIST_H
57 #include "util/netevent.h"
58 #include "util/storage/lruhash.h"
59 #include "util/module.h"
60 #include "util/tube.h"
61 #include "services/mesh.h"
62 
63 /**
64  * Macro to perform an assertion check for fptr wlist checks.
65  * Does not get disabled in optimize mode. Check adds security by layers.
66  */
67 #if defined(EXPORT_ALL_SYMBOLS)
68 #define fptr_ok(x) /* nothing, dll-exe memory layout on win disables it */
69 #else
70 #define fptr_ok(x) \
71 	do { if(!(x)) \
72 		fatal_exit("%s:%d: %s: pointer whitelist %s failed", \
73 		__FILE__, __LINE__, __func__, #x); \
74 	} while(0);
75 #endif
76 
77 /**
78  * Check function pointer whitelist for comm_point callback values.
79  *
80  * @param fptr: function pointer to check.
81  * @return false if not in whitelist.
82  */
83 int fptr_whitelist_comm_point(comm_point_callback_type *fptr);
84 
85 /**
86  * Check function pointer whitelist for raw comm_point callback values.
87  *
88  * @param fptr: function pointer to check.
89  * @return false if not in whitelist.
90  */
91 int fptr_whitelist_comm_point_raw(comm_point_callback_type *fptr);
92 
93 /**
94  * Check function pointer whitelist for comm_timer callback values.
95  *
96  * @param fptr: function pointer to check.
97  * @return false if not in whitelist.
98  */
99 int fptr_whitelist_comm_timer(void (*fptr)(void*));
100 
101 /**
102  * Check function pointer whitelist for comm_signal callback values.
103  *
104  * @param fptr: function pointer to check.
105  * @return false if not in whitelist.
106  */
107 int fptr_whitelist_comm_signal(void (*fptr)(int, void*));
108 
109 /**
110  * Check function pointer whitelist for start_accept callback values.
111  *
112  * @param fptr: function pointer to check.
113  * @return false if not in whitelist.
114  */
115 int fptr_whitelist_start_accept(void (*fptr)(void*));
116 
117 /**
118  * Check function pointer whitelist for stop_accept callback values.
119  *
120  * @param fptr: function pointer to check.
121  * @return false if not in whitelist.
122  */
123 int fptr_whitelist_stop_accept(void (*fptr)(void*));
124 
125 /**
126  * Check function pointer whitelist for event structure callback values.
127  * This is not called by libevent itself, but checked by netevent.
128  *
129  * @param fptr: function pointer to check.
130  * @return false if not in whitelist.
131  */
132 int fptr_whitelist_event(void (*fptr)(int, short, void *));
133 
134 /**
135  * Check function pointer whitelist for pending udp callback values.
136  *
137  * @param fptr: function pointer to check.
138  * @return false if not in whitelist.
139  */
140 int fptr_whitelist_pending_udp(comm_point_callback_type *fptr);
141 
142 /**
143  * Check function pointer whitelist for pending tcp callback values.
144  *
145  * @param fptr: function pointer to check.
146  * @return false if not in whitelist.
147  */
148 int fptr_whitelist_pending_tcp(comm_point_callback_type *fptr);
149 
150 /**
151  * Check function pointer whitelist for serviced query callback values.
152  *
153  * @param fptr: function pointer to check.
154  * @return false if not in whitelist.
155  */
156 int fptr_whitelist_serviced_query(comm_point_callback_type *fptr);
157 
158 /**
159  * Check function pointer whitelist for rbtree cmp callback values.
160  *
161  * @param fptr: function pointer to check.
162  * @return false if not in whitelist.
163  */
164 int fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *));
165 
166 /**
167  * Check function pointer whitelist for lruhash sizefunc callback values.
168  *
169  * @param fptr: function pointer to check.
170  * @return false if not in whitelist.
171  */
172 int fptr_whitelist_hash_sizefunc(lruhash_sizefunc_type fptr);
173 
174 /**
175  * Check function pointer whitelist for lruhash compfunc callback values.
176  *
177  * @param fptr: function pointer to check.
178  * @return false if not in whitelist.
179  */
180 int fptr_whitelist_hash_compfunc(lruhash_compfunc_type fptr);
181 
182 /**
183  * Check function pointer whitelist for lruhash delkeyfunc callback values.
184  *
185  * @param fptr: function pointer to check.
186  * @return false if not in whitelist.
187  */
188 int fptr_whitelist_hash_delkeyfunc(lruhash_delkeyfunc_type fptr);
189 
190 /**
191  * Check function pointer whitelist for lruhash deldata callback values.
192  *
193  * @param fptr: function pointer to check.
194  * @return false if not in whitelist.
195  */
196 int fptr_whitelist_hash_deldatafunc(lruhash_deldatafunc_type fptr);
197 
198 /**
199  * Check function pointer whitelist for lruhash markdel callback values.
200  *
201  * @param fptr: function pointer to check.
202  * @return false if not in whitelist.
203  */
204 int fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_type fptr);
205 
206 /**
207  * Check function pointer whitelist for module_env send_query callback values.
208  *
209  * @param fptr: function pointer to check.
210  * @return false if not in whitelist.
211  */
212 int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
213 	struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
214 	int nocaps, int check_ratelimit, struct sockaddr_storage* addr,
215 	socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream,
216 	int ssl_upstream, char* tls_auth_name, struct module_qstate* q,
217 	int* was_ratelimited));
218 
219 /**
220  * Check function pointer whitelist for module_env detach_subs callback values.
221  *
222  * @param fptr: function pointer to check.
223  * @return false if not in whitelist.
224  */
225 int fptr_whitelist_modenv_detach_subs(void (*fptr)(
226 	struct module_qstate* qstate));
227 
228 /**
229  * Check function pointer whitelist for module_env attach_sub callback values.
230  *
231  * @param fptr: function pointer to check.
232  * @return false if not in whitelist.
233  */
234 int fptr_whitelist_modenv_attach_sub(int (*fptr)(
235 	struct module_qstate* qstate, struct query_info* qinfo,
236 	uint16_t qflags, int prime, int valrec, struct module_qstate** newq));
237 
238 /**
239  * Check function pointer whitelist for module_env add_sub callback values.
240  *
241  * @param fptr: function pointer to check.
242  * @return false if not in whitelist.
243  */
244 int fptr_whitelist_modenv_add_sub(int (*fptr)(struct module_qstate* qstate,
245 	struct query_info* qinfo, uint16_t qflags, int prime, int valrec,
246 	struct module_qstate** newq, struct mesh_state** sub));
247 /**
248  * Check function pointer whitelist for module_env kill_sub callback values.
249  *
250  * @param fptr: function pointer to check.
251  * @return false if not in whitelist.
252  */
253 int fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq));
254 
255 /**
256  * Check function pointer whitelist for module_env detect_cycle callback values.
257  *
258  * @param fptr: function pointer to check.
259  * @return false if not in whitelist.
260  */
261 int fptr_whitelist_modenv_detect_cycle(int (*fptr)(
262 	struct module_qstate* qstate, struct query_info* qinfo,
263 	uint16_t flags, int prime, int valrec));
264 
265 /**
266  * Check function pointer whitelist for module init call values.
267  *
268  * @param fptr: function pointer to check.
269  * @return false if not in whitelist.
270  */
271 int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id));
272 
273 /**
274  * Check function pointer whitelist for module deinit call values.
275  *
276  * @param fptr: function pointer to check.
277  * @return false if not in whitelist.
278  */
279 int fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id));
280 
281 /**
282  * Check function pointer whitelist for module operate call values.
283  *
284  * @param fptr: function pointer to check.
285  * @return false if not in whitelist.
286  */
287 int fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
288 	enum module_ev event, int id, struct outbound_entry* outbound));
289 
290 /**
291  * Check function pointer whitelist for module inform_super call values.
292  *
293  * @param fptr: function pointer to check.
294  * @return false if not in whitelist.
295  */
296 int fptr_whitelist_mod_inform_super(void (*fptr)(
297 	struct module_qstate* qstate, int id, struct module_qstate* super));
298 
299 /**
300  * Check function pointer whitelist for module clear call values.
301  *
302  * @param fptr: function pointer to check.
303  * @return false if not in whitelist.
304  */
305 int fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate,
306 	int id));
307 
308 /**
309  * Check function pointer whitelist for module get_mem call values.
310  *
311  * @param fptr: function pointer to check.
312  * @return false if not in whitelist.
313  */
314 int fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id));
315 
316 /**
317  * Check function pointer whitelist for alloc clear on id overflow call values.
318  *
319  * @param fptr: function pointer to check.
320  * @return false if not in whitelist.
321  */
322 int fptr_whitelist_alloc_cleanup(void (*fptr)(void*));
323 
324 /**
325  * Check function pointer whitelist for tube listen handler values.
326  *
327  * @param fptr: function pointer to check.
328  * @return false if not in whitelist.
329  */
330 int fptr_whitelist_tube_listen(tube_callback_type* fptr);
331 
332 /**
333  * Check function pointer whitelist for mesh state callback values.
334  *
335  * @param fptr: function pointer to check.
336  * @return false if not in whitelist.
337  */
338 int fptr_whitelist_mesh_cb(mesh_cb_func_type fptr);
339 
340 /**
341  * Check function pointer whitelist for config_get_option func values.
342  * @param fptr: function pointer to check.
343  * @return false if not in whitelist.
344  */
345 int fptr_whitelist_print_func(void (*fptr)(char*,void*));
346 
347 /**
348  * Check function pointer whitelist for inplace_cb_reply,
349  * inplace_cb_reply_cache, inplace_cb_reply_local and inplace_cb_reply_servfail
350  * func values.
351  * @param fptr: function pointer to check.
352  * @param type: the type of the callback function.
353  * @return false if not in whitelist.
354  */
355 int fptr_whitelist_inplace_cb_reply_generic(inplace_cb_reply_func_type* fptr,
356 	enum inplace_cb_list_type type);
357 
358 /**
359  * Check function pointer whitelist for inplace_cb_query func values.
360  * @param fptr: function pointer to check.
361  * @return false if not in whitelist.
362  */
363 int fptr_whitelist_inplace_cb_query(inplace_cb_query_func_type* fptr);
364 
365 /**
366  * Check function pointer whitelist for inplace_cb_edns_back_parsed func values.
367  * @param fptr: function pointer to check.
368  * @return false if not in whitelist.
369  */
370 int fptr_whitelist_inplace_cb_edns_back_parsed(
371 	inplace_cb_edns_back_parsed_func_type* fptr);
372 
373 /**
374  * Check function pointer whitelist for inplace_cb_query_response func values.
375  * @param fptr: function pointer to check.
376  * @return false if not in whitelist.
377  */
378 int fptr_whitelist_inplace_cb_query_response(
379 	inplace_cb_query_response_func_type* fptr);
380 
381 /**
382  * Check function pointer whitelist for serve_expired_lookup func values.
383  * @param fptr: function pointer to check.
384  * @return false if not in whitelist.
385  */
386 int fptr_whitelist_serve_expired_lookup(serve_expired_lookup_func_type* fptr);
387 
388 /** Due to module breakage by fptr wlist, these test app declarations
389  * are presented here */
390 /**
391  * compare two order_ids from lock-verify test app
392  * @param e1: first order_id
393  * @param e2: second order_id
394  * @return compare code -1, 0, +1 (like memcmp).
395  */
396 int order_lock_cmp(const void* e1, const void* e2);
397 
398 /**
399  * compare two codeline structs for rbtree from memstats test app
400  * @param a: codeline
401  * @param b: codeline
402  * @return compare code -1, 0, +1 (like memcmp).
403  */
404 int codeline_cmp(const void* a, const void* b);
405 
406 /** compare two replay_vars */
407 int replay_var_compare(const void* a, const void* b);
408 
409 #endif /* UTIL_FPTR_WLIST_H */
410