1356843Sdim//===-- sanitizer_common_interceptors_netbsd_compat.inc ---------*- C++ -*-===// 2356843Sdim// 3356843Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4356843Sdim// See https://llvm.org/LICENSE.txt for license information. 5356843Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6356843Sdim// 7356843Sdim//===----------------------------------------------------------------------===// 8356843Sdim// 9356843Sdim// Common function interceptors for tools like AddressSanitizer, 10356843Sdim// ThreadSanitizer, MemorySanitizer, etc. 11356843Sdim// 12356843Sdim// Interceptors for NetBSD old function calls that have been versioned. 13356843Sdim// 14356843Sdim// NetBSD minimal version supported 9.0. 15356843Sdim// NetBSD current version supported 9.99.26. 16356843Sdim// 17356843Sdim//===----------------------------------------------------------------------===// 18356843Sdim 19356843Sdim#if SANITIZER_NETBSD 20356843Sdim 21356843Sdim// First undef all mangled symbols. 22356843Sdim// Next, define compat interceptors. 23356843Sdim// Finally, undef INIT_ and redefine it. 24356843Sdim// This allows to avoid preprocessor issues. 25356843Sdim 26356843Sdim#undef fstatvfs 27356843Sdim#undef fstatvfs1 28356843Sdim#undef getmntinfo 29356843Sdim#undef getvfsstat 30356843Sdim#undef statvfs 31356843Sdim#undef statvfs1 32356843Sdim 33356843SdimINTERCEPTOR(int, statvfs, char *path, void *buf) { 34356843Sdim void *ctx; 35356843Sdim COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf); 36356843Sdim if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 37356843Sdim // FIXME: under ASan the call below may write to freed memory and corrupt 38356843Sdim // its metadata. See 39356843Sdim // https://github.com/google/sanitizers/issues/321. 40356843Sdim int res = REAL(statvfs)(path, buf); 41356843Sdim if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); 42356843Sdim return res; 43356843Sdim} 44356843Sdim 45356843SdimINTERCEPTOR(int, fstatvfs, int fd, void *buf) { 46356843Sdim void *ctx; 47356843Sdim COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); 48356843Sdim COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 49356843Sdim // FIXME: under ASan the call below may write to freed memory and corrupt 50356843Sdim // its metadata. See 51356843Sdim // https://github.com/google/sanitizers/issues/321. 52356843Sdim int res = REAL(fstatvfs)(fd, buf); 53356843Sdim if (!res) { 54356843Sdim COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); 55356843Sdim if (fd >= 0) 56356843Sdim COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 57356843Sdim } 58356843Sdim return res; 59356843Sdim} 60356843Sdim 61356843Sdim#undef INIT_STATVFS 62356843Sdim#define INIT_STATVFS \ 63356843Sdim COMMON_INTERCEPT_FUNCTION(statvfs); \ 64356843Sdim COMMON_INTERCEPT_FUNCTION(fstatvfs); \ 65356843Sdim COMMON_INTERCEPT_FUNCTION(__statvfs90); \ 66356843Sdim COMMON_INTERCEPT_FUNCTION(__fstatvfs90) 67356843Sdim 68356843SdimINTERCEPTOR(int, __getmntinfo13, void **mntbufp, int flags) { 69356843Sdim void *ctx; 70356843Sdim COMMON_INTERCEPTOR_ENTER(ctx, __getmntinfo13, mntbufp, flags); 71356843Sdim int cnt = REAL(__getmntinfo13)(mntbufp, flags); 72356843Sdim if (cnt > 0 && mntbufp) { 73356843Sdim COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *)); 74356843Sdim if (*mntbufp) 75356843Sdim COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs90_sz); 76356843Sdim } 77356843Sdim return cnt; 78356843Sdim} 79356843Sdim 80356843Sdim#undef INIT_GETMNTINFO 81356843Sdim#define INIT_GETMNTINFO \ 82356843Sdim COMMON_INTERCEPT_FUNCTION(__getmntinfo13); \ 83356843Sdim COMMON_INTERCEPT_FUNCTION(__getmntinfo90) 84356843Sdim 85356843SdimINTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) { 86356843Sdim void *ctx; 87356843Sdim COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags); 88356843Sdim int ret = REAL(getvfsstat)(buf, bufsize, flags); 89356843Sdim if (buf && ret > 0) 90356843Sdim COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs90_sz); 91356843Sdim return ret; 92356843Sdim} 93356843Sdim 94356843Sdim#undef INIT_GETVFSSTAT 95356843Sdim#define INIT_GETVFSSTAT \ 96356843Sdim COMMON_INTERCEPT_FUNCTION(getvfsstat); \ 97356843Sdim COMMON_INTERCEPT_FUNCTION(__getvfsstat90) 98356843Sdim 99356843SdimINTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) { 100356843Sdim void *ctx; 101356843Sdim COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags); 102356843Sdim if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 103356843Sdim int res = REAL(statvfs1)(path, buf, flags); 104356843Sdim if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); 105356843Sdim return res; 106356843Sdim} 107356843Sdim 108356843SdimINTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) { 109356843Sdim void *ctx; 110356843Sdim COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags); 111356843Sdim COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 112356843Sdim int res = REAL(fstatvfs1)(fd, buf, flags); 113356843Sdim if (!res) { 114356843Sdim COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz); 115356843Sdim if (fd >= 0) 116356843Sdim COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 117356843Sdim } 118356843Sdim return res; 119356843Sdim} 120356843Sdim 121356843Sdim#undef INIT_STATVFS1 122356843Sdim#define INIT_STATVFS1 \ 123356843Sdim COMMON_INTERCEPT_FUNCTION(statvfs1); \ 124356843Sdim COMMON_INTERCEPT_FUNCTION(fstatvfs1); \ 125356843Sdim COMMON_INTERCEPT_FUNCTION(__statvfs190); \ 126356843Sdim COMMON_INTERCEPT_FUNCTION(__fstatvfs190) 127356843Sdim 128356843Sdim#endif 129