1933707f3Ssthen /* 2933707f3Ssthen * util/fptr_wlist.h - function pointer whitelists. 3933707f3Ssthen * 4933707f3Ssthen * Copyright (c) 2007, NLnet Labs. All rights reserved. 5933707f3Ssthen * 6933707f3Ssthen * This software is open source. 7933707f3Ssthen * 8933707f3Ssthen * Redistribution and use in source and binary forms, with or without 9933707f3Ssthen * modification, are permitted provided that the following conditions 10933707f3Ssthen * are met: 11933707f3Ssthen * 12933707f3Ssthen * Redistributions of source code must retain the above copyright notice, 13933707f3Ssthen * this list of conditions and the following disclaimer. 14933707f3Ssthen * 15933707f3Ssthen * Redistributions in binary form must reproduce the above copyright notice, 16933707f3Ssthen * this list of conditions and the following disclaimer in the documentation 17933707f3Ssthen * and/or other materials provided with the distribution. 18933707f3Ssthen * 19933707f3Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may 20933707f3Ssthen * be used to endorse or promote products derived from this software without 21933707f3Ssthen * specific prior written permission. 22933707f3Ssthen * 23933707f3Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 240b68ff31Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 250b68ff31Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 260b68ff31Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 270b68ff31Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 280b68ff31Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 290b68ff31Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 300b68ff31Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 310b68ff31Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 320b68ff31Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 330b68ff31Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34933707f3Ssthen */ 35933707f3Ssthen 36933707f3Ssthen /** 37933707f3Ssthen * \file 38933707f3Ssthen * 39933707f3Ssthen * This file contains functions that check function pointers. 40933707f3Ssthen * The functions contain a whitelist of known good callback values. 41933707f3Ssthen * Any other values lead to an error. 42933707f3Ssthen * 43933707f3Ssthen * This prevent heap overflow based exploits, where the callback pointer 44933707f3Ssthen * is overwritten by a buffer overflow (apart from this defense, buffer 45933707f3Ssthen * overflows should be fixed of course). 46933707f3Ssthen * 47933707f3Ssthen * Function pointers are used in 48933707f3Ssthen * o network code callbacks. 49933707f3Ssthen * o rbtree, lruhash, region data manipulation 50933707f3Ssthen * in lruhash, the assertions are before the critical regions. 51933707f3Ssthen * in other places, assertions are before the callback. 52933707f3Ssthen * o module operations. 53933707f3Ssthen */ 54933707f3Ssthen 55933707f3Ssthen #ifndef UTIL_FPTR_WLIST_H 56933707f3Ssthen #define UTIL_FPTR_WLIST_H 57933707f3Ssthen #include "util/netevent.h" 58933707f3Ssthen #include "util/storage/lruhash.h" 59933707f3Ssthen #include "util/module.h" 60933707f3Ssthen #include "util/tube.h" 61933707f3Ssthen #include "services/mesh.h" 62933707f3Ssthen 63933707f3Ssthen /** 64933707f3Ssthen * Macro to perform an assertion check for fptr wlist checks. 65933707f3Ssthen * Does not get disabled in optimize mode. Check adds security by layers. 66933707f3Ssthen */ 67933707f3Ssthen #if defined(EXPORT_ALL_SYMBOLS) 68933707f3Ssthen #define fptr_ok(x) /* nothing, dll-exe memory layout on win disables it */ 69933707f3Ssthen #else 70933707f3Ssthen #define fptr_ok(x) \ 71933707f3Ssthen do { if(!(x)) \ 72933707f3Ssthen fatal_exit("%s:%d: %s: pointer whitelist %s failed", \ 73933707f3Ssthen __FILE__, __LINE__, __func__, #x); \ 74933707f3Ssthen } while(0); 75933707f3Ssthen #endif 76933707f3Ssthen 77933707f3Ssthen /** 78933707f3Ssthen * Check function pointer whitelist for comm_point callback values. 79933707f3Ssthen * 80933707f3Ssthen * @param fptr: function pointer to check. 81933707f3Ssthen * @return false if not in whitelist. 82933707f3Ssthen */ 8377079be7Ssthen int fptr_whitelist_comm_point(comm_point_callback_type *fptr); 84933707f3Ssthen 85933707f3Ssthen /** 86933707f3Ssthen * Check function pointer whitelist for raw comm_point callback values. 87933707f3Ssthen * 88933707f3Ssthen * @param fptr: function pointer to check. 89933707f3Ssthen * @return false if not in whitelist. 90933707f3Ssthen */ 9177079be7Ssthen int fptr_whitelist_comm_point_raw(comm_point_callback_type *fptr); 92933707f3Ssthen 93933707f3Ssthen /** 94933707f3Ssthen * Check function pointer whitelist for comm_timer callback values. 95933707f3Ssthen * 96933707f3Ssthen * @param fptr: function pointer to check. 97933707f3Ssthen * @return false if not in whitelist. 98933707f3Ssthen */ 99933707f3Ssthen int fptr_whitelist_comm_timer(void (*fptr)(void*)); 100933707f3Ssthen 101933707f3Ssthen /** 102933707f3Ssthen * Check function pointer whitelist for comm_signal callback values. 103933707f3Ssthen * 104933707f3Ssthen * @param fptr: function pointer to check. 105933707f3Ssthen * @return false if not in whitelist. 106933707f3Ssthen */ 107933707f3Ssthen int fptr_whitelist_comm_signal(void (*fptr)(int, void*)); 108933707f3Ssthen 109933707f3Ssthen /** 110af4988b1Ssthen * Check function pointer whitelist for start_accept callback values. 111af4988b1Ssthen * 112af4988b1Ssthen * @param fptr: function pointer to check. 113af4988b1Ssthen * @return false if not in whitelist. 114af4988b1Ssthen */ 115af4988b1Ssthen int fptr_whitelist_start_accept(void (*fptr)(void*)); 116af4988b1Ssthen 117af4988b1Ssthen /** 118af4988b1Ssthen * Check function pointer whitelist for stop_accept callback values. 119af4988b1Ssthen * 120af4988b1Ssthen * @param fptr: function pointer to check. 121af4988b1Ssthen * @return false if not in whitelist. 122af4988b1Ssthen */ 123af4988b1Ssthen int fptr_whitelist_stop_accept(void (*fptr)(void*)); 124af4988b1Ssthen 125af4988b1Ssthen /** 126933707f3Ssthen * Check function pointer whitelist for event structure callback values. 127933707f3Ssthen * This is not called by libevent itself, but checked by netevent. 128933707f3Ssthen * 129933707f3Ssthen * @param fptr: function pointer to check. 130933707f3Ssthen * @return false if not in whitelist. 131933707f3Ssthen */ 132933707f3Ssthen int fptr_whitelist_event(void (*fptr)(int, short, void *)); 133933707f3Ssthen 134933707f3Ssthen /** 135933707f3Ssthen * Check function pointer whitelist for pending udp callback values. 136933707f3Ssthen * 137933707f3Ssthen * @param fptr: function pointer to check. 138933707f3Ssthen * @return false if not in whitelist. 139933707f3Ssthen */ 14077079be7Ssthen int fptr_whitelist_pending_udp(comm_point_callback_type *fptr); 141933707f3Ssthen 142933707f3Ssthen /** 143933707f3Ssthen * Check function pointer whitelist for pending tcp callback values. 144933707f3Ssthen * 145933707f3Ssthen * @param fptr: function pointer to check. 146933707f3Ssthen * @return false if not in whitelist. 147933707f3Ssthen */ 14877079be7Ssthen int fptr_whitelist_pending_tcp(comm_point_callback_type *fptr); 149933707f3Ssthen 150933707f3Ssthen /** 151933707f3Ssthen * Check function pointer whitelist for serviced query callback values. 152933707f3Ssthen * 153933707f3Ssthen * @param fptr: function pointer to check. 154933707f3Ssthen * @return false if not in whitelist. 155933707f3Ssthen */ 15677079be7Ssthen int fptr_whitelist_serviced_query(comm_point_callback_type *fptr); 157933707f3Ssthen 158933707f3Ssthen /** 159933707f3Ssthen * Check function pointer whitelist for rbtree cmp callback values. 160933707f3Ssthen * 161933707f3Ssthen * @param fptr: function pointer to check. 162933707f3Ssthen * @return false if not in whitelist. 163933707f3Ssthen */ 164933707f3Ssthen int fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *)); 165933707f3Ssthen 166933707f3Ssthen /** 167933707f3Ssthen * Check function pointer whitelist for lruhash sizefunc callback values. 168933707f3Ssthen * 169933707f3Ssthen * @param fptr: function pointer to check. 170933707f3Ssthen * @return false if not in whitelist. 171933707f3Ssthen */ 17277079be7Ssthen int fptr_whitelist_hash_sizefunc(lruhash_sizefunc_type fptr); 173933707f3Ssthen 174933707f3Ssthen /** 175933707f3Ssthen * Check function pointer whitelist for lruhash compfunc callback values. 176933707f3Ssthen * 177933707f3Ssthen * @param fptr: function pointer to check. 178933707f3Ssthen * @return false if not in whitelist. 179933707f3Ssthen */ 18077079be7Ssthen int fptr_whitelist_hash_compfunc(lruhash_compfunc_type fptr); 181933707f3Ssthen 182933707f3Ssthen /** 183933707f3Ssthen * Check function pointer whitelist for lruhash delkeyfunc callback values. 184933707f3Ssthen * 185933707f3Ssthen * @param fptr: function pointer to check. 186933707f3Ssthen * @return false if not in whitelist. 187933707f3Ssthen */ 18877079be7Ssthen int fptr_whitelist_hash_delkeyfunc(lruhash_delkeyfunc_type fptr); 189933707f3Ssthen 190933707f3Ssthen /** 191933707f3Ssthen * Check function pointer whitelist for lruhash deldata callback values. 192933707f3Ssthen * 193933707f3Ssthen * @param fptr: function pointer to check. 194933707f3Ssthen * @return false if not in whitelist. 195933707f3Ssthen */ 19677079be7Ssthen int fptr_whitelist_hash_deldatafunc(lruhash_deldatafunc_type fptr); 197933707f3Ssthen 198933707f3Ssthen /** 199933707f3Ssthen * Check function pointer whitelist for lruhash markdel callback values. 200933707f3Ssthen * 201933707f3Ssthen * @param fptr: function pointer to check. 202933707f3Ssthen * @return false if not in whitelist. 203933707f3Ssthen */ 20477079be7Ssthen int fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_type fptr); 205933707f3Ssthen 206933707f3Ssthen /** 207933707f3Ssthen * Check function pointer whitelist for module_env send_query callback values. 208933707f3Ssthen * 209933707f3Ssthen * @param fptr: function pointer to check. 210933707f3Ssthen * @return false if not in whitelist. 211933707f3Ssthen */ 212933707f3Ssthen int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)( 21377079be7Ssthen struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec, 214e21c60efSsthen int nocaps, int check_ratelimit, struct sockaddr_storage* addr, 215e21c60efSsthen socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream, 216e21c60efSsthen int ssl_upstream, char* tls_auth_name, struct module_qstate* q, 217e21c60efSsthen int* was_ratelimited)); 218933707f3Ssthen 219933707f3Ssthen /** 220933707f3Ssthen * Check function pointer whitelist for module_env detach_subs callback values. 221933707f3Ssthen * 222933707f3Ssthen * @param fptr: function pointer to check. 223933707f3Ssthen * @return false if not in whitelist. 224933707f3Ssthen */ 225933707f3Ssthen int fptr_whitelist_modenv_detach_subs(void (*fptr)( 226933707f3Ssthen struct module_qstate* qstate)); 227933707f3Ssthen 228933707f3Ssthen /** 229933707f3Ssthen * Check function pointer whitelist for module_env attach_sub callback values. 230933707f3Ssthen * 231933707f3Ssthen * @param fptr: function pointer to check. 232933707f3Ssthen * @return false if not in whitelist. 233933707f3Ssthen */ 234933707f3Ssthen int fptr_whitelist_modenv_attach_sub(int (*fptr)( 235933707f3Ssthen struct module_qstate* qstate, struct query_info* qinfo, 23657dceb2aSbrad uint16_t qflags, int prime, int valrec, struct module_qstate** newq)); 237933707f3Ssthen 238933707f3Ssthen /** 2392be9e038Ssthen * Check function pointer whitelist for module_env add_sub callback values. 2402be9e038Ssthen * 2412be9e038Ssthen * @param fptr: function pointer to check. 2422be9e038Ssthen * @return false if not in whitelist. 2432be9e038Ssthen */ 2442be9e038Ssthen int fptr_whitelist_modenv_add_sub(int (*fptr)(struct module_qstate* qstate, 2452be9e038Ssthen struct query_info* qinfo, uint16_t qflags, int prime, int valrec, 2462be9e038Ssthen struct module_qstate** newq, struct mesh_state** sub)); 2472be9e038Ssthen /** 248933707f3Ssthen * Check function pointer whitelist for module_env kill_sub callback values. 249933707f3Ssthen * 250933707f3Ssthen * @param fptr: function pointer to check. 251933707f3Ssthen * @return false if not in whitelist. 252933707f3Ssthen */ 253933707f3Ssthen int fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq)); 254933707f3Ssthen 255933707f3Ssthen /** 256933707f3Ssthen * Check function pointer whitelist for module_env detect_cycle callback values. 257933707f3Ssthen * 258933707f3Ssthen * @param fptr: function pointer to check. 259933707f3Ssthen * @return false if not in whitelist. 260933707f3Ssthen */ 261933707f3Ssthen int fptr_whitelist_modenv_detect_cycle(int (*fptr)( 262933707f3Ssthen struct module_qstate* qstate, struct query_info* qinfo, 26357dceb2aSbrad uint16_t flags, int prime, int valrec)); 264933707f3Ssthen 265933707f3Ssthen /** 266933707f3Ssthen * Check function pointer whitelist for module init call values. 267933707f3Ssthen * 268933707f3Ssthen * @param fptr: function pointer to check. 269933707f3Ssthen * @return false if not in whitelist. 270933707f3Ssthen */ 271933707f3Ssthen int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id)); 272933707f3Ssthen 273933707f3Ssthen /** 274933707f3Ssthen * Check function pointer whitelist for module deinit call values. 275933707f3Ssthen * 276933707f3Ssthen * @param fptr: function pointer to check. 277933707f3Ssthen * @return false if not in whitelist. 278933707f3Ssthen */ 279933707f3Ssthen int fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id)); 280933707f3Ssthen 281933707f3Ssthen /** 282*98bc733bSsthen * Check function pointer whitelist for module startup call values. 283*98bc733bSsthen * 284*98bc733bSsthen * @param fptr: function pointer to check. 285*98bc733bSsthen * @return false if not in whitelist. 286*98bc733bSsthen */ 287*98bc733bSsthen int fptr_whitelist_mod_startup(int (*fptr)(struct module_env* env, int id)); 288*98bc733bSsthen 289*98bc733bSsthen /** 290*98bc733bSsthen * Check function pointer whitelist for module destartup call values. 291*98bc733bSsthen * 292*98bc733bSsthen * @param fptr: function pointer to check. 293*98bc733bSsthen * @return false if not in whitelist. 294*98bc733bSsthen */ 295*98bc733bSsthen int fptr_whitelist_mod_destartup(void (*fptr)(struct module_env* env, int id)); 296*98bc733bSsthen 297*98bc733bSsthen /** 298933707f3Ssthen * Check function pointer whitelist for module operate call values. 299933707f3Ssthen * 300933707f3Ssthen * @param fptr: function pointer to check. 301933707f3Ssthen * @return false if not in whitelist. 302933707f3Ssthen */ 303933707f3Ssthen int fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate, 304933707f3Ssthen enum module_ev event, int id, struct outbound_entry* outbound)); 305933707f3Ssthen 306933707f3Ssthen /** 307933707f3Ssthen * Check function pointer whitelist for module inform_super call values. 308933707f3Ssthen * 309933707f3Ssthen * @param fptr: function pointer to check. 310933707f3Ssthen * @return false if not in whitelist. 311933707f3Ssthen */ 312933707f3Ssthen int fptr_whitelist_mod_inform_super(void (*fptr)( 313933707f3Ssthen struct module_qstate* qstate, int id, struct module_qstate* super)); 314933707f3Ssthen 315933707f3Ssthen /** 316933707f3Ssthen * Check function pointer whitelist for module clear call values. 317933707f3Ssthen * 318933707f3Ssthen * @param fptr: function pointer to check. 319933707f3Ssthen * @return false if not in whitelist. 320933707f3Ssthen */ 321933707f3Ssthen int fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate, 322933707f3Ssthen int id)); 323933707f3Ssthen 324933707f3Ssthen /** 325933707f3Ssthen * Check function pointer whitelist for module get_mem call values. 326933707f3Ssthen * 327933707f3Ssthen * @param fptr: function pointer to check. 328933707f3Ssthen * @return false if not in whitelist. 329933707f3Ssthen */ 330933707f3Ssthen int fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id)); 331933707f3Ssthen 332933707f3Ssthen /** 333933707f3Ssthen * Check function pointer whitelist for alloc clear on id overflow call values. 334933707f3Ssthen * 335933707f3Ssthen * @param fptr: function pointer to check. 336933707f3Ssthen * @return false if not in whitelist. 337933707f3Ssthen */ 338933707f3Ssthen int fptr_whitelist_alloc_cleanup(void (*fptr)(void*)); 339933707f3Ssthen 340933707f3Ssthen /** 341933707f3Ssthen * Check function pointer whitelist for tube listen handler values. 342933707f3Ssthen * 343933707f3Ssthen * @param fptr: function pointer to check. 344933707f3Ssthen * @return false if not in whitelist. 345933707f3Ssthen */ 34677079be7Ssthen int fptr_whitelist_tube_listen(tube_callback_type* fptr); 347933707f3Ssthen 348933707f3Ssthen /** 349933707f3Ssthen * Check function pointer whitelist for mesh state callback values. 350933707f3Ssthen * 351933707f3Ssthen * @param fptr: function pointer to check. 352933707f3Ssthen * @return false if not in whitelist. 353933707f3Ssthen */ 35477079be7Ssthen int fptr_whitelist_mesh_cb(mesh_cb_func_type fptr); 355933707f3Ssthen 356933707f3Ssthen /** 357933707f3Ssthen * Check function pointer whitelist for config_get_option func values. 358933707f3Ssthen * @param fptr: function pointer to check. 359933707f3Ssthen * @return false if not in whitelist. 360933707f3Ssthen */ 361933707f3Ssthen int fptr_whitelist_print_func(void (*fptr)(char*,void*)); 362933707f3Ssthen 36377079be7Ssthen /** 36477079be7Ssthen * Check function pointer whitelist for inplace_cb_reply, 36577079be7Ssthen * inplace_cb_reply_cache, inplace_cb_reply_local and inplace_cb_reply_servfail 36677079be7Ssthen * func values. 36777079be7Ssthen * @param fptr: function pointer to check. 36877079be7Ssthen * @param type: the type of the callback function. 36977079be7Ssthen * @return false if not in whitelist. 37077079be7Ssthen */ 37177079be7Ssthen int fptr_whitelist_inplace_cb_reply_generic(inplace_cb_reply_func_type* fptr, 37277079be7Ssthen enum inplace_cb_list_type type); 37377079be7Ssthen 37477079be7Ssthen /** 37577079be7Ssthen * Check function pointer whitelist for inplace_cb_query func values. 37677079be7Ssthen * @param fptr: function pointer to check. 37777079be7Ssthen * @return false if not in whitelist. 37877079be7Ssthen */ 37977079be7Ssthen int fptr_whitelist_inplace_cb_query(inplace_cb_query_func_type* fptr); 38077079be7Ssthen 3812be9e038Ssthen /** 3822be9e038Ssthen * Check function pointer whitelist for inplace_cb_edns_back_parsed func values. 3832be9e038Ssthen * @param fptr: function pointer to check. 3842be9e038Ssthen * @return false if not in whitelist. 3852be9e038Ssthen */ 3862be9e038Ssthen int fptr_whitelist_inplace_cb_edns_back_parsed( 3872be9e038Ssthen inplace_cb_edns_back_parsed_func_type* fptr); 3882be9e038Ssthen 3892be9e038Ssthen /** 3902be9e038Ssthen * Check function pointer whitelist for inplace_cb_query_response func values. 3912be9e038Ssthen * @param fptr: function pointer to check. 3922be9e038Ssthen * @return false if not in whitelist. 3932be9e038Ssthen */ 3942be9e038Ssthen int fptr_whitelist_inplace_cb_query_response( 3952be9e038Ssthen inplace_cb_query_response_func_type* fptr); 3962be9e038Ssthen 397eaf2578eSsthen /** 398eaf2578eSsthen * Check function pointer whitelist for serve_expired_lookup func values. 399eaf2578eSsthen * @param fptr: function pointer to check. 400eaf2578eSsthen * @return false if not in whitelist. 401eaf2578eSsthen */ 402eaf2578eSsthen int fptr_whitelist_serve_expired_lookup(serve_expired_lookup_func_type* fptr); 403eaf2578eSsthen 404933707f3Ssthen /** Due to module breakage by fptr wlist, these test app declarations 405933707f3Ssthen * are presented here */ 406933707f3Ssthen /** 407933707f3Ssthen * compare two order_ids from lock-verify test app 408933707f3Ssthen * @param e1: first order_id 409933707f3Ssthen * @param e2: second order_id 410933707f3Ssthen * @return compare code -1, 0, +1 (like memcmp). 411933707f3Ssthen */ 412933707f3Ssthen int order_lock_cmp(const void* e1, const void* e2); 413933707f3Ssthen 414933707f3Ssthen /** 415933707f3Ssthen * compare two codeline structs for rbtree from memstats test app 416933707f3Ssthen * @param a: codeline 417933707f3Ssthen * @param b: codeline 418933707f3Ssthen * @return compare code -1, 0, +1 (like memcmp). 419933707f3Ssthen */ 420933707f3Ssthen int codeline_cmp(const void* a, const void* b); 421933707f3Ssthen 422933707f3Ssthen /** compare two replay_vars */ 423933707f3Ssthen int replay_var_compare(const void* a, const void* b); 424933707f3Ssthen 425933707f3Ssthen #endif /* UTIL_FPTR_WLIST_H */ 426