[compiler-rt] r266297 - [sanitizer] [SystemZ] Abort if the kernel might be vulnerable to CVE-2016-2143.

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 15 09:44:49 PDT 2016


I am sorry that I couldn't review this patch in time (I was OOO) but I very
much dislike it.
Please revert and then let's do a proper patch.
See my recent comments in the review tool.

On Thu, Apr 14, 2016 at 5:56 AM, Marcin Koscielnicki via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: koriakin
> Date: Thu Apr 14 07:56:24 2016
> New Revision: 266297
>
> URL: http://llvm.org/viewvc/llvm-project?rev=266297&view=rev
> Log:
> [sanitizer] [SystemZ] Abort if the kernel might be vulnerable to
> CVE-2016-2143.
>
> In short, CVE-2016-2143 will crash the machine if a process uses both >4TB
> virtual addresses and fork().  ASan, TSan, and MSan will, by necessity, map
> a sizable chunk of virtual address space, which is much larger than 4TB.
> Even worse, sanitizers will always use fork() for llvm-symbolizer when a
> bug
> is detected.  Disable all three by aborting on process initialization if
> the running kernel version is not known to contain a fix.
>
> Unfortunately, there's no reliable way to detect the fix without crashing
> the kernel.  So, we rely on whitelisting - I've included a list of upstream
> kernel versions that will work.  In case someone uses a distribution kernel
> or applied the fix themselves, an override switch is also included.
>
> Differential Revision: http://reviews.llvm.org/D18915
>
> Modified:
>     compiler-rt/trunk/lib/asan/asan_rtl.cc
>     compiler-rt/trunk/lib/msan/msan.cc
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h
>     compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
>
> Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=266297&r1=266296&r2=266297&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_rtl.cc Thu Apr 14 07:56:24 2016
> @@ -27,6 +27,10 @@
>  #include "sanitizer_common/sanitizer_atomic.h"
>  #include "sanitizer_common/sanitizer_flags.h"
>  #include "sanitizer_common/sanitizer_libc.h"
> +#if defined(__s390x__) && defined(__linux__)
> +// For AvoidCVE_2016_2143.
> +#include "sanitizer_common/sanitizer_linux.h"
> +#endif
>  #include "sanitizer_common/sanitizer_symbolizer.h"
>  #include "lsan/lsan_common.h"
>  #include "ubsan/ubsan_init.h"
> @@ -415,6 +419,9 @@ static void AsanInitInternal() {
>
>    AsanCheckIncompatibleRT();
>    AsanCheckDynamicRTPrereqs();
> +#if defined(__s390x__) && defined(__linux__)
> +  AvoidCVE_2016_2143();
> +#endif
>
>    SetCanPoisonMemory(flags()->poison_heap);
>    SetMallocContextSize(common_flags()->malloc_context_size);
>
> Modified: compiler-rt/trunk/lib/msan/msan.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.cc?rev=266297&r1=266296&r2=266297&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/msan/msan.cc (original)
> +++ compiler-rt/trunk/lib/msan/msan.cc Thu Apr 14 07:56:24 2016
> @@ -22,6 +22,10 @@
>  #include "sanitizer_common/sanitizer_flags.h"
>  #include "sanitizer_common/sanitizer_flag_parser.h"
>  #include "sanitizer_common/sanitizer_libc.h"
> +#if defined(__s390x__) && defined(__linux__)
> +// For AvoidCVE_2016_2143.
> +#include "sanitizer_common/sanitizer_linux.h"
> +#endif
>  #include "sanitizer_common/sanitizer_procmaps.h"
>  #include "sanitizer_common/sanitizer_stacktrace.h"
>  #include "sanitizer_common/sanitizer_symbolizer.h"
> @@ -375,6 +379,9 @@ void __msan_init() {
>    msan_init_is_running = 1;
>    SanitizerToolName = "MemorySanitizer";
>
> +#if defined(__s390x__) && defined(__linux__)
> +  AvoidCVE_2016_2143();
> +#endif
>    InitTlsSize();
>
>    CacheBinaryName();
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=266297&r1=266296&r2=266297&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Thu Apr 14
> 07:56:24 2016
> @@ -56,6 +56,7 @@
>  #include <sys/syscall.h>
>  #include <sys/time.h>
>  #include <sys/types.h>
> +#include <sys/utsname.h>
>  #include <ucontext.h>
>  #include <unistd.h>
>
> @@ -1346,6 +1347,72 @@ void MaybeReexec() {
>    // No need to re-exec on Linux.
>  }
>
> +#ifdef __s390x__
> +static bool FixedCVE_2016_2143() {
> +  // Try to determine if the running kernel has a fix for CVE-2016-2143,
> +  // return false if in doubt (better safe than sorry).  Distros may want
> to
> +  // adjust this for their own kernels.
> +  struct utsname buf;
> +  unsigned int major, minor, patch = 0;
> +  // This should never fail, but just in case...
> +  if (uname(&buf))
> +    return false;
> +  char *ptr = buf.release;
> +  major = internal_simple_strtoll(ptr, &ptr, 10);
> +  // At least first 2 should be matched.
> +  if (ptr[0] != '.')
> +    return false;
> +  minor = internal_simple_strtoll(ptr+1, &ptr, 10);
> +  // Third is optional.
> +  if (ptr[0] == '.')
> +    patch = internal_simple_strtoll(ptr+1, &ptr, 10);
> +  if (major < 3) {
> +    // <3.0 is bad.
> +    return false;
> +  } else if (major == 3) {
> +    // 3.2.79+ is OK.
> +    if (minor == 2 && patch >= 79)
> +      return true;
> +    // Otherwise, bad.
> +    return false;
> +  } else if (major == 4) {
> +    // 4.1.21+ is OK.
> +    if (minor == 1 && patch >= 21)
> +      return true;
> +    // 4.4.6+ is OK.
> +    if (minor == 4 && patch >= 6)
> +      return true;
> +    // Otherwise, OK if 4.5+.
> +    return minor >= 5;
> +  } else {
> +    // Linux 5 and up are fine.
> +    return true;
> +  }
> +}
> +
> +void AvoidCVE_2016_2143() {
> +  // Older kernels are affected by CVE-2016-2143 - they will crash hard
> +  // if someone uses 4-level page tables (ie. virtual addresses >= 4TB)
> +  // and fork() in the same process.  Unfortunately, sanitizers tend to
> +  // require such addresses.  Since this is very likely to crash the whole
> +  // machine (sanitizers themselves use fork() for llvm-symbolizer, for
> one),
> +  // abort the process at initialization instead.
> +  if (FixedCVE_2016_2143())
> +    return;
> +  if (GetEnv("SANITIZER_IGNORE_CVE_2016_2143"))
> +    return;
> +  Report(
> +    "ERROR: Your kernel seems to be vulnerable to CVE-2016-2143.  Using
> ASan,\n"
> +    "MSan or TSan with such kernel can and will crash your machine, or
> worse.\n"
> +    "\n"
> +    "If you are certain your kernel is not vulnerable (you have compiled
> it\n"
> +    "yourself, are are using an unrecognized distribution kernel), you
> can\n"
> +    "override this safety check by exporting
> SANITIZER_IGNORE_CVE_2016_2143\n"
> +    "with any value.\n");
> +  Die();
> +}
> +#endif
> +
>  } // namespace __sanitizer
>
>  #endif // SANITIZER_FREEBSD || SANITIZER_LINUX
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h?rev=266297&r1=266296&r2=266297&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.h Thu Apr 14
> 07:56:24 2016
> @@ -83,6 +83,11 @@ bool LibraryNameIs(const char *full_name
>
>  // Call cb for each region mapped by map.
>  void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
> +
> +#ifdef __s390x__
> +// Aborts the process if running on a kernel without a fix for
> CVE-2016-2143.
> +void AvoidCVE_2016_2143();
> +#endif
>  }  // namespace __sanitizer
>
>  #endif  // SANITIZER_FREEBSD || SANITIZER_LINUX
>
> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc?rev=266297&r1=266296&r2=266297&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc (original)
> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc Thu Apr 14
> 07:56:24 2016
> @@ -247,6 +247,9 @@ static void InitDataSeg() {
>  #endif  // #ifndef SANITIZER_GO
>
>  void InitializePlatformEarly() {
> +#ifdef __s390x__
> +  AvoidCVE_2016_2143();
> +#endif
>  #ifdef TSAN_RUNTIME_VMA
>    vmaSize =
>      (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160415/03f0de9e/attachment.html>


More information about the llvm-commits mailing list