Skip to content

Commit d3cc043

Browse files
rahul-malikGeorge Karpenkov
authored andcommitted
Add Undefined Behavior sanitizer to Swift Driver (#18553)
This change allows the swift driver to link the ubsan runtime if `-sanitize=undefined` is specified. This is useful for sanitizing linked Objective-C code.
1 parent 6462473 commit d3cc043

22 files changed

+56
-1
lines changed

include/swift/Basic/Sanitizers.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ namespace swift {
1919
enum class SanitizerKind : unsigned {
2020
Address = 1 << 1,
2121
Thread = 1 << 2,
22-
Fuzzer = 1 << 3
22+
Fuzzer = 1 << 3,
23+
Undefined = 1 << 4
2324
};
2425

2526
} // end namespace swift

lib/Driver/DarwinToolChains.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,9 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
360360
if (context.OI.SelectedSanitizers & SanitizerKind::Thread)
361361
addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "tsan", *this);
362362

363+
if (context.OI.SelectedSanitizers & SanitizerKind::Undefined)
364+
addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "ubsan", *this);
365+
363366
// Only link in libFuzzer for executables.
364367
if (job.getKind() == LinkKind::Executable &&
365368
(context.OI.SelectedSanitizers & SanitizerKind::Fuzzer))

lib/Driver/UnixToolChains.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,13 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
301301
if (context.OI.SelectedSanitizers & SanitizerKind::Thread)
302302
addLinkSanitizerLibArgsForLinux(context.Args, Arguments, "tsan", *this);
303303

304+
if (context.OI.SelectedSanitizers & SanitizerKind::Undefined)
305+
addLinkSanitizerLibArgsForLinux(context.Args, Arguments, "ubsan", *this);
306+
304307
if (context.OI.SelectedSanitizers & SanitizerKind::Fuzzer)
305308
addLinkRuntimeLib(context.Args, Arguments,
306309
sanitizerRuntimeLibName("fuzzer"));
310+
307311
}
308312
}
309313

lib/Driver/WindowsToolChains.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ toolchains::Windows::constructInvocation(const LinkJobAction &job,
147147
if (context.OI.SelectedSanitizers & SanitizerKind::Address)
148148
addLinkRuntimeLib(context.Args, Arguments,
149149
sanitizerRuntimeLibName("asan"));
150+
151+
if (context.OI.SelectedSanitizers & SanitizerKind::Undefined)
152+
addLinkRuntimeLib(context.Args, Arguments,
153+
sanitizerRuntimeLibName("ubsan"));
150154
}
151155

