1 /* $OpenBSD: namespace.h,v 1.10 2016/05/07 19:05:22 guenther Exp $ */ 2 3 #ifndef _LIBC_NAMESPACE_H_ 4 #define _LIBC_NAMESPACE_H_ 5 6 /* 7 * Copyright (c) 2015 Philip Guenther <guenther@openbsd.org> 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 /* 23 * The goal: calls from inside libc to other libc functions should be via 24 * identifiers that are of hidden visibility and--to avoid confusion--are 25 * in the reserved namespace. By doing this these calls are protected 26 * from overriding by applications and on many platforms can avoid creation 27 * or use of GOT or PLT entries. I've chosen a prefix of underbar-C-underbar 28 * ("_libc_") for this. These will not be declared directly; instead, the 29 * gcc "asm labels" extension will be used rename the function. 30 * 31 * For syscalls which are cancellation points, such as wait4(), there 32 * are identifiers that do not provide cancellation: 33 * _libc_wait4 hidden alias, for use internal to libc only 34 * _thread_sys_wait4 global name, for use outside libc only 35 * ...and identifiers that do provide cancellation: 36 * wait4 weak alias, for general use 37 * _libc_wait4_cancel hidden alias, for use internal to libc only 38 * Inside libc, the bare name ("wait4") binds to the version *without* 39 * cancellation; the few times where cancellation is desired it can be 40 * obtained by calling CANCEL(x) instead of just x. 41 * 42 * Some other calls need to be wrapped for reasons other than cancellation, 43 * such as to provide functionality beyond the underlying syscall (e.g., 44 * sigaction). For these, there are identifiers for the raw call, without 45 * the wrapping: 46 * _libc_sigaction hidden alias, for use internal to libc only 47 * _thread_sys_sigaction global name, for use outside libc only 48 * ...and identifiers that do provide the libc wrapping: 49 * sigaction weak alias, for general use 50 * _libc_sigaction_wrap hidden alias, for use internal to libc only 51 * Inside libc, the bare name ("sigaction") binds to the wrapper; when the 52 * raw version is necessary it can be obtained by calling HIDDEN(x) instead of 53 * just x. 54 * 55 * For syscalls which are not cancellation points, such as getpid(), 56 * the identifiers are just: 57 * _libc_getpid hidden alias, for use internal to libc only 58 * _thread_sys_getpid global name, for use outside libc only 59 * getpid weak alias, for use outside libc only 60 * 61 * By using gcc's "asm label" extension, we can usually avoid having 62 * to type those prefixes in the .h and .c files. However, for those 63 * cases where a non-default binding is necessary we can use these macros 64 * to get the desired identifier: 65 * 66 * CANCEL(x) 67 * This expands to the internal, hidden name of a cancellation 68 * wrapper: _libc_x_cancel. ex: CANCEL(fsync)(fd) 69 * 70 * WRAP(x) 71 * This expands to the internal, hidden name of a non-cancellation 72 * wrapper: _libc_x_wrap. ex: WRAP(sigprocmask)(set) 73 * 74 * 75 * In order to actually set up the desired asm labels, we use these in 76 * the internal .h files: 77 * PROTO_NORMAL(x) Symbols used both internally and externally 78 * This makes gcc convert use of x to use _libc_x instead 79 * ex: PROTO_NORMAL(getpid) 80 * 81 * PROTO_STD_DEPRECATED(x) Standard C symbols that we don't want to use 82 * This just marks the symbol as deprecated, with no renaming. 83 * ex: PROTO_STD_DEPRECATED(strcpy) 84 * 85 * PROTO_DEPRECATED(x) Symbols not in ISO C that we don't want to use 86 * This marks the symbol as both weak and deprecated, with no renaming 87 * ex: PROTO_DEPRECATED(creat) 88 * 89 * PROTO_CANCEL(x) Functions that have cancellation wrappers 90 * Like PROTO_NORMAL(x), but also declares _libc_x_cancel 91 * ex: PROTO_CANCEL(wait4) 92 * 93 * PROTO_WRAP(x) Functions that have wrappers for other reasons 94 * Like PROTO_NORMAL(x), but also declares _libc_x_wrap. Internal 95 * calls that want the wrapper's processing should invoke WRAP(x)(...) 96 * ex: PROTO_WRAP(sigaction) 97 * 98 * 99 * Finally, to create the expected aliases, we use these in the .c files 100 * where the definitions are: 101 * DEF_STRONG(x) Symbols reserved to or specified by ISO C 102 * This defines x as a strong alias for _libc_x; this must only 103 * be used for symbols that are reserved by the C standard 104 * (or reserved in the external identifier namespace). 105 * Matches with PROTO_NORMAL() 106 * ex: DEF_STRONG(fopen) 107 * 108 * DEF_WEAK(x) Symbols used internally and not in ISO C 109 * This defines x as a weak alias for _libc_x 110 * Matches with PROTO_NORMAL() 111 * ex: DEF_WEAK(lseek) 112 * 113 * DEF_CANCEL(x) Symbols that have a cancellation wrapper 114 * This defines x as a weak alias for _libc_x_cancel. 115 * Matches with PROTO_CANCEL() 116 * ex: DEF_CANCEL(read) 117 * 118 * DEF_WRAP(x) 119 * This defines x as a weak alias for _libc_x_wrap. 120 * Matches with PROTO_WRAP() 121 * ex: DEF_WRAP(sigaction) 122 * 123 * DEF_SYS(x) 124 * This defines _thread_sys_x as a strong alias for _libc_x. This should 125 * only be needed for syscalls that have C instead of asm stubs. 126 * Matches with PROTO_NORMAL(), PROTO_CANCEL(), or PROTO_WRAP() 127 * ex: DEF_SYS(pread) 128 * 129 * MAKE_CLONE(dst, src) Symbols that are exact clones of other symbols 130 * This declares _libc_dst as being the same type as dst, and makes 131 * _libc_dst a strong, hidden alias for _libc_src. You still need to 132 * DEF_STRONG(dst) or DEF_WEAK(dst) to alias dst itself 133 * ex: MAKE_CLONE(SHA224Pad, SHA256Pad) 134 */ 135 136 #include <sys/cdefs.h> /* for __dso_hidden and __{weak,strong}_alias */ 137 138 #define HIDDEN(x) _libc_##x 139 #define CANCEL(x) _libc_##x##_cancel 140 #define WRAP(x) _libc_##x##_wrap 141 #define HIDDEN_STRING(x) "_libc_" __STRING(x) 142 #define CANCEL_STRING(x) "_libc_" __STRING(x) "_cancel" 143 #define WRAP_STRING(x) "_libc_" __STRING(x) "_wrap" 144 145 #define PROTO_NORMAL(x) __dso_hidden typeof(x) x asm(HIDDEN_STRING(x)) 146 #define PROTO_STD_DEPRECATED(x) typeof(x) x __attribute__((deprecated)) 147 #define PROTO_DEPRECATED(x) typeof(x) x __attribute__((deprecated, weak)) 148 #define PROTO_CANCEL(x) __dso_hidden typeof(x) HIDDEN(x), \ 149 x asm(CANCEL_STRING(x)) 150 #define PROTO_WRAP(x) PROTO_NORMAL(x), WRAP(x) 151 152 #define DEF_STRONG(x) __strong_alias(x, HIDDEN(x)) 153 #define DEF_WEAK(x) __weak_alias(x, HIDDEN(x)) 154 #define DEF_CANCEL(x) __weak_alias(x, CANCEL(x)) 155 #define DEF_WRAP(x) __weak_alias(x, WRAP(x)) 156 #define DEF_SYS(x) __strong_alias(_thread_sys_##x, HIDDEN(x)) 157 158 #define MAKE_CLONE(dst, src) __dso_hidden typeof(dst) HIDDEN(dst) \ 159 __attribute__((alias (HIDDEN_STRING(src)))) 160 161 162 /* 163 * gcc will generate calls to the functions below. 164 * Declare and redirect them here so we always go 165 * directly to our hidden aliases. 166 */ 167 #include <sys/_types.h> 168 void *memcpy(void *__restrict, const void *__restrict, __size_t); 169 void *memset(void *, int, __size_t); 170 void __stack_smash_handler(const char [], int __attribute__((__unused__))); 171 PROTO_NORMAL(memcpy); 172 PROTO_NORMAL(memset); 173 PROTO_NORMAL(__stack_smash_handler); 174 175 #endif /* _LIBC_NAMESPACE_H_ */ 176 177