master
  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