1 /* $OpenBSD: namespace.h,v 1.12 2018/01/18 08:23:44 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 __dso_protected __attribute__((__visibility__("protected"))) 139 140 #define HIDDEN(x) _libc_##x 141 #define CANCEL(x) _libc_##x##_cancel 142 #define WRAP(x) _libc_##x##_wrap 143 #define HIDDEN_STRING(x) "_libc_" __STRING(x) 144 #define CANCEL_STRING(x) "_libc_" __STRING(x) "_cancel" 145 #define WRAP_STRING(x) "_libc_" __STRING(x) "_wrap" 146 147 #define PROTO_NORMAL(x) __dso_hidden typeof(x) x asm(HIDDEN_STRING(x)) 148 #define PROTO_STD_DEPRECATED(x) typeof(x) x __attribute__((deprecated)) 149 #define PROTO_DEPRECATED(x) typeof(x) x __attribute__((deprecated, weak)) 150 #define PROTO_CANCEL(x) __dso_hidden typeof(x) HIDDEN(x), \ 151 x asm(CANCEL_STRING(x)) 152 #define PROTO_WRAP(x) PROTO_NORMAL(x), WRAP(x) 153 #define PROTO_PROTECTED(x) __dso_protected typeof(x) x 154 155 #define DEF_STRONG(x) __strong_alias(x, HIDDEN(x)) 156 #define DEF_WEAK(x) __weak_alias(x, HIDDEN(x)) 157 #define DEF_CANCEL(x) __weak_alias(x, CANCEL(x)) 158 #define DEF_WRAP(x) __weak_alias(x, WRAP(x)) 159 #define DEF_SYS(x) __strong_alias(_thread_sys_##x, HIDDEN(x)) 160 #ifdef __clang__ 161 #define DEF_BUILTIN(x) __asm("") 162 #define BUILTIN __dso_protected 163 #else 164 #define DEF_BUILTIN(x) DEF_STRONG(x) 165 #define BUILTIN 166 #endif 167 168 #define MAKE_CLONE(dst, src) __dso_hidden typeof(dst) HIDDEN(dst) \ 169 __attribute__((alias (HIDDEN_STRING(src)))) 170 171 172 /* 173 * gcc and clang will generate calls to the functions below. 174 * Declare and redirect them here so we always go 175 * directly to our hidden aliases. 176 */ 177 #include <sys/_types.h> 178 BUILTIN void *memmove(void *, const void *, __size_t); 179 BUILTIN void *memcpy(void *__restrict, const void *__restrict, __size_t); 180 BUILTIN void *memset(void *, int, __size_t); 181 BUILTIN void __stack_smash_handler(const char [], int __unused); 182 #ifndef __clang__ 183 PROTO_NORMAL(memmove); 184 PROTO_NORMAL(memcpy); 185 PROTO_NORMAL(memset); 186 PROTO_NORMAL(__stack_smash_handler); 187 #endif 188 #undef BUILTIN 189 190 #endif /* _LIBC_NAMESPACE_H_ */ 191 192