13b6c3722Schristos /* 23b6c3722Schristos * util/fptr_wlist.h - function pointer whitelists. 33b6c3722Schristos * 43b6c3722Schristos * Copyright (c) 2007, NLnet Labs. All rights reserved. 53b6c3722Schristos * 63b6c3722Schristos * This software is open source. 73b6c3722Schristos * 83b6c3722Schristos * Redistribution and use in source and binary forms, with or without 93b6c3722Schristos * modification, are permitted provided that the following conditions 103b6c3722Schristos * are met: 113b6c3722Schristos * 123b6c3722Schristos * Redistributions of source code must retain the above copyright notice, 133b6c3722Schristos * this list of conditions and the following disclaimer. 143b6c3722Schristos * 153b6c3722Schristos * Redistributions in binary form must reproduce the above copyright notice, 163b6c3722Schristos * this list of conditions and the following disclaimer in the documentation 173b6c3722Schristos * and/or other materials provided with the distribution. 183b6c3722Schristos * 193b6c3722Schristos * Neither the name of the NLNET LABS nor the names of its contributors may 203b6c3722Schristos * be used to endorse or promote products derived from this software without 213b6c3722Schristos * specific prior written permission. 223b6c3722Schristos * 233b6c3722Schristos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 243b6c3722Schristos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 253b6c3722Schristos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 263b6c3722Schristos * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 273b6c3722Schristos * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 283b6c3722Schristos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 293b6c3722Schristos * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 303b6c3722Schristos * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 313b6c3722Schristos * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 323b6c3722Schristos * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 333b6c3722Schristos * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 343b6c3722Schristos */ 353b6c3722Schristos 363b6c3722Schristos /** 373b6c3722Schristos * \file 383b6c3722Schristos * 393b6c3722Schristos * This file contains functions that check function pointers. 403b6c3722Schristos * The functions contain a whitelist of known good callback values. 413b6c3722Schristos * Any other values lead to an error. 423b6c3722Schristos * 433b6c3722Schristos * This prevent heap overflow based exploits, where the callback pointer 443b6c3722Schristos * is overwritten by a buffer overflow (apart from this defense, buffer 453b6c3722Schristos * overflows should be fixed of course). 463b6c3722Schristos * 473b6c3722Schristos * Function pointers are used in 483b6c3722Schristos * o network code callbacks. 493b6c3722Schristos * o rbtree, lruhash, region data manipulation 503b6c3722Schristos * in lruhash, the assertions are before the critical regions. 513b6c3722Schristos * in other places, assertions are before the callback. 523b6c3722Schristos * o module operations. 533b6c3722Schristos */ 543b6c3722Schristos 553b6c3722Schristos #ifndef UTIL_FPTR_WLIST_H 563b6c3722Schristos #define UTIL_FPTR_WLIST_H 573b6c3722Schristos #include "util/netevent.h" 583b6c3722Schristos #include "util/storage/lruhash.h" 593b6c3722Schristos #include "util/module.h" 603b6c3722Schristos #include "util/tube.h" 613b6c3722Schristos #include "services/mesh.h" 623b6c3722Schristos 633b6c3722Schristos /** 643b6c3722Schristos * Macro to perform an assertion check for fptr wlist checks. 653b6c3722Schristos * Does not get disabled in optimize mode. Check adds security by layers. 663b6c3722Schristos */ 673b6c3722Schristos #if defined(EXPORT_ALL_SYMBOLS) 683b6c3722Schristos #define fptr_ok(x) /* nothing, dll-exe memory layout on win disables it */ 693b6c3722Schristos #else 703b6c3722Schristos #define fptr_ok(x) \ 713b6c3722Schristos do { if(!(x)) \ 723b6c3722Schristos fatal_exit("%s:%d: %s: pointer whitelist %s failed", \ 733b6c3722Schristos __FILE__, __LINE__, __func__, #x); \ 743b6c3722Schristos } while(0); 753b6c3722Schristos #endif 763b6c3722Schristos 773b6c3722Schristos /** 783b6c3722Schristos * Check function pointer whitelist for comm_point callback values. 793b6c3722Schristos * 803b6c3722Schristos * @param fptr: function pointer to check. 813b6c3722Schristos * @return false if not in whitelist. 823b6c3722Schristos */ 830cd9f4ecSchristos int fptr_whitelist_comm_point(comm_point_callback_type *fptr); 843b6c3722Schristos 853b6c3722Schristos /** 863b6c3722Schristos * Check function pointer whitelist for raw comm_point callback values. 873b6c3722Schristos * 883b6c3722Schristos * @param fptr: function pointer to check. 893b6c3722Schristos * @return false if not in whitelist. 903b6c3722Schristos */ 910cd9f4ecSchristos int fptr_whitelist_comm_point_raw(comm_point_callback_type *fptr); 923b6c3722Schristos 933b6c3722Schristos /** 943b6c3722Schristos * Check function pointer whitelist for comm_timer callback values. 953b6c3722Schristos * 963b6c3722Schristos * @param fptr: function pointer to check. 973b6c3722Schristos * @return false if not in whitelist. 983b6c3722Schristos */ 993b6c3722Schristos int fptr_whitelist_comm_timer(void (*fptr)(void*)); 1003b6c3722Schristos 1013b6c3722Schristos /** 1023b6c3722Schristos * Check function pointer whitelist for comm_signal callback values. 1033b6c3722Schristos * 1043b6c3722Schristos * @param fptr: function pointer to check. 1053b6c3722Schristos * @return false if not in whitelist. 1063b6c3722Schristos */ 1073b6c3722Schristos int fptr_whitelist_comm_signal(void (*fptr)(int, void*)); 1083b6c3722Schristos 1093b6c3722Schristos /** 1103b6c3722Schristos * Check function pointer whitelist for start_accept callback values. 1113b6c3722Schristos * 1123b6c3722Schristos * @param fptr: function pointer to check. 1133b6c3722Schristos * @return false if not in whitelist. 1143b6c3722Schristos */ 1153b6c3722Schristos int fptr_whitelist_start_accept(void (*fptr)(void*)); 1163b6c3722Schristos 1173b6c3722Schristos /** 1183b6c3722Schristos * Check function pointer whitelist for stop_accept callback values. 1193b6c3722Schristos * 1203b6c3722Schristos * @param fptr: function pointer to check. 1213b6c3722Schristos * @return false if not in whitelist. 1223b6c3722Schristos */ 1233b6c3722Schristos int fptr_whitelist_stop_accept(void (*fptr)(void*)); 1243b6c3722Schristos 1253b6c3722Schristos /** 1263b6c3722Schristos * Check function pointer whitelist for event structure callback values. 1273b6c3722Schristos * This is not called by libevent itself, but checked by netevent. 1283b6c3722Schristos * 1293b6c3722Schristos * @param fptr: function pointer to check. 1303b6c3722Schristos * @return false if not in whitelist. 1313b6c3722Schristos */ 1323b6c3722Schristos int fptr_whitelist_event(void (*fptr)(int, short, void *)); 1333b6c3722Schristos 1343b6c3722Schristos /** 1353b6c3722Schristos * Check function pointer whitelist for pending udp callback values. 1363b6c3722Schristos * 1373b6c3722Schristos * @param fptr: function pointer to check. 1383b6c3722Schristos * @return false if not in whitelist. 1393b6c3722Schristos */ 1400cd9f4ecSchristos int fptr_whitelist_pending_udp(comm_point_callback_type *fptr); 1413b6c3722Schristos 1423b6c3722Schristos /** 1433b6c3722Schristos * Check function pointer whitelist for pending tcp callback values. 1443b6c3722Schristos * 1453b6c3722Schristos * @param fptr: function pointer to check. 1463b6c3722Schristos * @return false if not in whitelist. 1473b6c3722Schristos */ 1480cd9f4ecSchristos int fptr_whitelist_pending_tcp(comm_point_callback_type *fptr); 1493b6c3722Schristos 1503b6c3722Schristos /** 1513b6c3722Schristos * Check function pointer whitelist for serviced query callback values. 1523b6c3722Schristos * 1533b6c3722Schristos * @param fptr: function pointer to check. 1543b6c3722Schristos * @return false if not in whitelist. 1553b6c3722Schristos */ 1560cd9f4ecSchristos int fptr_whitelist_serviced_query(comm_point_callback_type *fptr); 1573b6c3722Schristos 1583b6c3722Schristos /** 1593b6c3722Schristos * Check function pointer whitelist for rbtree cmp callback values. 1603b6c3722Schristos * 1613b6c3722Schristos * @param fptr: function pointer to check. 1623b6c3722Schristos * @return false if not in whitelist. 1633b6c3722Schristos */ 1643b6c3722Schristos int fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *)); 1653b6c3722Schristos 1663b6c3722Schristos /** 1673b6c3722Schristos * Check function pointer whitelist for lruhash sizefunc callback values. 1683b6c3722Schristos * 1693b6c3722Schristos * @param fptr: function pointer to check. 1703b6c3722Schristos * @return false if not in whitelist. 1713b6c3722Schristos */ 1720cd9f4ecSchristos int fptr_whitelist_hash_sizefunc(lruhash_sizefunc_type fptr); 1733b6c3722Schristos 1743b6c3722Schristos /** 1753b6c3722Schristos * Check function pointer whitelist for lruhash compfunc callback values. 1763b6c3722Schristos * 1773b6c3722Schristos * @param fptr: function pointer to check. 1783b6c3722Schristos * @return false if not in whitelist. 1793b6c3722Schristos */ 1800cd9f4ecSchristos int fptr_whitelist_hash_compfunc(lruhash_compfunc_type fptr); 1813b6c3722Schristos 1823b6c3722Schristos /** 1833b6c3722Schristos * Check function pointer whitelist for lruhash delkeyfunc callback values. 1843b6c3722Schristos * 1853b6c3722Schristos * @param fptr: function pointer to check. 1863b6c3722Schristos * @return false if not in whitelist. 1873b6c3722Schristos */ 1880cd9f4ecSchristos int fptr_whitelist_hash_delkeyfunc(lruhash_delkeyfunc_type fptr); 1893b6c3722Schristos 1903b6c3722Schristos /** 1913b6c3722Schristos * Check function pointer whitelist for lruhash deldata callback values. 1923b6c3722Schristos * 1933b6c3722Schristos * @param fptr: function pointer to check. 1943b6c3722Schristos * @return false if not in whitelist. 1953b6c3722Schristos */ 1960cd9f4ecSchristos int fptr_whitelist_hash_deldatafunc(lruhash_deldatafunc_type fptr); 1973b6c3722Schristos 1983b6c3722Schristos /** 1993b6c3722Schristos * Check function pointer whitelist for lruhash markdel callback values. 2003b6c3722Schristos * 2013b6c3722Schristos * @param fptr: function pointer to check. 2023b6c3722Schristos * @return false if not in whitelist. 2033b6c3722Schristos */ 2040cd9f4ecSchristos int fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_type fptr); 2053b6c3722Schristos 2063b6c3722Schristos /** 2073b6c3722Schristos * Check function pointer whitelist for module_env send_query callback values. 2083b6c3722Schristos * 2093b6c3722Schristos * @param fptr: function pointer to check. 2103b6c3722Schristos * @return false if not in whitelist. 2113b6c3722Schristos */ 2123b6c3722Schristos int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)( 2130cd9f4ecSchristos struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec, 214*7a540f2bSchristos int nocaps, int check_ratelimit, struct sockaddr_storage* addr, 215*7a540f2bSchristos socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream, 216*7a540f2bSchristos int ssl_upstream, char* tls_auth_name, struct module_qstate* q, 217*7a540f2bSchristos int* was_ratelimited)); 2183b6c3722Schristos 2193b6c3722Schristos /** 2203b6c3722Schristos * Check function pointer whitelist for module_env detach_subs callback values. 2213b6c3722Schristos * 2223b6c3722Schristos * @param fptr: function pointer to check. 2233b6c3722Schristos * @return false if not in whitelist. 2243b6c3722Schristos */ 2253b6c3722Schristos int fptr_whitelist_modenv_detach_subs(void (*fptr)( 2263b6c3722Schristos struct module_qstate* qstate)); 2273b6c3722Schristos 2283b6c3722Schristos /** 2293b6c3722Schristos * Check function pointer whitelist for module_env attach_sub callback values. 2303b6c3722Schristos * 2313b6c3722Schristos * @param fptr: function pointer to check. 2323b6c3722Schristos * @return false if not in whitelist. 2333b6c3722Schristos */ 2343b6c3722Schristos int fptr_whitelist_modenv_attach_sub(int (*fptr)( 2353b6c3722Schristos struct module_qstate* qstate, struct query_info* qinfo, 2363b6c3722Schristos uint16_t qflags, int prime, int valrec, struct module_qstate** newq)); 2373b6c3722Schristos 2383b6c3722Schristos /** 2390cd9f4ecSchristos * Check function pointer whitelist for module_env add_sub callback values. 2400cd9f4ecSchristos * 2410cd9f4ecSchristos * @param fptr: function pointer to check. 2420cd9f4ecSchristos * @return false if not in whitelist. 2430cd9f4ecSchristos */ 2440cd9f4ecSchristos int fptr_whitelist_modenv_add_sub(int (*fptr)(struct module_qstate* qstate, 2450cd9f4ecSchristos struct query_info* qinfo, uint16_t qflags, int prime, int valrec, 2460cd9f4ecSchristos struct module_qstate** newq, struct mesh_state** sub)); 2470cd9f4ecSchristos /** 2483b6c3722Schristos * Check function pointer whitelist for module_env kill_sub callback values. 2493b6c3722Schristos * 2503b6c3722Schristos * @param fptr: function pointer to check. 2513b6c3722Schristos * @return false if not in whitelist. 2523b6c3722Schristos */ 2533b6c3722Schristos int fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq)); 2543b6c3722Schristos 2553b6c3722Schristos /** 2563b6c3722Schristos * Check function pointer whitelist for module_env detect_cycle callback values. 2573b6c3722Schristos * 2583b6c3722Schristos * @param fptr: function pointer to check. 2593b6c3722Schristos * @return false if not in whitelist. 2603b6c3722Schristos */ 2613b6c3722Schristos int fptr_whitelist_modenv_detect_cycle(int (*fptr)( 2623b6c3722Schristos struct module_qstate* qstate, struct query_info* qinfo, 2633b6c3722Schristos uint16_t flags, int prime, int valrec)); 2643b6c3722Schristos 2653b6c3722Schristos /** 2663b6c3722Schristos * Check function pointer whitelist for module init call values. 2673b6c3722Schristos * 2683b6c3722Schristos * @param fptr: function pointer to check. 2693b6c3722Schristos * @return false if not in whitelist. 2703b6c3722Schristos */ 2713b6c3722Schristos int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id)); 2723b6c3722Schristos 2733b6c3722Schristos /** 2743b6c3722Schristos * Check function pointer whitelist for module deinit call values. 2753b6c3722Schristos * 2763b6c3722Schristos * @param fptr: function pointer to check. 2773b6c3722Schristos * @return false if not in whitelist. 2783b6c3722Schristos */ 2793b6c3722Schristos int fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id)); 2803b6c3722Schristos 2813b6c3722Schristos /** 2823b6c3722Schristos * Check function pointer whitelist for module operate call values. 2833b6c3722Schristos * 2843b6c3722Schristos * @param fptr: function pointer to check. 2853b6c3722Schristos * @return false if not in whitelist. 2863b6c3722Schristos */ 2873b6c3722Schristos int fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate, 2883b6c3722Schristos enum module_ev event, int id, struct outbound_entry* outbound)); 2893b6c3722Schristos 2903b6c3722Schristos /** 2913b6c3722Schristos * Check function pointer whitelist for module inform_super call values. 2923b6c3722Schristos * 2933b6c3722Schristos * @param fptr: function pointer to check. 2943b6c3722Schristos * @return false if not in whitelist. 2953b6c3722Schristos */ 2963b6c3722Schristos int fptr_whitelist_mod_inform_super(void (*fptr)( 2973b6c3722Schristos struct module_qstate* qstate, int id, struct module_qstate* super)); 2983b6c3722Schristos 2993b6c3722Schristos /** 3003b6c3722Schristos * Check function pointer whitelist for module clear call values. 3013b6c3722Schristos * 3023b6c3722Schristos * @param fptr: function pointer to check. 3033b6c3722Schristos * @return false if not in whitelist. 3043b6c3722Schristos */ 3053b6c3722Schristos int fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate, 3063b6c3722Schristos int id)); 3073b6c3722Schristos 3083b6c3722Schristos /** 3093b6c3722Schristos * Check function pointer whitelist for module get_mem call values. 3103b6c3722Schristos * 3113b6c3722Schristos * @param fptr: function pointer to check. 3123b6c3722Schristos * @return false if not in whitelist. 3133b6c3722Schristos */ 3143b6c3722Schristos int fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id)); 3153b6c3722Schristos 3163b6c3722Schristos /** 3173b6c3722Schristos * Check function pointer whitelist for alloc clear on id overflow call values. 3183b6c3722Schristos * 3193b6c3722Schristos * @param fptr: function pointer to check. 3203b6c3722Schristos * @return false if not in whitelist. 3213b6c3722Schristos */ 3223b6c3722Schristos int fptr_whitelist_alloc_cleanup(void (*fptr)(void*)); 3233b6c3722Schristos 3243b6c3722Schristos /** 3253b6c3722Schristos * Check function pointer whitelist for tube listen handler values. 3263b6c3722Schristos * 3273b6c3722Schristos * @param fptr: function pointer to check. 3283b6c3722Schristos * @return false if not in whitelist. 3293b6c3722Schristos */ 3300cd9f4ecSchristos int fptr_whitelist_tube_listen(tube_callback_type* fptr); 3313b6c3722Schristos 3323b6c3722Schristos /** 3333b6c3722Schristos * Check function pointer whitelist for mesh state callback values. 3343b6c3722Schristos * 3353b6c3722Schristos * @param fptr: function pointer to check. 3363b6c3722Schristos * @return false if not in whitelist. 3373b6c3722Schristos */ 3380cd9f4ecSchristos int fptr_whitelist_mesh_cb(mesh_cb_func_type fptr); 3393b6c3722Schristos 3403b6c3722Schristos /** 3413b6c3722Schristos * Check function pointer whitelist for config_get_option func values. 3423b6c3722Schristos * @param fptr: function pointer to check. 3433b6c3722Schristos * @return false if not in whitelist. 3443b6c3722Schristos */ 3453b6c3722Schristos int fptr_whitelist_print_func(void (*fptr)(char*,void*)); 3463b6c3722Schristos 3470cd9f4ecSchristos /** 3480cd9f4ecSchristos * Check function pointer whitelist for inplace_cb_reply, 3490cd9f4ecSchristos * inplace_cb_reply_cache, inplace_cb_reply_local and inplace_cb_reply_servfail 3500cd9f4ecSchristos * func values. 3510cd9f4ecSchristos * @param fptr: function pointer to check. 3520cd9f4ecSchristos * @param type: the type of the callback function. 3530cd9f4ecSchristos * @return false if not in whitelist. 3540cd9f4ecSchristos */ 3550cd9f4ecSchristos int fptr_whitelist_inplace_cb_reply_generic(inplace_cb_reply_func_type* fptr, 3560cd9f4ecSchristos enum inplace_cb_list_type type); 3570cd9f4ecSchristos 3580cd9f4ecSchristos /** 3590cd9f4ecSchristos * Check function pointer whitelist for inplace_cb_query func values. 3600cd9f4ecSchristos * @param fptr: function pointer to check. 3610cd9f4ecSchristos * @return false if not in whitelist. 3620cd9f4ecSchristos */ 3630cd9f4ecSchristos int fptr_whitelist_inplace_cb_query(inplace_cb_query_func_type* fptr); 3640cd9f4ecSchristos 3650cd9f4ecSchristos /** 3660cd9f4ecSchristos * Check function pointer whitelist for inplace_cb_edns_back_parsed func values. 3670cd9f4ecSchristos * @param fptr: function pointer to check. 3680cd9f4ecSchristos * @return false if not in whitelist. 3690cd9f4ecSchristos */ 3700cd9f4ecSchristos int fptr_whitelist_inplace_cb_edns_back_parsed( 3710cd9f4ecSchristos inplace_cb_edns_back_parsed_func_type* fptr); 3720cd9f4ecSchristos 3730cd9f4ecSchristos /** 3740cd9f4ecSchristos * Check function pointer whitelist for inplace_cb_query_response func values. 3750cd9f4ecSchristos * @param fptr: function pointer to check. 3760cd9f4ecSchristos * @return false if not in whitelist. 3770cd9f4ecSchristos */ 3780cd9f4ecSchristos int fptr_whitelist_inplace_cb_query_response( 3790cd9f4ecSchristos inplace_cb_query_response_func_type* fptr); 3800cd9f4ecSchristos 381d0eba39bSchristos /** 382d0eba39bSchristos * Check function pointer whitelist for serve_expired_lookup func values. 383d0eba39bSchristos * @param fptr: function pointer to check. 384d0eba39bSchristos * @return false if not in whitelist. 385d0eba39bSchristos */ 386d0eba39bSchristos int fptr_whitelist_serve_expired_lookup(serve_expired_lookup_func_type* fptr); 387d0eba39bSchristos 3883b6c3722Schristos /** Due to module breakage by fptr wlist, these test app declarations 3893b6c3722Schristos * are presented here */ 3903b6c3722Schristos /** 3913b6c3722Schristos * compare two order_ids from lock-verify test app 3923b6c3722Schristos * @param e1: first order_id 3933b6c3722Schristos * @param e2: second order_id 3943b6c3722Schristos * @return compare code -1, 0, +1 (like memcmp). 3953b6c3722Schristos */ 3963b6c3722Schristos int order_lock_cmp(const void* e1, const void* e2); 3973b6c3722Schristos 3983b6c3722Schristos /** 3993b6c3722Schristos * compare two codeline structs for rbtree from memstats test app 4003b6c3722Schristos * @param a: codeline 4013b6c3722Schristos * @param b: codeline 4023b6c3722Schristos * @return compare code -1, 0, +1 (like memcmp). 4033b6c3722Schristos */ 4043b6c3722Schristos int codeline_cmp(const void* a, const void* b); 4053b6c3722Schristos 4063b6c3722Schristos /** compare two replay_vars */ 4073b6c3722Schristos int replay_var_compare(const void* a, const void* b); 4083b6c3722Schristos 4093b6c3722Schristos #endif /* UTIL_FPTR_WLIST_H */ 410