1 | //===-- sanitizer_common_interceptors_netbsd_compat.inc ---------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // Common function interceptors for tools like AddressSanitizer, |
10 | // ThreadSanitizer, MemorySanitizer, etc. |
11 | // |
12 | // Interceptors for NetBSD old function calls that have been versioned. |
13 | // |
14 | // NetBSD minimal version supported 9.0. |
15 | // NetBSD current version supported 9.99.26. |
16 | // |
17 | //===----------------------------------------------------------------------===// |
18 | |
19 | #if SANITIZER_NETBSD |
20 | |
21 | // First undef all mangled symbols. |
22 | // Next, define compat interceptors. |
23 | // Finally, undef INIT_ and redefine it. |
24 | // This allows to avoid preprocessor issues. |
25 | |
26 | #undef fstatvfs |
27 | #undef fstatvfs1 |
28 | #undef getmntinfo |
29 | #undef getvfsstat |
30 | #undef statvfs |
31 | #undef statvfs1 |
32 | |
33 | INTERCEPTOR(int, statvfs, char *path, void *buf) { |
34 | void *ctx; |
35 | COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf); |
36 | if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); |
37 | // FIXME: under ASan the call below may write to freed memory and corrupt |
38 | // its metadata. See |
39 | // https://github.com/google/sanitizers/issues/321. |
40 | int res = REAL(statvfs)(path, buf); |
41 | if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); |
42 | return res; |
43 | } |
44 | |
45 | INTERCEPTOR(int, fstatvfs, int fd, void *buf) { |
46 | void *ctx; |
47 | COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); |
48 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
49 | // FIXME: under ASan the call below may write to freed memory and corrupt |
50 | // its metadata. See |
51 | // https://github.com/google/sanitizers/issues/321. |
52 | int res = REAL(fstatvfs)(fd, buf); |
53 | if (!res) { |
54 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); |
55 | if (fd >= 0) |
56 | COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); |
57 | } |
58 | return res; |
59 | } |
60 | |
61 | #undef INIT_STATVFS |
62 | #define INIT_STATVFS \ |
63 | COMMON_INTERCEPT_FUNCTION(statvfs); \ |
64 | COMMON_INTERCEPT_FUNCTION(fstatvfs); \ |
65 | COMMON_INTERCEPT_FUNCTION(__statvfs90); \ |
66 | COMMON_INTERCEPT_FUNCTION(__fstatvfs90) |
67 | |
68 | INTERCEPTOR(int, __getmntinfo13, void **mntbufp, int flags) { |
69 | void *ctx; |
70 | COMMON_INTERCEPTOR_ENTER(ctx, __getmntinfo13, mntbufp, flags); |
71 | int cnt = REAL(__getmntinfo13)(mntbufp, flags); |
72 | if (cnt > 0 && mntbufp) { |
73 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *)); |
74 | if (*mntbufp) |
75 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs90_sz); |
76 | } |
77 | return cnt; |
78 | } |
79 | |
80 | #undef INIT_GETMNTINFO |
81 | #define INIT_GETMNTINFO \ |
82 | COMMON_INTERCEPT_FUNCTION(__getmntinfo13); \ |
83 | COMMON_INTERCEPT_FUNCTION(__getmntinfo90) |
84 | |
85 | INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) { |
86 | void *ctx; |
87 | COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags); |
88 | int ret = REAL(getvfsstat)(buf, bufsize, flags); |
89 | if (buf && ret > 0) |
90 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs90_sz); |
91 | return ret; |
92 | } |
93 | |
94 | #undef INIT_GETVFSSTAT |
95 | #define INIT_GETVFSSTAT \ |
96 | COMMON_INTERCEPT_FUNCTION(getvfsstat); \ |
97 | COMMON_INTERCEPT_FUNCTION(__getvfsstat90) |
98 | |
99 | INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) { |
100 | void *ctx; |
101 | COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags); |
102 | if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1); |
103 | int res = REAL(statvfs1)(path, buf, flags); |
104 | if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); |
105 | return res; |
106 | } |
107 | |
108 | INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) { |
109 | void *ctx; |
110 | COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags); |
111 | COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); |
112 | int res = REAL(fstatvfs1)(fd, buf, flags); |
113 | if (!res) { |
114 | COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); |
115 | if (fd >= 0) |
116 | COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); |
117 | } |
118 | return res; |
119 | } |
120 | |
121 | #undef INIT_STATVFS1 |
122 | #define INIT_STATVFS1 \ |
123 | COMMON_INTERCEPT_FUNCTION(statvfs1); \ |
124 | COMMON_INTERCEPT_FUNCTION(fstatvfs1); \ |
125 | COMMON_INTERCEPT_FUNCTION(__statvfs190); \ |
126 | COMMON_INTERCEPT_FUNCTION(__fstatvfs190) |
127 | |
128 | #endif |
129 | |