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
33INTERCEPTOR(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
45INTERCEPTOR(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
68INTERCEPTOR(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
85INTERCEPTOR(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
99INTERCEPTOR(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
108INTERCEPTOR(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