Add internal_sysctl() used by FreeBSD, NetBSD, OpenBSD and MacOSX

Summary:
Switch local sysctl(2) calls to internal_sysctl().

This is a preparation for introduction of interceptors for
the sysctl*() family of functions and switching `internal_sysctl*()`
to libc calls bypassing interceptors.

No functional change intended with this revision.

Reviewers: vitalybuka, joerg, kcc

Reviewed By: vitalybuka

Subscribers: kubamracek, llvm-commits, #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D51425

llvm-svn: 341181
This commit is contained in:
Kamil Rytarowski 2018-08-31 08:10:06 +00:00
parent 146d5791d9
commit 935203306f
5 changed files with 34 additions and 18 deletions

View File

@ -648,10 +648,10 @@ void ReExec() {
CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME,
};
char path[400];
size_t len;
uptr len;
len = sizeof(path);
if (sysctl(name, ARRAY_SIZE(name), path, &len, NULL, 0) != -1)
if (internal_sysctl(name, ARRAY_SIZE(name), path, &len, NULL, 0) != -1)
pathname = path;
#elif SANITIZER_SOLARIS
pathname = getexecname();
@ -815,6 +815,13 @@ int internal_fork() {
#endif
}
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
uptr *oldlenp, const void *newp, uptr newlen) {
return sysctl(name, namelen, oldp, oldlenp, newp, newlen);
}
#endif
#if SANITIZER_LINUX
#define SA_RESTORER 0x04000000
// Doesn't set sa_restorer if the caller did not set it, so use with caution
@ -1114,8 +1121,9 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
const int Mib[4] = {CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME};
#endif
const char *default_module_name = "kern.proc.pathname";
size_t Size = buf_len;
bool IsErr = (sysctl(Mib, ARRAY_SIZE(Mib), buf, &Size, NULL, 0) != 0);
uptr Size = buf_len;
bool IsErr =
(internal_sysctl(Mib, ARRAY_SIZE(Mib), buf, &Size, NULL, 0) != 0);
int readlink_error = IsErr ? errno : 0;
uptr module_name_len = Size;
#else
@ -1980,13 +1988,13 @@ void CheckASLR() {
#if SANITIZER_NETBSD
int mib[3];
int paxflags;
size_t len = sizeof(paxflags);
uptr len = sizeof(paxflags);
mib[0] = CTL_PROC;
mib[1] = internal_getpid();
mib[2] = PROC_PID_PAXFLAGS;
if (UNLIKELY(sysctl(mib, 3, &paxflags, &len, NULL, 0) == -1)) {
if (UNLIKELY(internal_sysctl(mib, 3, &paxflags, &len, NULL, 0) == -1)) {
Printf("sysctl failed\n");
Die();
}

View File

@ -652,10 +652,10 @@ u32 GetNumberOfCPUs() {
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
u32 ncpu;
int req[2];
size_t len = sizeof(ncpu);
uptr len = sizeof(ncpu);
req[0] = CTL_HW;
req[1] = HW_NCPU;
CHECK_EQ(sysctl(req, 2, &ncpu, &len, NULL, 0), 0);
CHECK_EQ(internal_sysctl(req, 2, &ncpu, &len, NULL, 0), 0);
return ncpu;
#elif SANITIZER_ANDROID && !defined(CPU_COUNT) && !defined(__aarch64__)
// Fall back to /sys/devices/system/cpu on Android when cpu_set_t doesn't

View File

@ -213,6 +213,11 @@ int internal_fork() {
return fork();
}
int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
uptr *oldlenp, const void *newp, uptr newlen) {
return sysctl(name, namelen, oldp, oldlenp, newp, newlen);
}
int internal_forkpty(int *amaster) {
int master, slave;
if (openpty(&master, &slave, nullptr, nullptr, nullptr) == -1) return -1;
@ -499,9 +504,9 @@ MacosVersion GetMacosVersionInternal() {
uptr len = 0, maxlen = sizeof(version) / sizeof(version[0]);
for (uptr i = 0; i < maxlen; i++) version[i] = '\0';
// Get the version length.
CHECK_NE(sysctl(mib, 2, 0, &len, 0, 0), -1);
CHECK_NE(internal_sysctl(mib, 2, 0, &len, 0, 0), -1);
CHECK_LT(len, maxlen);
CHECK_NE(sysctl(mib, 2, version, &len, 0, 0), -1);
CHECK_NE(internal_sysctl(mib, 2, version, &len, 0, 0), -1);
switch (version[0]) {
case '9': return MACOS_VERSION_LEOPARD;
case '1': {

View File

@ -54,9 +54,9 @@ int internal_mprotect(void *addr, uptr length, int prot) {
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
// On OpenBSD we cannot get the full path
struct kinfo_proc kp;
size_t kl;
uptr kl;
const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
if (sysctl(Mib, ARRAY_SIZE(Mib), &kp, &kl, NULL, 0) != -1)
if (internal_sysctl(Mib, ARRAY_SIZE(Mib), &kp, &kl, NULL, 0) != -1)
return internal_snprintf(buf,
(KI_MAXCOMLEN < buf_len ? KI_MAXCOMLEN : buf_len),
"%s", kp.p_comm);
@ -64,23 +64,23 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
}
static void GetArgsAndEnv(char ***argv, char ***envp) {
size_t nargv;
size_t nenv;
uptr nargv;
uptr nenv;
int argvmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV};
int envmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ENV};
if (sysctl(argvmib, 4, NULL, &nargv, NULL, 0) == -1) {
if (internal_sysctl(argvmib, 4, NULL, &nargv, NULL, 0) == -1) {
Printf("sysctl KERN_PROC_NARGV failed\n");
Die();
}
if (sysctl(envmib, 4, NULL, &nenv, NULL, 0) == -1) {
if (internal_sysctl(envmib, 4, NULL, &nenv, NULL, 0) == -1) {
Printf("sysctl KERN_PROC_NENV failed\n");
Die();
}
if (sysctl(argvmib, 4, &argv, &nargv, NULL, 0) == -1) {
if (internal_sysctl(argvmib, 4, &argv, &nargv, NULL, 0) == -1) {
Printf("sysctl KERN_PROC_ARGV failed\n");
Die();
}
if (sysctl(envmib, 4, &envp, &nenv, NULL, 0) == -1) {
if (internal_sysctl(envmib, 4, &envp, &nenv, NULL, 0) == -1) {
Printf("sysctl KERN_PROC_ENV failed\n");
Die();
}

View File

@ -60,6 +60,9 @@ uptr internal_waitpid(int pid, int *status, int options);
int internal_fork();
int internal_forkpty(int *amaster);
int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
uptr *oldlenp, const void *newp, uptr newlen);
// These functions call appropriate pthread_ functions directly, bypassing
// the interceptor. They are weak and may not be present in some tools.
SANITIZER_WEAK_ATTRIBUTE