forked from OSchip/llvm-project
[compiler-rt] Use uname syscall in GetKernelAreaSize()
Commit 5f5fb56c68
("[compiler-rt] Intercept the uname() function")
broke clang-cmake-thumbv7-full-sh build:
http://lab.llvm.org:8011/builders/clang-cmake-thumbv7-full-sh/builds/4296
This also affects i386.
The reason is that intercepted uname() is called by GetKernelAreaSize()
during ASAN initialization on 32-bit platforms, but the respective
interceptor is not initialized yet at this point, leading to null
pointer dereference.
Introduce internal_uname() wrapper around uname syscall, and use it in
GetKernelAreaSize() and in FixedCVE_2016_2143().
Author: Ilya Leoshkevich
Reviewed By: Evgenii Stepanov
Differential Revision: https://reviews.llvm.org/D76776
This commit is contained in:
parent
dc37287320
commit
2ca7fe3796
|
@ -1015,9 +1015,8 @@ static uptr GetKernelAreaSize() {
|
|||
// is modified (e.g. under schroot) so check this as well.
|
||||
struct utsname uname_info;
|
||||
int pers = personality(0xffffffffUL);
|
||||
if (!(pers & PER_MASK)
|
||||
&& uname(&uname_info) == 0
|
||||
&& internal_strstr(uname_info.machine, "64"))
|
||||
if (!(pers & PER_MASK) && internal_uname(&uname_info) == 0 &&
|
||||
internal_strstr(uname_info.machine, "64"))
|
||||
return 0;
|
||||
#endif // SANITIZER_ANDROID
|
||||
|
||||
|
@ -1629,6 +1628,12 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
|
|||
}
|
||||
#endif // defined(__x86_64__) && SANITIZER_LINUX
|
||||
|
||||
#if SANITIZER_LINUX
|
||||
int internal_uname(struct utsname *buf) {
|
||||
return internal_syscall(SYSCALL(uname), buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SANITIZER_ANDROID
|
||||
#if __ANDROID_API__ < 21
|
||||
extern "C" __attribute__((weak)) int dl_iterate_phdr(
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "sanitizer_posix.h"
|
||||
|
||||
struct link_map; // Opaque type returned by dlopen().
|
||||
struct utsname;
|
||||
|
||||
namespace __sanitizer {
|
||||
// Dirent structure for getdents(). Note that this structure is different from
|
||||
|
@ -64,6 +65,7 @@ void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
|
|||
|| defined(__arm__)
|
||||
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
|
||||
int *parent_tidptr, void *newtls, int *child_tidptr);
|
||||
int internal_uname(struct utsname *buf);
|
||||
#endif
|
||||
#elif SANITIZER_FREEBSD
|
||||
void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
|
||||
|
|
|
@ -123,12 +123,8 @@ static bool FixedCVE_2016_2143() {
|
|||
// adjust this for their own kernels.
|
||||
struct utsname buf;
|
||||
unsigned int major, minor, patch = 0;
|
||||
// Depending on the concrete sanitizer being used, uname may or may not
|
||||
// be intercepted. Make sure we use the libc version in either case.
|
||||
using Uname = int (*)(struct utsname *);
|
||||
Uname uname = reinterpret_cast<Uname>(dlsym(RTLD_NEXT, "uname"));
|
||||
// This should never fail, but just in case...
|
||||
if (uname == nullptr || uname(&buf))
|
||||
if (internal_uname(&buf))
|
||||
return false;
|
||||
const char *ptr = buf.release;
|
||||
major = internal_simple_strtoll(ptr, &ptr, 10);
|
||||
|
|
Loading…
Reference in New Issue