-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdw-wrap-glibc.c
409 lines (366 loc) · 29.1 KB
/
dw-wrap-glibc.c
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
// We wrap all important calls to glibc to insure that pointers are checked and unprotected before being used
// internally in glibc or passed to system calls.
//
// For each pointer argument, we need to check, unprotect, call the glibc function and reprotect.
// If a glibc function calls another nested glibc function, there is no need to do further
// processing, because the arguments should have already been checked and unprotected.
#define _GNU_SOURCE
#include <malloc.h>
#include <string.h>
#include <wchar.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <errno.h>
#include <sched.h>
#include <limits.h>
#include <sys/mman.h>
#include <execinfo.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/openat2.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <sys/vfs.h>
#include <dirent.h>
#include <libintl.h>
#include <locale.h>
#include <sys/param.h>
#include "dw-log.h"
#include "dw-protect.h"
#include "dw-wrap-glibc.h"
// Intercept common glibc functions to check access and remove the protection from pointers.
// This is essential for system calls because otherwise they will fail.
// It is also useful for utility functions, as it can simplify the access check
// (a single one instead of multiple ones) and avoid some functions that may perform
// tricky pointer arithmetic (e.g. memcpy / memmove)
//
// Only a minimal set of wrappers was implemented, it is far from being complete.
// Moreover, some of the wrappers are incomplete. For instance, for the execvpe and
// similar functions, the argv and envp arrays are unprotected, but not the pointers
// contained within. This would require allocating a new array where to copy the unprotected
// pointers.
// Check that we can get the desired symbol
void *dlsym_check(void *restrict handle, const char *restrict symbol) {
void *ret = dlsym(handle, symbol);
if(ret == NULL) dw_log(WARNING, WRAP, "Symbol %s not found\n", symbol);
return ret;
}
// Size of argv arguments in execve and similar functions
static size_t arglen(char *const argv[])
{
size_t i = 0;
for(; argv[i] != NULL; i++);
return sizeof(char *) * (i + 1);
}
// Have our own strlen, not called with tainted pointers, that will
// not be instrumented by libpatch.
size_t dw_strlen(const char* s)
{
const char* cursor;
for (cursor = s; *cursor != 0; cursor++);
return (size_t)(cursor - s);
}
// Declare all the pointers to the original libc functions
static char* (*libc_strchr)(const char *s, int c);
static char* (*libc_strrchr)(const char *s, int c);
static int (*libc_strcmp)(const char *s1, const char *s2);
static int (*libc_strncmp)(const char *s1, const char *s2, size_t n);
static int (*libc_fputs)(const char *restrict s, FILE *restrict stream);
static int (*libc_puts)(const char *s);
static size_t (*libc_strlen)(const char *s);
static int (*libc_open)(const char *pathname, int flags, ...);
static int (*libc_openat)(int dirfd, const char *pathname, int flags, ...);
static int (*libc_creat)(const char *pathname, mode_t mode);
static int (*libc_access)(const char *pathname, int mode);
static char* (*libc_getcwd)(char *buf, size_t size);
static ssize_t (*libc_getrandom)(void *buf, size_t buflen, unsigned int flags);
static int (*libc_stat)(const char *restrict pathname, struct stat *restrict statbuf);
static int (*libc_fstat)(int fd, struct stat *statbuf);
static int (*libc_lstat)(const char *restrict pathname, struct stat *restrict statbuf);
static int (*libc_fstatat)(int dirfd, const char *restrict pathname, struct stat *restrict statbuf, int flags);
static size_t (*libc_fread)(void *ptr, size_t size, size_t nmemb, FILE *stream);
static size_t (*libc_fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream);
static ssize_t (*libc_pread)(int fd, void *buf, size_t count, off_t offset);
static ssize_t (*libc_pwrite)(int fd, const void *buf, size_t count, off_t offset);
static ssize_t (*libc_read)(int fd, void *buf, size_t count);
extern ssize_t __read(int fd, void *buf, size_t count);
static ssize_t (*libc_write)(int fd, const void *buf, size_t count);
extern ssize_t libc_real_write(int fd, const void *buf, size_t count);
static int (*libc_statfs)(const char *path, struct statfs *buf);
static int (*libc_fstatfs)(int fd, struct statfs *buf);
static ssize_t (*libc_getdents64)(int fd, void *dirp, size_t count);
static DIR* (*libc_opendir)(const char *name);
static int (*libc_bcmp)(const void *s1, const void *s2, size_t n);
static void (*libc_bcopy)(const void *src, void *dest, size_t n);
static void (*libc_bzero)(void *s, size_t n);
static void* (*libc_memccpy)(void *dest, const void *src, int c, size_t n);
static void* (*libc_memchr)(const void *s, int c, size_t n);
static int (*libc_memcmp)(const void *s1, const void *s2, size_t n);
static void* (*libc_memcpy)(void *dest, const void *src, size_t n);
static void* (*libc_memcpy_chk)(void *dest, const void *src, size_t len, size_t destlen);
static void* (*libc_memfrob)(void *s, size_t n);
static void* (*libc_memmem)(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
static void* (*libc_memmove)(void *dest, const void *src, size_t n);
static void* (*libc_mempcpy)(void *restrict dest, const void *restrict src, size_t n);
static void* (*libc_memset)(void *s, int c, size_t n);
static char* (*libc_strcpy)(char *restrict dest, const char *src);
static char* (*libc_strcat)(char *restrict dest, const char *src);
static char* (*libc_strncpy)(char *restrict dest, const char *restrict src, size_t n);
static wchar_t* (*libc_wmemmove)(wchar_t *dest, const wchar_t *src, size_t n);
static wchar_t* (*libc_wmempcpy)(wchar_t *restrict dest, const wchar_t *restrict src, size_t n);
static wchar_t* (*libc_wmemcpy)(wchar_t *restrict dest, const wchar_t *restrict src, size_t n);
static char* (*libc_gettext)(const char * msgid);
static char* (*libc_dgettext)(const char * domainname, const char * msgid);
extern char* __dgettext(const char * domainname, const char * msgid);
extern char* __dcgettext(const char * domainname, const char * msgid, int category);
static char* (*libc_ngettext)(const char *msgid, const char *msgid_plural, unsigned long int n);
static char* (*libc_dcngettext)(const char *domainname, const char *msgid, const char *msgid_plural, unsigned long int n, int category);
static char* (*libc_setlocale)(int category, const char *locale);
static char* (*libc_textdomain)(const char * domainname);
static int (*libc_execve)(const char *pathname, char *const argv[], char *const envp[]);
static int (*libc_execv)(const char *pathname, char *const argv[]);
static int (*libc_execvp)(const char *file, char *const argv[]);
static int (*libc_execvpe)(const char *file, char *const argv[], char *const envp[]);
// Get the address for all the wrapped libc functions. Some of these functions may get called
// very early. Therefore we do check for initialization right before use with the iss() macro.
int dw_init_stubs = 0;
// size_t (*dw_strlen)(const char *s);
void dw_init_syscall_stubs() {
libc_strlen = dw_strlen;
libc_strchr = dlsym_check(RTLD_NEXT, "strchr");
libc_strrchr = dlsym_check(RTLD_NEXT, "strrchr");
libc_strcmp = dlsym_check(RTLD_NEXT, "strcmp");
libc_strncmp = dlsym_check(RTLD_NEXT, "strncmp");
libc_fputs = dlsym_check(RTLD_NEXT, "fputs");
libc_puts = dlsym_check(RTLD_NEXT, "puts");
libc_open = dlsym_check(RTLD_NEXT, "open");
libc_openat = dlsym_check(RTLD_NEXT, "openat");
libc_creat = dlsym_check(RTLD_NEXT, "creat");
libc_access = dlsym_check(RTLD_NEXT, "access");
libc_getcwd = dlsym_check(RTLD_NEXT, "getcwd");
libc_getrandom = dlsym_check(RTLD_NEXT, "getrandom");
libc_stat = dlsym_check(RTLD_NEXT, "stat");
libc_fstat = dlsym_check(RTLD_NEXT, "fstat");
libc_lstat = dlsym_check(RTLD_NEXT, "lstat");
libc_fstatat = dlsym_check(RTLD_NEXT, "fstatat");
libc_fread = dlsym_check(RTLD_NEXT, "fread");
libc_fwrite = dlsym_check(RTLD_NEXT, "fwrite");
libc_pread = dlsym_check(RTLD_NEXT, "pread");
libc_pwrite = dlsym_check(RTLD_NEXT, "pwrite");
libc_read = __read; // dlsym_check(RTLD_NEXT, "read");
libc_write = dlsym_check(RTLD_NEXT, "write");
libc_statfs = dlsym_check(RTLD_NEXT, "statfs");
libc_fstatfs = dlsym_check(RTLD_NEXT, "fstatfs");
libc_getdents64 = dlsym_check(RTLD_NEXT, "getdents64");
libc_bcmp = dlsym_check(RTLD_NEXT, "bcmp");
libc_bcopy = dlsym_check(RTLD_NEXT, "bcopy");
libc_bzero = dlsym_check(RTLD_NEXT, "bzero");
libc_memccpy = dlsym_check(RTLD_NEXT, "memccpy");
libc_memchr = dlsym_check(RTLD_NEXT, "memchr");
libc_memcmp = dlsym_check(RTLD_NEXT, "memcmp");
libc_memcpy = dlsym_check(RTLD_NEXT, "memcpy");
libc_memcpy_chk = dlsym_check(RTLD_NEXT, "__memcpy_chk");
libc_memfrob = dlsym_check(RTLD_NEXT, "memfrob");
libc_memmem = dlsym_check(RTLD_NEXT, "memmem");
libc_memmove = dlsym_check(RTLD_NEXT, "memmove");
libc_mempcpy = dlsym_check(RTLD_NEXT, "mempcpy");
libc_memset = dlsym_check(RTLD_NEXT, "memset");
libc_strcpy = dlsym_check(RTLD_NEXT, "strcpy");
libc_strcat = dlsym_check(RTLD_NEXT, "strcat");
libc_strncpy = dlsym_check(RTLD_NEXT, "strncpy");
libc_wmemmove = dlsym_check(RTLD_NEXT, "wmemmove");
libc_wmempcpy = dlsym_check(RTLD_NEXT, "wmempcpy");
libc_wmemcpy = dlsym_check(RTLD_NEXT, "wmemcpy");
libc_gettext = dlsym_check(RTLD_NEXT, "gettext");
libc_dgettext = __dgettext; // dlsym_check(RTLD_NEXT, "dgettext ");
libc_ngettext = dlsym_check(RTLD_NEXT, "ngettext");
libc_dcngettext = dlsym_check(RTLD_NEXT, "dcngettext");
libc_setlocale = dlsym_check(RTLD_NEXT, "setlocale");
libc_opendir = dlsym_check(RTLD_NEXT, "opendir");
libc_textdomain = dlsym_check(RTLD_NEXT, "textdomain");
libc_execve = dlsym_check(RTLD_NEXT, "execve");
libc_execv = dlsym_check(RTLD_NEXT, "execv");
libc_execvp = dlsym_check(RTLD_NEXT, "execvp");
libc_execvpe = dlsym_check(RTLD_NEXT, "execvpe");
dw_init_stubs = 1;
}
// Make it shorter, every function calls those
#define sin() dw_sin()
#define sout() dw_sout()
// For each tainted pointer passed to a wrapper, we could eventually check if it is accessed properly,
// given the semantics of the function called and the bounds of the pointed object.
// The replacements for libc functions for now simply remove the taint before calling
// the replaced functions. In some cases, the taint must be reapplied. For instance,
// the memccpy function copies a string to a certain character then returns a pointer to
// that character. This pointer may be derived from a tainted pointer and the taint must be
// carried to it from the dest pointer.
size_t strlen(const char *s) { sin(); size_t ret = libc_strlen(dw_unprotect((void *)s)); dw_reprotect((void *)s); sout(); return ret; }
#include "dw-printf.h"
static inline void fputc_wrapper(char c, void* extra_arg)
{
FILE *fp = (FILE *)extra_arg;
fputc(c, fp);
}
static inline void dputc_wrapper(char c, void* extra_arg)
{
int fd = (int)((uintptr_t)extra_arg);
libc_write(fd, &c, 1);
}
int __fprintf_chk(FILE *stream, int flag, const char *format, ...) {
va_list arg; va_start(arg, format);
const int ret = vfctprintf(fputc_wrapper, (void *)stream, format, arg);
va_end(arg);
return ret;
}
int fprintf(FILE *stream, const char *format, ...) {
va_list arg; va_start(arg, format);
const int ret = vfctprintf(fputc_wrapper, (void *)stream, format, arg);
va_end(arg);
return ret;
}
int dprintf(int fd, const char *format, ...) {
va_list arg; va_start(arg, format);
const int ret = vfctprintf(dputc_wrapper, (void *)((uintptr_t)fd), format, arg);
va_end(arg);
return ret;
}
int __sprintf_chk(char *s, int flag, size_t os, const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
const int ret = vsnprintf(s, os, fmt, arg);
va_end(arg);
return ret;
}
int __snprintf_chk(char *s, size_t maxlen, int flag, size_t os, const char *fmt, ...) {
va_list arg;
va_start(arg, fmt);
const int ret = vsnprintf(s, os, fmt, arg);
va_end(arg);
return ret;
}
int vfprintf(FILE *restrict stream, const char *restrict format, va_list arg)
{
return vfctprintf(fputc_wrapper, (void *)stream, format, arg);
}
int vdprintf(int fd, const char *restrict format, va_list arg)
{
return vfctprintf(dputc_wrapper, (void *)((uintptr_t)fd), format, arg);
}
char *strchr(const char *s, int c) { sin(); char *ns = dw_unprotect((void *)s); dw_check_access((void *)s, libc_strlen(ns) + 1); char *ret = libc_strchr(ns, c); dw_reprotect((void *)s); sout(); if(ret == NULL) return ret; return (void *)dw_retaint(ret, s); }
char *strrchr(const char *s, int c) { sin(); char *ns = dw_unprotect((void *)s); dw_check_access((void *)s, libc_strlen(ns) + 1); char *ret = libc_strrchr(ns, c); dw_reprotect((void *)s); sout(); if(ret == NULL) return ret; return (void *)dw_retaint(ret, s); }
int strcmp(const char *s1, const char *s2) { sin(); char *ns1 = dw_unprotect((void *)s1); dw_check_access((void *)s1, libc_strlen(ns1) + 1); char *ns2 = dw_unprotect((void *)s2); dw_check_access((void *)s2, libc_strlen(ns2) + 1); int ret = libc_strcmp(ns1, ns2); dw_reprotect((void *)s1); dw_reprotect((void *)s2); sout(); return ret; }
int strncmp(const char *s1, const char *s2, size_t n) { sin(); char *ns1 = dw_unprotect((void *)s1); dw_check_access((void *)s1, MIN(n, libc_strlen(ns1) + 1)); char *ns2 = dw_unprotect((void *)s2); dw_check_access((void *)s2, MIN(n, libc_strlen(ns2) + 1)); int ret = libc_strncmp(ns1, ns2, n); dw_reprotect((void *)s1); dw_reprotect((void *)s2); sout(); return ret; }
int fputs(const char *restrict s, FILE *restrict stream) { sin(); char *ns = dw_unprotect((void *)s); dw_check_access((void *)s, libc_strlen(ns) + 1); int ret = libc_fputs(ns, stream); dw_reprotect((void *)s); sout(); return ret; }
int puts(const char *s) { sin(); char *ns = dw_unprotect((void *)s); dw_check_access((void *)s, libc_strlen(ns) + 1); int ret = libc_puts(ns); dw_reprotect((void *)s); sout(); return ret; }
// Open can take 2 or 3 arguments, we handle it just like glibc does it internally.
int open(const char *pathname, int flags, ...) {
sin();
mode_t mode = 0;
if(__OPEN_NEEDS_MODE(flags)) {
va_list arg;
va_start(arg, flags);
mode = va_arg(arg, mode_t);
va_end(arg);
}
char *npathname = dw_unprotect((void *)pathname);
dw_check_access((void *)pathname, libc_strlen(npathname) + 1); int ret = libc_open(npathname, flags, mode);
dw_reprotect((void *)pathname); sout(); return ret;
}
int openat(int dirfd, const char *pathname, int flags, ...) {
sin();
mode_t mode = 0;
if(__OPEN_NEEDS_MODE(flags)) {
va_list arg;
va_start(arg, flags);
mode = va_arg(arg, mode_t);
va_end(arg);
}
char *npathname = dw_unprotect((void *)pathname);
dw_check_access((void *)pathname, libc_strlen(npathname) + 1); int ret = libc_openat(dirfd, npathname, flags, mode);
dw_reprotect((void *)pathname); sout(); return ret;
}
int creat(const char *pathname, mode_t mode) { sin(); char *npathname = dw_unprotect((void *)pathname); dw_check_access((void *)pathname, libc_strlen(npathname) + 1); int ret = libc_creat(npathname, mode); dw_reprotect((void *)pathname); sout(); return ret; }
int access(const char *pathname, int mode) { sin(); char *npathname = dw_unprotect((void *)pathname); dw_check_access((void *)pathname, libc_strlen(npathname) + 1); int ret = libc_access(npathname, mode); dw_reprotect((void *)pathname); sout(); return ret; }
char *getcwd(char *buf, size_t size) { sin(); dw_check_access((void *)buf, size); char *ret = libc_getcwd(dw_unprotect((void *)buf), size); dw_reprotect((void *)buf); sout(); if(ret == dw_untaint(buf)) return buf; return ret; }
ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) { sin(); dw_check_access((void *)buf, buflen); ssize_t ret = libc_getrandom(dw_unprotect(buf), buflen, flags); dw_reprotect(buf); sout(); return ret; }
int stat(const char *restrict pathname, struct stat *restrict statbuf) { sin(); char *npathname = dw_unprotect((void *)pathname); dw_check_access((void *)pathname, libc_strlen(npathname) + 1); dw_check_access((void *)statbuf, sizeof(struct stat)); int ret = libc_stat(npathname, (struct stat *)dw_unprotect((void *)statbuf)); dw_reprotect((void *)pathname); dw_reprotect((void *)statbuf); sout(); return ret; }
int fstat(int fd, struct stat *statbuf) { sin(); dw_check_access((void *)statbuf, sizeof(struct stat)); int ret = libc_fstat(fd, (struct stat *)dw_unprotect(statbuf)); dw_reprotect(statbuf); sout(); return ret; }
int lstat(const char *restrict pathname, struct stat *restrict statbuf) { sin(); char *npathname = dw_unprotect((void *)pathname); dw_check_access((void *)pathname, libc_strlen(npathname) + 1); dw_check_access((void *)statbuf, sizeof(struct stat)); int ret = libc_lstat(npathname, (struct stat *)dw_unprotect((void *)statbuf)); dw_reprotect((void *)pathname); dw_reprotect((void *)statbuf); sout(); return ret; }
int fstatat(int dirfd, const char *restrict pathname, struct stat *restrict statbuf, int flags) { sin(); char *npathname = dw_unprotect((void *)pathname); dw_check_access((void *)pathname, libc_strlen(npathname) + 1); dw_check_access((void *)statbuf, sizeof(struct stat)); int ret = libc_fstatat(dirfd, npathname, (struct stat *)dw_unprotect((void *)statbuf), flags); dw_reprotect((void *)pathname); dw_reprotect((void *)statbuf); sout(); return ret; }
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { sin(); dw_check_access(ptr, size * nmemb); ssize_t ret = libc_fread(dw_unprotect(ptr), size, nmemb, stream); dw_reprotect(ptr); sout(); return ret; }
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { sin(); dw_check_access(ptr, size * nmemb); ssize_t ret = libc_fwrite((const void *)dw_unprotect(ptr), size, nmemb, stream); dw_reprotect(ptr); sout(); return ret; }
ssize_t pread(int fd, void *buf, size_t count, off_t offset) { sin(); dw_check_access(buf, count); ssize_t ret = libc_pread(fd, dw_unprotect(buf), count, offset); dw_reprotect(buf); sout(); return ret; }
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) { sin(); dw_check_access(buf, count); ssize_t ret = libc_pwrite(fd, (const void *)dw_unprotect(buf), count, offset); dw_reprotect(buf); sout(); return ret; }
ssize_t read(int fd, void *buf, size_t count) { sin(); dw_check_access(buf, count); ssize_t ret = libc_read(fd, dw_unprotect(buf), count); dw_reprotect(buf); sout(); return ret; }
ssize_t write(int fd, const void *buf, size_t count) { sin(); dw_check_access(buf, count); ssize_t ret = libc_write(fd, (const void *)dw_unprotect(buf), count); dw_reprotect(buf); sout(); return ret; }
int statfs(const char *path, struct statfs *buf) { sin(); char *npath = dw_unprotect((void *)path); dw_check_access((void *)path, libc_strlen(npath) + 1); dw_check_access((void *)buf, sizeof(struct statfs)); int ret = libc_statfs(npath, (struct statfs *)dw_unprotect((void *)buf)); dw_reprotect((void *)path); dw_reprotect((void *)buf); sout(); return ret; }
int fstatfs(int fd, struct statfs *buf) { sin(); dw_check_access((void *)buf, sizeof(struct statfs)); int ret = libc_fstatfs(fd, (struct statfs *)dw_unprotect((void *)buf)); dw_reprotect((void *)buf); sout(); return ret; }
ssize_t getdents64(int fd, void *dirp, size_t count) { sin(); dw_check_access(dirp, count); ssize_t ret = libc_getdents64(fd, dw_unprotect(dirp), count); dw_reprotect(dirp); sout(); return ret; }
DIR *opendir(const char *name) { sin(); char *nname = dw_unprotect((void *)name); dw_check_access((void *)name, libc_strlen(nname) + 1); DIR *ret = libc_opendir(nname); dw_reprotect(name); sout(); return ret; }
int bcmp(const void *s1, const void *s2, size_t n) { sin(); dw_check_access(s1, n); dw_check_access(s2, n); int ret = libc_bcmp((const void *)dw_unprotect(s1), (const void *)dw_unprotect(s2), n); dw_reprotect(s1); dw_reprotect(s2); sout(); return ret; }
void bcopy(const void *src, void *dest, size_t n) { sin(); dw_check_access(src, n); dw_check_access(dest, n); libc_bcopy((const void *)dw_unprotect(src), (void *)dw_unprotect(dest), n); dw_reprotect(src); dw_reprotect(dest); sout(); }
void bzero(void *s, size_t n) { sin(); dw_check_access(s, n); libc_bzero((void *)dw_unprotect(s), n); dw_reprotect(s); sout(); }
void *memccpy(void *dest, const void *src, int c, size_t n) {
sin();
dw_check_access(dest, n); dw_check_access(src, n);
void *ret = libc_memccpy((void *)dw_unprotect(dest), (const void *)dw_unprotect(src), c, n);
dw_reprotect(dest);
dw_reprotect(src);
sout();
if(ret == NULL) return ret;
return (void *)dw_retaint(ret, dest);
}
void *memchr(const void *s, int c, size_t n) {
sin();
dw_check_access(s, n);
void *ret = libc_memchr((const void *)dw_unprotect(s), c, n);
dw_reprotect(s);
sout();
if(ret == NULL) return ret;
return (void *)dw_retaint(ret, s);
}
int memcmp(const void *s1, const void *s2, size_t n) { sin(); dw_check_access(s1, n); dw_check_access(s2, n); int ret = libc_memcmp((const void *)dw_unprotect(s1), (const void *)dw_unprotect(s2), n); dw_reprotect(s1); dw_reprotect(s2); sout(); return ret; }
void *memcpy(void *dest, const void *src, size_t n) { sin(); dw_check_access(dest, n); dw_check_access(src, n); libc_memcpy((void *)dw_unprotect(dest), (const void *)dw_unprotect(src), n); dw_reprotect(dest); dw_reprotect(src); sout(); return dest; }
void *__memcpy_chk(void *dest, const void *src, size_t len, size_t destlen) { sin(); dw_check_access(dest, destlen); dw_check_access(src, len); libc_memcpy_chk((void *)dw_unprotect(dest), (const void *)dw_unprotect(src), len, destlen); dw_reprotect(dest); dw_reprotect(src); sout(); return dest; }
// void *memfrob(void *s, size_t n) { sin(); return libc_memfrob(void *s, size_t n); }
void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
sin();
dw_check_access(haystack, haystacklen); dw_check_access(needle, needlelen);
void *ret = libc_memmem((const void *)dw_unprotect(haystack), haystacklen, (const void *)dw_unprotect(needle), needlelen);
dw_reprotect(haystack); dw_reprotect(needle);
sout();
if(ret == NULL) return ret;
return (void *)dw_retaint(ret, haystack);
}
void *memmove(void *dest, const void *src, size_t n) { sin(); dw_check_access(dest, n); dw_check_access(src, n); libc_memmove((void *)dw_unprotect(dest), (void *)dw_unprotect(src), n); dw_reprotect(dest); dw_reprotect(src); sout(); return dest; }
void *mempcpy(void *restrict dest, const void *restrict src, size_t n) { sin(); dw_check_access(dest, n); dw_check_access(src, n); libc_mempcpy((void *)dw_unprotect(dest), (void *)dw_unprotect(src), n); dw_reprotect(dest); dw_reprotect(src); sout(); return dest; }
void *memset(void *s, int c, size_t n) { sin(); dw_check_access(s, n); libc_memset((void *)dw_unprotect(s), c, n); dw_reprotect(s); sout(); return s; }
char *strcpy(char *restrict dest, const char *src) { sin(); char *ndest = dw_unprotect((void *)dest); char *nsrc = dw_unprotect((void *)src); size_t len = libc_strlen(nsrc) + 1; dw_check_access(dest, len); dw_check_access(src, len); libc_strcpy(ndest, nsrc); dw_reprotect(dest); dw_reprotect(src); sout(); return dest;}
char *strcat(char *restrict dest, const char *src) { sin(); char *ndest = dw_unprotect((void *)dest); char *nsrc = dw_unprotect((void *)src); size_t dst_len = libc_strlen(ndest); size_t src_len = libc_strlen(nsrc); dw_check_access(dest, dst_len + src_len + 1); dw_check_access(src, src_len + 1); libc_strcat(ndest, nsrc); dw_reprotect(dest); dw_reprotect(src); sout(); return dest;}
char *strncpy(char *restrict dest, const char *restrict src, size_t n) { sin(); char *nsrc = dw_unprotect((void *)src); size_t len = libc_strlen(nsrc) + 1; dw_check_access(dest, n); dw_check_access(src, len < n ? len : n); libc_strncpy(dw_unprotect(dest), nsrc, n); dw_reprotect(dest); dw_reprotect(src); sout(); return dest; }
wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t n) { sin(); dw_check_access(dest, n * sizeof(wchar_t)); dw_check_access(src, n * sizeof(wchar_t)); libc_wmemmove((wchar_t *)dw_unprotect(dest), (wchar_t *)dw_unprotect(src), n); dw_reprotect(dest); dw_reprotect(src); sout(); return dest; }
wchar_t *wmempcpy(wchar_t *restrict dest, const wchar_t *restrict src, size_t n) {
sin();
dw_check_access(dest, n * sizeof(wchar_t)); dw_check_access(src, n * sizeof(wchar_t));
wchar_t *ret = libc_wmempcpy((wchar_t *)dw_unprotect(dest), (wchar_t *)dw_unprotect(src), n);
dw_reprotect(dest); dw_reprotect(src);
sout(); return (wchar_t *)dw_retaint(ret, dest);
}
wchar_t *wmemcpy(wchar_t *restrict dest, const wchar_t *restrict src, size_t n) { sin(); dw_check_access(dest, n * sizeof(wchar_t)); dw_check_access(src, n * sizeof(wchar_t)); libc_wmemcpy((wchar_t *)dw_unprotect(dest), (wchar_t *)dw_unprotect(src), n); dw_reprotect(dest); dw_reprotect(src); sout(); return dest; }
char *gettext (const char * msgid) { sin(); char *nmsgid = dw_unprotect((void *)msgid); dw_check_access((void *)msgid, libc_strlen(nmsgid) + 1); char *ret = libc_gettext(nmsgid); dw_reprotect(msgid); sout(); if(ret == nmsgid) return (char *)msgid; else return ret; }
char *dgettext (const char * domainname, const char * msgid) { sin(); char *ndomainname = dw_unprotect((void *)domainname); char *nmsgid = dw_unprotect((void *)msgid); dw_check_access((void *)domainname, libc_strlen(ndomainname) + 1); dw_check_access((void *)msgid, libc_strlen(nmsgid) + 1); char *ret = libc_dgettext(ndomainname, nmsgid); dw_reprotect(domainname); dw_reprotect(msgid); sout(); if(ret == nmsgid) return (char *)msgid; else return ret; }
char *dcgettext (const char * domainname, const char * msgid, int category) { sin(); char *ndomainname = dw_unprotect((void *)domainname); char *nmsgid = dw_unprotect((void *)msgid); dw_check_access((void *)domainname, libc_strlen(ndomainname) + 1); dw_check_access((void *)msgid, libc_strlen(nmsgid) + 1); char *ret = __dcgettext (ndomainname, nmsgid, category); dw_reprotect(domainname); dw_reprotect(msgid); sout(); if(ret == nmsgid) return (char *)msgid; else return ret; }
char *ngettext(const char *msgid, const char *msgid_plural, unsigned long int n) { sin(); char *nmsgid = dw_unprotect((void *)msgid); char *nmsgid_plural = dw_unprotect((void *)msgid_plural); dw_check_access((void *)msgid, libc_strlen(nmsgid) + 1); dw_check_access((void *)msgid_plural, libc_strlen(nmsgid_plural) + 1); char *ret = libc_ngettext(nmsgid, nmsgid_plural, n); dw_reprotect(msgid); dw_reprotect(msgid_plural); sout(); if(ret == nmsgid) return (char *)msgid; else if(ret == nmsgid_plural) return (char *)msgid_plural; else return ret; }
char *dcngettext(const char *domainname, const char *msgid, const char *msgid_plural, unsigned long int n, int category) { sin(); char *ndomainname = dw_unprotect((void *)domainname); char *nmsgid = dw_unprotect((void *)msgid); char *nmsgid_plural = dw_unprotect((void *)msgid_plural); dw_check_access((void *)domainname, libc_strlen(ndomainname) + 1); dw_check_access((void *)msgid, libc_strlen(nmsgid) + 1); dw_check_access((void *)msgid_plural, libc_strlen(nmsgid_plural) + 1); char *ret = libc_dcngettext(ndomainname, nmsgid, nmsgid_plural, n, category); dw_reprotect(domainname); dw_reprotect(msgid); dw_reprotect(msgid_plural); sout(); if(ret == nmsgid) return (char *)msgid; else if(ret == nmsgid_plural) return (char *)msgid_plural; else return ret; }
char *setlocale(int category, const char *locale) { sin(); char *nlocale = dw_unprotect((void *)locale); dw_check_access((void *)locale, libc_strlen(nlocale) + 1); char *ret = libc_setlocale(category, nlocale); dw_reprotect(locale); sout(); return ret; }
char *textdomain(const char * domainname) { sin(); char *ndomainname = dw_unprotect((void *)domainname); dw_check_access((void *)domainname, libc_strlen(ndomainname) + 1); char *ret = libc_textdomain(ndomainname); dw_reprotect(domainname); sout(); return ret; }
int execve(const char *pathname, char *const argv[], char *const envp[]) { sin(); char *npathname = dw_unprotect((void *)pathname); dw_check_access((void *)pathname, libc_strlen(npathname) + 1); dw_check_access((void *)argv, arglen(argv)); dw_check_access((void *)envp, arglen(envp)); int ret = libc_execve(npathname, dw_unprotect(argv), dw_unprotect(envp)); dw_reprotect(pathname); dw_reprotect(argv); dw_reprotect(envp); sout(); return ret; }
int execv(const char *pathname, char *const argv[]) { sin(); char *npathname = dw_unprotect((void *)pathname); dw_check_access((void *)pathname, libc_strlen(npathname) + 1); dw_check_access((void *)argv, arglen(argv)); int ret = libc_execv(npathname, dw_unprotect(argv)); dw_reprotect(pathname); dw_reprotect(argv); sout(); return ret; }
int execvp(const char *file, char *const argv[]) { sin(); char *nfile = dw_unprotect((void *)file); dw_check_access((void *)file, libc_strlen(nfile) + 1); dw_check_access((void *)argv, arglen(argv)); int ret = libc_execvp(nfile, dw_unprotect(argv)); dw_reprotect(file); dw_reprotect(argv); sout(); return ret; }
int execvpe(const char *file, char *const argv[], char *const envp[]) { sin(); char *nfile = dw_unprotect((void *)file); dw_check_access((void *)file, libc_strlen(nfile) + 1); dw_check_access((void *)argv, arglen(argv)); dw_check_access((void *)envp, arglen(envp)); int ret = libc_execvpe(nfile, dw_unprotect(argv), dw_unprotect(envp)); dw_reprotect(file); dw_reprotect(argv); dw_reprotect(envp); sout(); return ret; }