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
|
//===-- sanitizer_common_syscalls.inc ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Common syscalls handlers for tools like AddressSanitizer,
// ThreadSanitizer, MemorySanitizer, etc.
//
// This file should be included into the tool's interceptor file,
// which has to define it's own macros:
// COMMON_SYSCALL_PRE_READ_RANGE
// Called in prehook for regions that will be read by the kernel and
// must be initialized.
// COMMON_SYSCALL_PRE_WRITE_RANGE
// Called in prehook for regions that will be written to by the kernel
// and must be addressable. The actual write range may be smaller than
// reported in the prehook. See POST_WRITE_RANGE.
// COMMON_SYSCALL_POST_READ_RANGE
// Called in posthook for regions that were read by the kernel. Does
// not make much sense.
// COMMON_SYSCALL_POST_WRITE_RANGE
// Called in posthook for regions that were written to by the kernel
// and are now initialized.
//===----------------------------------------------------------------------===//
#define PRE_SYSCALL(name) \
SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_pre_##name
#define PRE_READ(p, s) COMMON_SYSCALL_PRE_READ_RANGE(p, s)
#define PRE_WRITE(p, s) COMMON_SYSCALL_PRE_WRITE_RANGE(p, s)
#define POST_SYSCALL(name) \
SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_post_##name
#define POST_READ(p, s) COMMON_SYSCALL_POST_READ_RANGE(p, s)
#define POST_WRITE(p, s) COMMON_SYSCALL_POST_WRITE_RANGE(p, s)
// FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such).
extern "C" {
struct sanitizer_kernel_iovec {
void *iov_base;
unsigned long iov_len;
};
struct sanitizer_kernel_msghdr {
void *msg_name;
int msg_namelen;
struct sanitizer_kernel_iovec *msg_iov;
unsigned long msg_iovlen;
void *msg_control;
unsigned long msg_controllen;
unsigned msg_flags;
};
PRE_SYSCALL(recvmsg)(int sockfd, struct sanitizer_kernel_msghdr *msg,
int flags) {
PRE_READ(msg, sizeof(*msg));
}
POST_SYSCALL(recvmsg)(int res, int sockfd, struct sanitizer_kernel_msghdr *msg,
int flags) {
if (res > 0)
for (unsigned long i = 0; i < msg->msg_iovlen; ++i)
POST_WRITE(msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len);
POST_WRITE(msg->msg_control, msg->msg_controllen);
}
PRE_SYSCALL(rt_sigpending)(void *p, unsigned long s) { PRE_WRITE(p, s); }
POST_SYSCALL(rt_sigpending)(int res, void *p, unsigned long s) {
if (res == 0)
POST_WRITE(p, s);
}
PRE_SYSCALL(getdents)(int fd, void *dirp, int count) { PRE_WRITE(dirp, count); }
POST_SYSCALL(getdents)(int res, int fd, void *dirp, int count) {
if (res > 0)
POST_WRITE(dirp, res);
}
PRE_SYSCALL(getdents64)(int fd, void *dirp, int count) {
PRE_WRITE(dirp, count);
}
POST_SYSCALL(getdents64)(int res, int fd, void *dirp, int count) {
if (res > 0)
POST_WRITE(dirp, res);
}
} // extern "C"
#undef PRE_SYSCALL
#undef PRE_READ
#undef PRE_WRITE
#undef POST_SYSCALL
#undef POST_READ
#undef POST_WRITE
|