forked from OSchip/llvm-project
[Sanitizer] intercept part of sysctl Api
- Distringuish what FreeBSD/NetBSD can and NetBSD specifics. - Fixing page size value collection. Reviewers: krytarowski, vitalybuka Reviewed By: krytarowski Differential Revision: https://reviews.llvm.org/D55265 llvm-svn: 348293
This commit is contained in:
parent
3d5bb15a1d
commit
2330a24ca5
|
@ -7568,6 +7568,67 @@ INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp,
|
|||
return res;
|
||||
}
|
||||
|
||||
INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name,
|
||||
SIZE_T *namelenp) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp);
|
||||
if (sname)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
|
||||
if (namelenp)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
|
||||
int res = REAL(sysctlnametomib)(sname, name, namelenp);
|
||||
if (!res) {
|
||||
if (namelenp) {
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
|
||||
if (name)
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#define INIT_SYSCTL \
|
||||
COMMON_INTERCEPT_FUNCTION(sysctl); \
|
||||
COMMON_INTERCEPT_FUNCTION(sysctlbyname); \
|
||||
COMMON_INTERCEPT_FUNCTION(sysctlnametomib);
|
||||
#else
|
||||
#define INIT_SYSCTL
|
||||
#endif
|
||||
|
||||
#if SANITIZER_INTERCEPT_ASYSCTL
|
||||
INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len);
|
||||
if (name)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen);
|
||||
void *res = REAL(asysctl)(name, namelen, len);
|
||||
if (res && len) {
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len);
|
||||
if (sname)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
|
||||
void *res = REAL(asysctlbyname)(sname, len);
|
||||
if (res && len) {
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#define INIT_ASYSCTL \
|
||||
COMMON_INTERCEPT_FUNCTION(asysctl); \
|
||||
COMMON_INTERCEPT_FUNCTION(asysctlbyname);
|
||||
#else
|
||||
#define INIT_ASYSCTL
|
||||
#endif
|
||||
|
||||
#if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO
|
||||
INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name,
|
||||
unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode,
|
||||
int v) {
|
||||
|
@ -7597,62 +7658,13 @@ INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name,
|
|||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name,
|
||||
SIZE_T *namelenp) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp);
|
||||
if (sname)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
|
||||
if (namelenp)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
|
||||
int res = REAL(sysctlnametomib)(sname, name, namelenp);
|
||||
if (!res) {
|
||||
if (namelenp) {
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
|
||||
if (name)
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len);
|
||||
if (name)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen);
|
||||
void *res = REAL(asysctl)(name, namelen, len);
|
||||
if (res && len) {
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len);
|
||||
if (sname)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
|
||||
void *res = REAL(asysctlbyname)(sname, len);
|
||||
if (res && len) {
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
|
||||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#define INIT_SYSCTL \
|
||||
COMMON_INTERCEPT_FUNCTION(sysctl); \
|
||||
COMMON_INTERCEPT_FUNCTION(sysctlbyname); \
|
||||
COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo); \
|
||||
COMMON_INTERCEPT_FUNCTION(sysctlnametomib); \
|
||||
COMMON_INTERCEPT_FUNCTION(asysctl); \
|
||||
COMMON_INTERCEPT_FUNCTION(asysctlbyname);
|
||||
#define INIT_SYSCTLGETMIBINFO \
|
||||
COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo);
|
||||
#else
|
||||
#define INIT_SYSCTL
|
||||
#define INIT_SYSCTLGETMIBINFO
|
||||
#endif
|
||||
|
||||
|
||||
static void InitializeCommonInterceptors() {
|
||||
static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
|
||||
interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
|
||||
|
@ -7913,6 +7925,8 @@ static void InitializeCommonInterceptors() {
|
|||
INIT_REGEX;
|
||||
INIT_FTS;
|
||||
INIT_SYSCTL;
|
||||
INIT_ASYSCTL;
|
||||
INIT_SYSCTLGETMIBINFO;
|
||||
|
||||
INIT___PRINTF_CHK;
|
||||
}
|
||||
|
|
|
@ -772,7 +772,7 @@ int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
|
|||
return sysctl(name, namelen, oldp, (size_t *)oldlenp, (void *)newp,
|
||||
(size_t)newlen);
|
||||
#else
|
||||
return sysctl(name, namelen, oldp, (size_t *)oldlenp, newp, (size_t)newlen);
|
||||
return internal_syscall(SYSCALL(__sysctl), name, namelen, oldp, (size_t *)oldlenp, newp, (size_t)newlen);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1076,6 +1076,14 @@ uptr GetPageSize() {
|
|||
return EXEC_PAGESIZE;
|
||||
#elif SANITIZER_USE_GETAUXVAL
|
||||
return getauxval(AT_PAGESZ);
|
||||
#elif SANITIZER_FREEBSD || SANITIZER_NETBSD
|
||||
// Use sysctl as sysconf can trigger interceptors internally.
|
||||
int pz = 0;
|
||||
uptr pzl = sizeof(pz);
|
||||
int mib[2] = {CTL_HW, HW_PAGESIZE};
|
||||
int rv = internal_sysctl(mib, 2, &pz, &pzl, nullptr, 0);
|
||||
CHECK_EQ(rv, 0);
|
||||
return (uptr)pz;
|
||||
#else
|
||||
return sysconf(_SC_PAGESIZE); // EXEC_PAGESIZE may not be trustworthy.
|
||||
#endif
|
||||
|
|
|
@ -523,6 +523,8 @@
|
|||
#define SANITIZER_INTERCEPT_GETVFSSTAT SI_NETBSD
|
||||
#define SANITIZER_INTERCEPT_REGEX SI_NETBSD
|
||||
#define SANITIZER_INTERCEPT_FTS SI_NETBSD
|
||||
#define SANITIZER_INTERCEPT_SYSCTL SI_NETBSD
|
||||
#define SANITIZER_INTERCEPT_SYSCTL (SI_NETBSD || SI_FREEBSD)
|
||||
#define SANITIZER_INTERCEPT_ASYSCTL SI_NETBSD
|
||||
#define SANITIZER_INTERCEPT_SYSCTLGETMIBINFO SI_NETBSD
|
||||
|
||||
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
|
||||
//
|
||||
// UNSUPPORTED: linux darwin solaris
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -9,6 +11,10 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef __arraycount
|
||||
#define __arraycount(a) (sizeof(a) / sizeof(a[0]))
|
||||
#endif
|
||||
|
||||
void test_sysctl() {
|
||||
char buf[100];
|
||||
size_t len = sizeof(buf);
|
||||
|
@ -22,28 +28,12 @@ void test_sysctl() {
|
|||
void test_sysctlbyname() {
|
||||
char buf[100];
|
||||
size_t len = sizeof(buf);
|
||||
int mib[] = {CTL_KERN, KERN_OSTYPE};
|
||||
int rv = sysctlbyname("kern.ostype", buf, &len, NULL, 0);
|
||||
assert(!rv);
|
||||
|
||||
printf("sysctlbyname: '%s' size: '%zu'\n", buf, len);
|
||||
}
|
||||
|
||||
void test_sysctlgetmibinfo() {
|
||||
int mib[CTL_MAXNAME];
|
||||
unsigned int mib_len = __arraycount(mib);
|
||||
int rv = sysctlgetmibinfo("kern.ostype", &mib[0], &mib_len, NULL, NULL, NULL,
|
||||
SYSCTL_VERSION);
|
||||
assert(!rv);
|
||||
|
||||
char buf[100];
|
||||
size_t len = sizeof(buf);
|
||||
rv = sysctl(mib, mib_len, buf, &len, NULL, 0);
|
||||
assert(!rv);
|
||||
|
||||
printf("sysctlgetmibinfo: '%s' size: '%zu'\n", buf, len);
|
||||
}
|
||||
|
||||
void test_sysctlnametomib() {
|
||||
int mib[CTL_MAXNAME];
|
||||
size_t mib_len = __arraycount(mib);
|
||||
|
@ -58,6 +48,7 @@ void test_sysctlnametomib() {
|
|||
printf("sysctlnametomib: '%s' size: '%zu'\n", buf, len);
|
||||
}
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
void test_asysctl() {
|
||||
int mib[] = {CTL_KERN, KERN_OSTYPE};
|
||||
size_t len;
|
||||
|
@ -79,23 +70,43 @@ void test_asysctlbyname() {
|
|||
free(buf);
|
||||
}
|
||||
|
||||
void test_sysctlgetmibinfo() {
|
||||
int mib[CTL_MAXNAME];
|
||||
unsigned int mib_len = __arraycount(mib);
|
||||
int rv = sysctlgetmibinfo("kern.ostype", &mib[0], &mib_len, NULL, NULL, NULL,
|
||||
SYSCTL_VERSION);
|
||||
assert(!rv);
|
||||
|
||||
char buf[100];
|
||||
size_t len = sizeof(buf);
|
||||
rv = sysctl(mib, mib_len, buf, &len, NULL, 0);
|
||||
assert(!rv);
|
||||
|
||||
printf("sysctlgetmibinfo: '%s' size: '%zu'\n", buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(void) {
|
||||
printf("sysctl\n");
|
||||
|
||||
test_sysctl();
|
||||
test_sysctlbyname();
|
||||
test_sysctlgetmibinfo();
|
||||
test_sysctlnametomib();
|
||||
#if defined(__NetBSD__)
|
||||
test_asysctl();
|
||||
test_asysctlbyname();
|
||||
test_sysctlgetmibinfo();
|
||||
#endif
|
||||
|
||||
// CHECK: sysctl
|
||||
// CHECK: sysctl: '{{.*}}' size: '{{.*}}'
|
||||
// CHECK: sysctlbyname: '{{.*}}' size: '{{.*}}'
|
||||
// CHECK: sysctlgetmibinfo: '{{.*}}' size: '{{.*}}'
|
||||
// CHECK: sysctlnametomib: '{{.*}}' size: '{{.*}}'
|
||||
#if defined(__NetBSD__)
|
||||
// CHECK: asysctl: '{{.*}}' size: '{{.*}}'
|
||||
// CHECK: asysctlbyname: '{{.*}}' size: '{{.*}}'
|
||||
// CHECK: sysctlgetmibinfo: '{{.*}}' size: '{{.*}}'
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue