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