1: /*
2: * Copyright (c) 2004-2005, 2010-2013 Todd C. Miller <Todd.Miller@courtesan.com>
3: *
4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15: */
16:
17: #include <config.h>
18:
19: #include <sys/types.h>
20:
21: #include <errno.h>
22: #include <stdarg.h>
23: #ifdef HAVE_UNISTD_H
24: # include <unistd.h>
25: #endif /* HAVE_UNISTD_H */
26: #ifdef HAVE_SPAWN_H
27: #include <spawn.h>
28: #endif
29:
30: #include "missing.h"
31:
32: #ifdef HAVE___INTERPOSE
33: /*
34: * Mac OS X 10.4 and above has support for library symbol interposition.
35: * There is a good explanation of this in the Mac OS X Internals book.
36: */
37: typedef struct interpose_s {
38: void *new_func;
39: void *orig_func;
40: } interpose_t;
41:
42: # define FN_NAME(fn) dummy_ ## fn
43: # define INTERPOSE(fn) \
44: __attribute__((__used__)) static const interpose_t interpose_ ## fn \
45: __attribute__((__section__("__DATA,__interpose"))) = \
46: { (void *)dummy_ ## fn, (void *)fn };
47: #else
48: # define FN_NAME(fn) fn
49: # define INTERPOSE(fn)
50: #endif
51:
52: /*
53: * Dummy versions of the exec(3) family of syscalls. It is not enough
54: * to just dummy out execve(2) since some C libraries use direct syscalls
55: * for the other functions instead of calling execve(2). Note that it is
56: * still possible to access the real syscalls via the syscall(2) interface
57: * but very few programs actually do that.
58: */
59:
60: #define DUMMY_BODY \
61: { \
62: errno = EACCES; \
63: return -1; \
64: }
65:
66: #define DUMMY2(fn, t1, t2) \
67: __dso_public int \
68: FN_NAME(fn)(t1 a1, t2 a2) \
69: DUMMY_BODY \
70: INTERPOSE(fn)
71:
72: #define DUMMY3(fn, t1, t2, t3) \
73: __dso_public int \
74: FN_NAME(fn)(t1 a1, t2 a2, t3 a3) \
75: DUMMY_BODY \
76: INTERPOSE(fn)
77:
78: #define DUMMY6(fn, t1, t2, t3, t4, t5, t6) \
79: __dso_public int \
80: FN_NAME(fn)(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
81: DUMMY_BODY \
82: INTERPOSE(fn)
83:
84: #define DUMMY_VA(fn, t1, t2) \
85: __dso_public int \
86: FN_NAME(fn)(t1 a1, t2 a2, ...) \
87: DUMMY_BODY \
88: INTERPOSE(fn)
89:
90: /*
91: * Standard exec(3) family of functions.
92: */
93: DUMMY_VA(execl, const char *, const char *)
94: DUMMY_VA(execle, const char *, const char *)
95: DUMMY_VA(execlp, const char *, const char *)
96: DUMMY2(execv, const char *, char * const *)
97: DUMMY2(execvp, const char *, char * const *)
98: DUMMY3(execve, const char *, char * const *, char * const *)
99:
100: /*
101: * Private versions of the above.
102: */
103: #ifdef HAVE__EXECL
104: DUMMY_VA(_execl, const char *, const char *)
105: #endif
106: #ifdef HAVE___EXECL
107: DUMMY_VA(__execl, const char *, const char *)
108: #endif
109: #ifdef HAVE__EXECLE
110: DUMMY_VA(_execle, const char *, const char *)
111: #endif
112: #ifdef HAVE___EXECLE
113: DUMMY_VA(__execle, const char *, const char *)
114: #endif
115: #ifdef HAVE__EXECLP
116: DUMMY_VA(_execlp, const char *, const char *)
117: #endif
118: #ifdef HAVE___EXECLP
119: DUMMY_VA(__execlp, const char *, const char *)
120: #endif
121: #ifdef HAVE__EXECV
122: DUMMY2(_execv, const char *, char * const *)
123: #endif
124: #ifdef HAVE___EXECV
125: DUMMY2(__execv, const char *, char * const *)
126: #endif
127: #ifdef HAVE__EXECVP
128: DUMMY2(_execvp, const char *, char * const *)
129: #endif
130: #ifdef HAVE___EXECVP
131: DUMMY2(__execvp, const char *, char * const *)
132: #endif
133: #ifdef HAVE__EXECVE
134: DUMMY3(_execve, const char *, char * const *, char * const *)
135: #endif
136: #ifdef HAVE___EXECVE
137: DUMMY3(__execve, const char *, char * const *, char * const *)
138: #endif
139:
140: /*
141: * Non-standard exec functions and corresponding private versions.
142: */
143: #ifdef HAVE_EXECVP
144: DUMMY3(execvP, const char *, const char *, char * const *)
145: #endif
146: #ifdef HAVE__EXECVP
147: DUMMY3(_execvP, const char *, const char *, char * const *)
148: #endif
149: #ifdef HAVE___EXECVP
150: DUMMY3(__execvP, const char *, const char *, char * const *)
151: #endif
152:
153: #ifdef HAVE_EXECVPE
154: DUMMY3(execvpe, const char *, char * const *, char * const *)
155: #endif
156: #ifdef HAVE__EXECVPE
157: DUMMY3(_execvpe, const char *, char * const *, char * const *)
158: #endif
159: #ifdef HAVE___EXECVPE
160: DUMMY3(__execvpe, const char *, char * const *, char * const *)
161: #endif
162:
163: #ifdef HAVE_EXECT
164: DUMMY3(exect, const char *, char * const *, char * const *)
165: #endif
166: #ifdef HAVE__EXECT
167: DUMMY3(_exect, const char *, char * const *, char * const *)
168: #endif
169: #ifdef HAVE___EXECT
170: DUMMY3(__exect, const char *, char * const *, char * const *)
171: #endif
172:
173: #ifdef HAVE_FEXECVE
174: DUMMY3(fexecve, int , char * const *, char * const *)
175: #endif
176: #ifdef HAVE__FEXECVE
177: DUMMY3(_fexecve, int , char * const *, char * const *)
178: #endif
179: #ifdef HAVE___FEXECVE
180: DUMMY3(__fexecve, int , char * const *, char * const *)
181: #endif
182:
183: /*
184: * posix_spawn, posix_spawnp and any private versions.
185: */
186: #ifdef HAVE_POSIX_SPAWN
187: DUMMY6(posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
188: #endif
189: #ifdef HAVE__POSIX_SPAWN
190: DUMMY6(_posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
191: #endif
192: #ifdef HAVE___POSIX_SPAWN
193: DUMMY6(__posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
194: #endif
195:
196: #ifdef HAVE_POSIX_SPAWNP
197: DUMMY6(posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
198: #endif
199: #ifdef HAVE_POSIX__SPAWNP
200: DUMMY6(_posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
201: #endif
202: #ifdef HAVE_POSIX___SPAWNP
203: DUMMY6(__posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
204: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>