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, REAL(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, REAL(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