forked from OSchip/llvm-project
[compiler-rt] [netbsd] Add support for versioned statvfs interceptors
Summary: Add support for NetBSD 9.0 and newer versions of interceptors operating on struct statvfs: fstatvfs, fstatvfs1, getmntinfo, getvfsstat, statvfs, statvfs1. The default promoted interceptors are for NetBSD 9.99.26. Older ones (currently 9.0) are kept in a new NetBSD specific file: /sanitizer_common_interceptors_netbsd_compat.inc. This file defines compat interceptors and mangles `INIT_*` macros, concatenating the current interceptors and the compat ones. This redefinition is not elegant, but it avoids preprocessor madness. Define struct_statvfs90_sz for the compat purposes. Reviewers: mgorny, kcc, vitalybuka, joerg Reviewed By: mgorny Subscribers: dberris, llvm-commits, #sanitizers Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D71700
This commit is contained in:
parent
1584e2f987
commit
78f714f824
|
@ -79,13 +79,15 @@
|
|||
#define devname __devname50
|
||||
#define fgetpos __fgetpos50
|
||||
#define fsetpos __fsetpos50
|
||||
#define fstatvfs __fstatvfs90
|
||||
#define fstatvfs1 __fstatvfs190
|
||||
#define fts_children __fts_children60
|
||||
#define fts_close __fts_close60
|
||||
#define fts_open __fts_open60
|
||||
#define fts_read __fts_read60
|
||||
#define fts_set __fts_set60
|
||||
#define getitimer __getitimer50
|
||||
#define getmntinfo __getmntinfo13
|
||||
#define getmntinfo __getmntinfo90
|
||||
#define getpwent __getpwent50
|
||||
#define getpwnam __getpwnam50
|
||||
#define getpwnam_r __getpwnam_r50
|
||||
|
@ -95,6 +97,7 @@
|
|||
#define getutxent __getutxent50
|
||||
#define getutxid __getutxid50
|
||||
#define getutxline __getutxline50
|
||||
#define getvfsstat __getvfsstat90
|
||||
#define pututxline __pututxline50
|
||||
#define glob __glob30
|
||||
#define gmtime __gmtime50
|
||||
|
@ -116,6 +119,8 @@
|
|||
#define sigprocmask __sigprocmask14
|
||||
#define sigtimedwait __sigtimedwait50
|
||||
#define stat __stat50
|
||||
#define statvfs __statvfs90
|
||||
#define statvfs1 __statvfs190
|
||||
#define time __time50
|
||||
#define times __times13
|
||||
#define unvis __unvis50
|
||||
|
@ -9708,6 +9713,8 @@ INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size,
|
|||
#define INIT_QSORT_R
|
||||
#endif
|
||||
|
||||
#include "sanitizer_common_interceptors_netbsd_compat.inc"
|
||||
|
||||
static void InitializeCommonInterceptors() {
|
||||
#if SI_POSIX
|
||||
static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
//===-- sanitizer_common_interceptors_netbsd_compat.inc ---------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Common function interceptors for tools like AddressSanitizer,
|
||||
// ThreadSanitizer, MemorySanitizer, etc.
|
||||
//
|
||||
// Interceptors for NetBSD old function calls that have been versioned.
|
||||
//
|
||||
// NetBSD minimal version supported 9.0.
|
||||
// NetBSD current version supported 9.99.26.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if SANITIZER_NETBSD
|
||||
|
||||
// First undef all mangled symbols.
|
||||
// Next, define compat interceptors.
|
||||
// Finally, undef INIT_ and redefine it. This allows to avoid preprocessor issues.
|
||||
|
||||
#undef fstatvfs
|
||||
#undef fstatvfs1
|
||||
#undef getmntinfo
|
||||
#undef getvfsstat
|
||||
#undef statvfs
|
||||
#undef statvfs1
|
||||
|
||||
INTERCEPTOR(int, statvfs, char *path, void *buf) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
|
||||
if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
|
||||
// FIXME: under ASan the call below may write to freed memory and corrupt
|
||||
// its metadata. See
|
||||
// https://github.com/google/sanitizers/issues/321.
|
||||
int res = REAL(statvfs)(path, buf);
|
||||
if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz);
|
||||
return res;
|
||||
}
|
||||
|
||||
INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
|
||||
COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
|
||||
// FIXME: under ASan the call below may write to freed memory and corrupt
|
||||
// its metadata. See
|
||||
// https://github.com/google/sanitizers/issues/321.
|
||||
int res = REAL(fstatvfs)(fd, buf);
|
||||
if (!res) {
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz);
|
||||
if (fd >= 0)
|
||||
COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef INIT_STATVFS
|
||||
#define INIT_STATVFS \
|
||||
COMMON_INTERCEPT_FUNCTION(statvfs); \
|
||||
COMMON_INTERCEPT_FUNCTION(fstatvfs); \
|
||||
COMMON_INTERCEPT_FUNCTION(__statvfs90); \
|
||||
COMMON_INTERCEPT_FUNCTION(__fstatvfs90)
|
||||
|
||||
INTERCEPTOR(int, __getmntinfo13, void **mntbufp, int flags) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, __getmntinfo13, mntbufp, flags);
|
||||
int cnt = REAL(__getmntinfo13)(mntbufp, flags);
|
||||
if (cnt > 0 && mntbufp) {
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *));
|
||||
if (*mntbufp)
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs90_sz);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#undef INIT_GETMNTINFO
|
||||
#define INIT_GETMNTINFO \
|
||||
COMMON_INTERCEPT_FUNCTION(__getmntinfo13); \
|
||||
COMMON_INTERCEPT_FUNCTION(__getmntinfo90)
|
||||
|
||||
INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags);
|
||||
int ret = REAL(getvfsstat)(buf, bufsize, flags);
|
||||
if (buf && ret > 0)
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs90_sz);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef INIT_GETVFSSTAT
|
||||
#define INIT_GETVFSSTAT \
|
||||
COMMON_INTERCEPT_FUNCTION(getvfsstat); \
|
||||
COMMON_INTERCEPT_FUNCTION(__getvfsstat90)
|
||||
|
||||
INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags);
|
||||
if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
|
||||
int res = REAL(statvfs1)(path, buf, flags);
|
||||
if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz);
|
||||
return res;
|
||||
}
|
||||
|
||||
INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags);
|
||||
COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
|
||||
int res = REAL(fstatvfs1)(fd, buf, flags);
|
||||
if (!res) {
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs90_sz);
|
||||
if (fd >= 0)
|
||||
COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef INIT_STATVFS1
|
||||
#define INIT_STATVFS1 \
|
||||
COMMON_INTERCEPT_FUNCTION(statvfs1); \
|
||||
COMMON_INTERCEPT_FUNCTION(fstatvfs1); \
|
||||
COMMON_INTERCEPT_FUNCTION(__statvfs190); \
|
||||
COMMON_INTERCEPT_FUNCTION(__fstatvfs190)
|
||||
|
||||
#endif
|
|
@ -2414,4 +2414,42 @@ CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_flags);
|
|||
CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_props);
|
||||
CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_propslen);
|
||||
|
||||
// Compat with 9.0
|
||||
struct statvfs90 {
|
||||
unsigned long f_flag;
|
||||
unsigned long f_bsize;
|
||||
unsigned long f_frsize;
|
||||
unsigned long f_iosize;
|
||||
|
||||
u64 f_blocks;
|
||||
u64 f_bfree;
|
||||
u64 f_bavail;
|
||||
u64 f_bresvd;
|
||||
|
||||
u64 f_files;
|
||||
u64 f_ffree;
|
||||
u64 f_favail;
|
||||
u64 f_fresvd;
|
||||
|
||||
u64 f_syncreads;
|
||||
u64 f_syncwrites;
|
||||
|
||||
u64 f_asyncreads;
|
||||
u64 f_asyncwrites;
|
||||
|
||||
struct {
|
||||
s32 __fsid_val[2];
|
||||
} f_fsidx;
|
||||
unsigned long f_fsid;
|
||||
unsigned long f_namemax;
|
||||
u32 f_owner;
|
||||
|
||||
u32 f_spare[4];
|
||||
|
||||
char f_fstypename[_VFS_NAMELEN];
|
||||
char f_mntonname[_VFS_MNAMELEN];
|
||||
char f_mntfromname[_VFS_MNAMELEN];
|
||||
};
|
||||
unsigned struct_statvfs90_sz = sizeof(struct statvfs90);
|
||||
|
||||
#endif // SANITIZER_NETBSD
|
||||
|
|
|
@ -2420,6 +2420,9 @@ struct __sanitizer_cdbw {
|
|||
|
||||
#define SIGACTION_SYMNAME __sigaction14
|
||||
|
||||
// Compat with 9.0
|
||||
extern unsigned struct_statvfs90_sz;
|
||||
|
||||
#endif // SANITIZER_NETBSD
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue