From 66e493f81e8e27b4a498a6dac54d404c2333fa5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Sat, 3 Oct 2020 16:38:09 +0200 Subject: [PATCH] [asan] Stop instrumenting user-defined ELF sections Do not instrument user-defined ELF sections (whose names resemble valid C identifiers). They may have special use semantics and modifying them may break programs. This is e.g. the case with NetBSD __link_set API that expects these sections to store consecutive array elements. Differential Revision: https://reviews.llvm.org/D76665 --- .../Instrumentation/AddressSanitizer.cpp | 8 ++++++++ .../do-not-instrument-netbsd-link_set.ll | 14 ++++++++++++++ .../instrument-section-invalid-c-ident.ll | 17 +++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 llvm/test/Instrumentation/AddressSanitizer/do-not-instrument-netbsd-link_set.ll create mode 100644 llvm/test/Instrumentation/AddressSanitizer/instrument-section-invalid-c-ident.ll diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index fd5eaada2febc..5902a2eb8374c 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1883,6 +1883,14 @@ bool ModuleAddressSanitizer::shouldInstrumentGlobal(GlobalVariable *G) const { return false; } + // Do not instrument user-defined sections (with names resembling + // valid C identifiers) + if (TargetTriple.isOSBinFormatELF()) { + if (std::all_of(Section.begin(), Section.end(), + [](char c) { return llvm::isAlnum(c) || c == '_'; })) + return false; + } + // On COFF, if the section name contains '$', it is highly likely that the // user is using section sorting to create an array of globals similar to // the way initialization callbacks are registered in .init_array and diff --git a/llvm/test/Instrumentation/AddressSanitizer/do-not-instrument-netbsd-link_set.ll b/llvm/test/Instrumentation/AddressSanitizer/do-not-instrument-netbsd-link_set.ll new file mode 100644 index 0000000000000..fd37d1357e87d --- /dev/null +++ b/llvm/test/Instrumentation/AddressSanitizer/do-not-instrument-netbsd-link_set.ll @@ -0,0 +1,14 @@ +; This test checks that NetBSD link_set array elements remain consecutive. +; RUN: opt < %s -asan -asan-module -S | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-netbsd" + +module asm ".hidden __stop_link_set_test_set" + +@data1 = dso_local global i32 1, align 4 +@data2 = dso_local global i32 2, align 4 +@__link_set_test_set_sym_data1 = internal constant i8* bitcast (i32* @data1 to i8*), section "link_set_test_set", align 8 +@__link_set_test_set_sym_data2 = internal constant i8* bitcast (i32* @data2 to i8*), section "link_set_test_set", align 8 +; CHECK: @__link_set_test_set_sym_data1 = internal constant i8*{{.*}}, section "link_set_test_set" +; CHECK-NEXT: @__link_set_test_set_sym_data2 = internal constant i8*{{.*}}, section "link_set_test_set" diff --git a/llvm/test/Instrumentation/AddressSanitizer/instrument-section-invalid-c-ident.ll b/llvm/test/Instrumentation/AddressSanitizer/instrument-section-invalid-c-ident.ll new file mode 100644 index 0000000000000..a320f797a7137 --- /dev/null +++ b/llvm/test/Instrumentation/AddressSanitizer/instrument-section-invalid-c-ident.ll @@ -0,0 +1,17 @@ +; This test checks that sections with names not resembling valid C identifiers +; are instrumented. +; RUN: opt < %s -asan -asan-module -S | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-netbsd" + +module asm ".hidden invalid$c$name" + +@data1 = dso_local global i32 1, align 4 +@data2 = dso_local global i32 2, align 4 +@__invalid$c$name_sym_data1 = internal constant i8* bitcast (i32* @data1 to i8*), section "invalid$c$name", align 8 +@__invalid$c$name_sym_data2 = internal constant i8* bitcast (i32* @data2 to i8*), section "invalid$c$name", align 8 +; CHECK: @"__invalid$c$name_sym_data1" = internal constant{{.*}}, section "invalid$c$name", comdat +; CHECK-NEXT: @"__invalid$c$name_sym_data2" = internal constant{{.*}}, section "invalid$c$name", comdat +; CHECK: @"__asan_global___invalid$c$name_sym_data1" +; CHECK-NEXT: @"__asan_global___invalid$c$name_sym_data2"