152156
if (context.Args.hasArg(options::OPT_profile_generate)) {

lib/Option/SanitizerOptions.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ static StringRef toStringRef(const SanitizerKind kind) {
3737
return "thread";
3838
case SanitizerKind::Fuzzer:
3939
return "fuzzer";
40+
case SanitizerKind::Undefined:
41+
return "undefined";
4042
}
4143
llvm_unreachable("Unsupported sanitizer");
4244
}
@@ -49,6 +51,8 @@ static const char* toFileName(const SanitizerKind kind) {
4951
return "tsan";
5052
case SanitizerKind::Fuzzer:
5153
return "fuzzer";
54+
case SanitizerKind::Undefined:
55+
return "ubsan";
5256
}
5357
llvm_unreachable("Unsupported sanitizer");
5458
}
@@ -134,6 +138,7 @@ OptionSet<SanitizerKind> swift::parseSanitizerArgValues(
134138
.Case("address", SanitizerKind::Address)
135139
.Case("thread", SanitizerKind::Thread)
136140
.Case("fuzzer", SanitizerKind::Fuzzer)
141+
.Case("undefined", SanitizerKind::Undefined)
137142
.Default(None);
138143
bool isShared = kind && *kind != SanitizerKind::Fuzzer;
139144
if (!kind) {

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_ios.a

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_ios_dynamic.dylib

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_iossim.a

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_iossim_dynamic.dylib

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_osx.a

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_osx_dynamic.dylib

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvos.a

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvos_dynamic.dylib

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvossim.a

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvossim_dynamic.dylib

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchos.a

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchos_dynamic.dylib

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchossim.a

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchossim_dynamic.dylib

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.ubsan-x86_64.a

Whitespace-only changes.

test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/windows/clang_rt.ubsan-x86_64.lib

Whitespace-only changes.

test/Driver/sanitizers.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/*
2+
* Address Sanitizer Tests (asan)
3+
*/
14
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-apple-macosx10.9 %s | %FileCheck -check-prefix=ASAN -check-prefix=ASAN_OSX %s
25
// RUN: not %swiftc_driver -driver-print-jobs -sanitize=fuzzer -target x86_64-apple-macosx10.9 -resource-dir %S/Inputs/nonexistent-resource-dir %s 2>&1 | %FileCheck -check-prefix=FUZZER_NONEXISTENT %s
36
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-apple-ios7.1 %s | %FileCheck -check-prefix=ASAN -check-prefix=ASAN_IOSSIM %s
@@ -9,6 +12,9 @@
912
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck -check-prefix=ASAN_LINUX %s
1013
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-unknown-windows-msvc %s 2>&1 | %FileCheck -check-prefix=ASAN_WINDOWS %s
1114

15+
/*
16+
* Thread Sanitizer Tests (tsan)
17+
*/
1218
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86_64-apple-macosx10.9 %s | %FileCheck -check-prefix=TSAN -check-prefix=TSAN_OSX %s
1319
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86-apple-macosx10.9 %s 2>&1 | %FileCheck -check-prefix=TSAN_OSX_32 %s
1420
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86_64-apple-ios7.1 %s 2>&1 | %FileCheck -check-prefix=TSAN_IOSSIM %s
@@ -20,6 +26,23 @@
2026
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86_64-unknown-windows-msvc %s 2>&1 | %FileCheck -check-prefix=TSAN_WINDOWS %s
2127
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=thread -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck -check-prefix=TSAN_LINUX %s
2228

29+
/*
30+
* Undefined Behavior Sanitizer Tests (ubsan)
31+
*/
32+
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target x86_64-apple-macosx10.9 %s | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_OSX %s
33+
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target x86_64-apple-ios7.1 %s | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_IOSSIM %s
34+
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target arm64-apple-ios7.1 %s | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_IOS %s
35+
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target x86_64-apple-tvos9.0 %s | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_tvOS_SIM %s
36+
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target arm64-apple-tvos9.0 %s | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_tvOS %s
37+
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target i386-apple-watchos2.0 %s | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_watchOS_SIM %s
38+
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target armv7k-apple-watchos2.0 %s | %FileCheck -check-prefix=UBSAN -check-prefix=UBSAN_watchOS %s
39+
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target x86_64-unknown-linux-gnu %s 2>&1 | %FileCheck -check-prefix=UBSAN_LINUX %s
40+
// RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=undefined -target x86_64-unknown-windows-msvc %s 2>&1 | %FileCheck -check-prefix=UBSAN_WINDOWS %s
41+
42+
43+
/*
44+
* Bad Argument Tests
45+
*/
2346
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address,unknown %s 2>&1 | %FileCheck -check-prefix=BADARG %s
2447
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -sanitize=unknown %s 2>&1 | %FileCheck -check-prefix=BADARG %s
2548
// RUN: not %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address,thread %s 2>&1 | %FileCheck -check-prefix=INCOMPATIBLESANITIZERS %s
@@ -64,5 +87,20 @@
6487

6588
// TSAN: -rpath @executable_path
6689

90+
// UBSAN: swift
91+
// UBSAN: -sanitize=undefined
92+
93+
// UBSAN_OSX: lib/swift/clang/lib/darwin/libclang_rt.ubsan_osx_dynamic.dylib
94+
// UBSAN_IOSSIM: lib/swift/clang/lib/darwin/libclang_rt.ubsan_iossim_dynamic.dylib
95+
// UBSAN_IOS: lib/swift/clang/lib/darwin/libclang_rt.ubsan_ios_dynamic.dylib
96+
// UBSAN_tvOS_SIM: lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvossim_dynamic.dylib
97+
// UBSAN_tvOS: lib/swift/clang/lib/darwin/libclang_rt.ubsan_tvos_dynamic.dylib
98+
// UBSAN_watchOS_SIM: lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchossim_dynamic.dylib
99+
// UBSAN_watchOS: lib/swift/clang/lib/darwin/libclang_rt.ubsan_watchos_dynamic.dylib
100+
// UBSAN_LINUX: lib/swift/clang/lib/linux/libclang_rt.ubsan-x86_64.a
101+
// UBSAN_WINDOWS: lib/swift/clang/lib/windows/clang_rt.ubsan-x86_64.lib
102+
103+
// UBSAN: -rpath @executable_path
104+
67105
// BADARG: unsupported argument 'unknown' to option '-sanitize='
68106
// INCOMPATIBLESANITIZERS: argument '-sanitize=address' is not allowed with '-sanitize=thread'

0 commit comments

Comments
 (0)