Skip to content

Commit 2bd8d3b

Browse files
author
David Kilzer
committed
Compile WebKit with UBSan
<https://webkit.org/b/176131> <rdar://problem/34174018> Reviewed by Alexey Proskuryakov. .: * Makefile.shared: - Add support for "UBSAN=YES" argument to make. Tools: * Scripts/set-webkit-configuration: - Add support for --[no-]ubsan command-line switch. - Add warning when enabling ASan and TSan together. (updateOrDeleteConfigurationFile): - Extract common code for updating configuration files. * Scripts/webkitdirs.pm: (readSanitizerConfiguration): Add. - Extract common code for reading sanitizer configuration files. (determineASanIsEnabled): (determineTSanIsEnabled): (determineUBSanIsEnabled): Add. - Make use of readSanitizerConfiguration(). (ubsanIsEnabled): Add. (XcodeOptions): - Add command-line switches for UBSan. (generateBuildSystemFromCMakeProject): Ditto. * sanitizer/ubsan.xcconfig: Add. - Contains Xcode settings for enabling UBSan. Canonical link: https://commits.webkit.org/235853@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275150 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 3c5902d commit 2bd8d3b

6 files changed

Lines changed: 128 additions & 80 deletions

File tree

ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2021-03-28 David Kilzer <ddkilzer@apple.com>
2+
3+
Compile WebKit with UBSan
4+
<https://webkit.org/b/176131>
5+
<rdar://problem/34174018>
6+
7+
Reviewed by Alexey Proskuryakov.
8+
9+
* Makefile.shared:
10+
- Add support for "UBSAN=YES" argument to make.
11+
112
2021-03-27 Philippe Normand <pnormand@igalia.com>
213

314
REGRESSION(r275111) [GLIB] Fix build with new derived sources and forwarding headers scheme

Makefile.shared

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ TSAN_OPTION=--no-tsan
7777
endif
7878
endif
7979

80+
ifeq ($(UBSAN),YES)
81+
UBSAN_OPTION=--ubsan
82+
else
83+
ifeq ($(UBSAN),NO)
84+
UBSAN_OPTION=--no-ubsan
85+
endif
86+
endif
87+
8088
ifeq ($(WK_LTO_MODE),full)
8189
WK_LTO_OPTION=--lto-mode=full
8290
else ifeq ($(WK_LTO_MODE),thin)
@@ -93,7 +101,7 @@ export PATH = $(shell getconf PATH)
93101

94102

95103
define set_webkit_configuration
96-
$(SCRIPTS_PATH)/set-webkit-configuration $1 $(ASAN_OPTION) $(TSAN_OPTION) $(WK_LTO_OPTION)
104+
$(SCRIPTS_PATH)/set-webkit-configuration $1 $(ASAN_OPTION) $(TSAN_OPTION) $(UBSAN_OPTION) $(WK_LTO_OPTION)
97105
endef
98106

99107
define invoke_xcode
@@ -107,7 +115,7 @@ define invoke_xcode
107115
endef
108116

109117
all:
110-
ifneq (,$(strip $(ASAN_OPTION) $(TSAN_OPTION) $(WK_LTO_OPTION)))
118+
ifneq (,$(strip $(ASAN_OPTION) $(TSAN_OPTION) $(UBSAN_OPTION) $(WK_LTO_OPTION)))
111119
@$(call set_webkit_configuration,)
112120
endif
113121
@$(call invoke_xcode,,GCC_PREPROCESSOR_DEFINITIONS='$(GCC_PREPROCESSOR_ADDITIONS) $$(inherited)')

Tools/ChangeLog

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,32 @@
1+
2021-03-28 David Kilzer <ddkilzer@apple.com>
2+
3+
Compile WebKit with UBSan
4+
<https://webkit.org/b/176131>
5+
<rdar://problem/34174018>
6+
7+
Reviewed by Alexey Proskuryakov.
8+
9+
* Scripts/set-webkit-configuration:
10+
- Add support for --[no-]ubsan command-line switch.
11+
- Add warning when enabling ASan and TSan together.
12+
(updateOrDeleteConfigurationFile):
13+
- Extract common code for updating configuration files.
14+
15+
* Scripts/webkitdirs.pm:
16+
(readSanitizerConfiguration): Add.
17+
- Extract common code for reading sanitizer configuration files.
18+
(determineASanIsEnabled):
19+
(determineTSanIsEnabled):
20+
(determineUBSanIsEnabled): Add.
21+
- Make use of readSanitizerConfiguration().
22+
(ubsanIsEnabled): Add.
23+
(XcodeOptions):
24+
- Add command-line switches for UBSan.
25+
(generateBuildSystemFromCMakeProject): Ditto.
26+
27+
* sanitizer/ubsan.xcconfig: Add.
28+
- Contains Xcode settings for enabling UBSan.
29+
130
2021-03-27 Kate Cheney <katherine_cheney@apple.com>
231

332
PCM: Send report to both click source and attribution destination website

Tools/Scripts/set-webkit-configuration

Lines changed: 32 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env perl
22

3-
# Copyright (C) 2005-2020 Apple Inc. All rights reserved.
3+
# Copyright (C) 2005-2021 Apple Inc. All rights reserved.
44
#
55
# Redistribution and use in source and binary forms, with or without
66
# modification, are permitted provided that the following conditions
@@ -41,6 +41,7 @@ Usage: $programName [options]
4141
--[no-]asan Enable or disable clang address sanitizer
4242
--[no-]coverage Enable or disable LLVM Source-based Code Coverage
4343
--[no-]tsan Enable or disable clang thread sanitizer
44+
--[no-]ubsan Enable or disable clang undefined behavior sanitizer
4445
--force-optimization-level=<level> Optimization level: O3, O2, O1, O0, Os, Ofast, Og, or none
4546
--lto-mode=<mode> Set LTO mode: full, thin, or none
4647
--debug Set the default configuration to debug
@@ -56,6 +57,8 @@ my $enableCoverage = checkForArgumentAndRemoveFromARGV("--coverage");
5657
my $disableCoverage = checkForArgumentAndRemoveFromARGV("--no-coverage");
5758
my $enableTSAN = checkForArgumentAndRemoveFromARGV("--tsan");
5859
my $disableTSAN = checkForArgumentAndRemoveFromARGV("--no-tsan");
60+
my $enableUBSAN = checkForArgumentAndRemoveFromARGV("--ubsan");
61+
my $disableUBSAN = checkForArgumentAndRemoveFromARGV("--no-ubsan");
5962
my $ltoMode;
6063
if (!checkForArgumentAndRemoveFromARGVGettingValue("--lto-mode", \$ltoMode)) {
6164
$ltoMode="";
@@ -81,25 +84,28 @@ my $baseProductDir = baseProductDir();
8184
system "mkdir", "-p", "$baseProductDir";
8285

8386
if (checkForArgumentAndRemoveFromARGV("--reset")) {
84-
unlink "$baseProductDir/Configuration";
85-
unlink "$baseProductDir/Architecture";
86-
unlink "$baseProductDir/ASan";
87-
unlink "$baseProductDir/Coverage";
88-
unlink File::Spec->catfile($baseProductDir, "TSan");
89-
unlink "$baseProductDir/ForceOptimizationLevel";
90-
unlink "$baseProductDir/LTO";
87+
for my $fileName (qw(Architecture ASan Configuration Coverage ForceOptimizationLevel LTO TSan UBSan)) {
88+
unlink File::Spec->catfile($baseProductDir, $fileName);
89+
}
9190
exit 0;
9291
}
9392

94-
if ((!$configuration && !$architecture && !$enableASAN && !$disableASAN && !$enableCoverage && !$disableCoverage && !$enableTSAN && !$disableTSAN && !$ltoMode && !$forceOptimizationLevel)
93+
if ((!$configuration && !$architecture && !$enableASAN && !$disableASAN && !$enableCoverage && !$disableCoverage && !$enableTSAN && !$disableTSAN && !$enableUBSAN && !$disableUBSAN && !$ltoMode && !$forceOptimizationLevel)
9594
|| ($enableASAN && $disableASAN)
9695
|| ($enableCoverage && $disableCoverage)
9796
|| ($enableTSAN && $disableTSAN)
97+
|| ($enableUBSAN && $disableUBSAN)
9898
) {
9999
print STDERR $usage;
100100
exit 1;
101101
}
102102

103+
if ($enableASAN && $enableTSAN) {
104+
print STDERR "ERROR: Address Sanitizer and Thread Sanitzer can't be enabled together.\n";
105+
print STDERR $usage;
106+
exit 1;
107+
}
108+
103109
if ($ltoMode && $ltoMode ne "full" && $ltoMode ne "thin" && $ltoMode ne "none") {
104110
print STDERR $usage;
105111
exit 1;
@@ -118,56 +124,24 @@ if ($forceOptimizationLevel
118124
exit 1;
119125
}
120126

121-
if ($configuration) {
122-
open CONFIGURATION, ">", "$baseProductDir/Configuration" or die;
123-
print CONFIGURATION $configuration;
124-
close CONFIGURATION;
125-
}
126-
127-
if ($architecture) {
128-
if ($architecture ne "x86_64") {
129-
open ARCHITECTURE, ">", "$baseProductDir/Architecture" or die;
130-
print ARCHITECTURE $architecture;
131-
close ARCHITECTURE;
127+
sub updateOrDeleteConfigurationFile($$)
128+
{
129+
my ($fileName, $contents) = @_;
130+
my $filePath = File::Spec->catfile($baseProductDir, $fileName);
131+
if ($contents) {
132+
open FILE, ">", $filePath or die;
133+
print FILE $contents;
134+
close FILE;
132135
} else {
133-
unlink "$baseProductDir/Architecture";
136+
unlink $filePath;
134137
}
135138
}
136139

137-
if ($enableASAN) {
138-
open ASAN, ">", "$baseProductDir/ASan" or die;
139-
print ASAN "YES";
140-
close ASAN;
141-
} elsif ($disableASAN) {
142-
unlink "$baseProductDir/ASan";
143-
}
144-
145-
if ($enableCoverage) {
146-
open Coverage, ">", "$baseProductDir/Coverage" or die;
147-
print Coverage "YES";
148-
close Coverage;
149-
} elsif ($disableCoverage) {
150-
unlink "$baseProductDir/Coverage";
151-
}
152-
153-
if ($enableTSAN) {
154-
open TSAN, ">", File::Spec->catfile($baseProductDir, "TSan") or die;
155-
print TSAN "YES";
156-
close TSAN;
157-
} elsif ($disableTSAN) {
158-
unlink File::Spec->catfile($baseProductDir, "TSan");
159-
}
160-
161-
if ($forceOptimizationLevel && $forceOptimizationLevel eq "none") {
162-
unlink "$baseProductDir/ForceOptimizationLevel";
163-
} elsif ($forceOptimizationLevel) {
164-
open ForceOptimizationLevel, ">", "$baseProductDir/ForceOptimizationLevel" or die;
165-
print ForceOptimizationLevel substr($forceOptimizationLevel, 1) . "\n";
166-
close ForceOptimizationLevel;
167-
}
168-
169-
if ($ltoMode) {
170-
open LTO, ">", "$baseProductDir/LTO" or die;
171-
print LTO "$ltoMode";
172-
close LTO;
173-
}
140+
updateOrDeleteConfigurationFile("Configuration", $configuration);
141+
updateOrDeleteConfigurationFile("Architecture", $architecture && $architecture ne "x86_64" ? $architecture : undef);
142+
updateOrDeleteConfigurationFile("ASan", $enableASAN ? "YES" : undef);
143+
updateOrDeleteConfigurationFile("Coverage", $enableCoverage ? "YES" : undef);
144+
updateOrDeleteConfigurationFile("TSan", $enableTSAN ? "YES" : undef);
145+
updateOrDeleteConfigurationFile("UBSan", $enableUBSAN ? "YES" : undef);
146+
updateOrDeleteConfigurationFile("ForceOptimizationLevel", (!$forceOptimizationLevel || $forceOptimizationLevel eq "none") ? undef : substr($forceOptimizationLevel, 1) . "\n");
147+
updateOrDeleteConfigurationFile("LTO", $ltoMode);

Tools/Scripts/webkitdirs.pm

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2005-2020 Apple Inc. All rights reserved.
1+
# Copyright (C) 2005-2021 Apple Inc. All rights reserved.
22
# Copyright (C) 2009 Google Inc. All rights reserved.
33
# Copyright (C) 2011 Research In Motion Limited. All rights reserved.
44
# Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
@@ -131,6 +131,7 @@ my $architecture;
131131
my %nativeArchitectureMap = ();
132132
my $asanIsEnabled;
133133
my $tsanIsEnabled;
134+
my $ubsanIsEnabled;
134135
my $forceOptimizationLevel;
135136
my $coverageIsEnabled;
136137
my $ltoMode;
@@ -432,36 +433,39 @@ sub determineArchitecture
432433
$architecture = 'arm64' if $architecture =~ /aarch64/i;
433434
}
434435

436+
sub readSanitizerConfiguration($)
437+
{
438+
my ($fileName) = @_;
439+
440+
if (open FILE, File::Spec->catfile($baseProductDir, $fileName)) {
441+
my $value = <FILE>;
442+
close FILE;
443+
chomp $value;
444+
return ($value eq "YES");
445+
}
446+
447+
return 0;
448+
}
449+
435450
sub determineASanIsEnabled
436451
{
437452
return if defined $asanIsEnabled;
438453
determineBaseProductDir();
439-
440-
$asanIsEnabled = 0;
441-
my $asanConfigurationValue;
442-
443-
if (open ASAN, "$baseProductDir/ASan") {
444-
$asanConfigurationValue = <ASAN>;
445-
close ASAN;
446-
chomp $asanConfigurationValue;
447-
$asanIsEnabled = 1 if $asanConfigurationValue eq "YES";
448-
}
454+
$asanIsEnabled = readSanitizerConfiguration("ASan");
449455
}
450456

451457
sub determineTSanIsEnabled
452458
{
453459
return if defined $tsanIsEnabled;
454460
determineBaseProductDir();
461+
$tsanIsEnabled = readSanitizerConfiguration("TSan");
462+
}
455463

456-
$tsanIsEnabled = 0;
457-
my $tsanConfigurationValue;
458-
459-
if (open TSAN, "$baseProductDir/TSan") {
460-
$tsanConfigurationValue = <TSAN>;
461-
close TSAN;
462-
chomp $tsanConfigurationValue;
463-
$tsanIsEnabled = 1 if $tsanConfigurationValue eq "YES";
464-
}
464+
sub determineUBSanIsEnabled
465+
{
466+
return if defined $ubsanIsEnabled;
467+
determineBaseProductDir();
468+
$ubsanIsEnabled = readSanitizerConfiguration("UBSan");
465469
}
466470

467471
sub determineForceOptimizationLevel
@@ -909,6 +913,12 @@ sub tsanIsEnabled()
909913
return $tsanIsEnabled;
910914
}
911915

916+
sub ubsanIsEnabled()
917+
{
918+
determineUBSanIsEnabled();
919+
return $ubsanIsEnabled;
920+
}
921+
912922
sub forceOptimizationLevel()
913923
{
914924
determineForceOptimizationLevel();
@@ -964,6 +974,7 @@ sub XcodeOptions
964974
determineArchitecture();
965975
determineASanIsEnabled();
966976
determineTSanIsEnabled();
977+
determineUBSanIsEnabled();
967978
determineForceOptimizationLevel();
968979
determineCoverageIsEnabled();
969980
determineLTOMode();
@@ -980,6 +991,7 @@ sub XcodeOptions
980991
} elsif ($tsanIsEnabled) {
981992
push @options, ("-xcconfig", File::Spec->catfile(sourceDir(), "Tools", "sanitizer", "tsan.xcconfig"));
982993
}
994+
push @options, ("-xcconfig", File::Spec->catfile(sourceDir(), "Tools", "sanitizer", "ubsan.xcconfig")) if $ubsanIsEnabled;
983995
push @options, ("-xcconfig", sourceDir() . "/Tools/coverage/coverage.xcconfig") if $coverageIsEnabled;
984996
push @options, ("GCC_OPTIMIZATION_LEVEL=$forceOptimizationLevel") if $forceOptimizationLevel;
985997
push @options, "WK_LTO_MODE=$ltoMode" if $ltoMode;
@@ -2470,6 +2482,7 @@ sub generateBuildSystemFromCMakeProject
24702482

24712483
push @args, "-DENABLE_SANITIZERS=address" if asanIsEnabled();
24722484
push @args, "-DENABLE_SANITIZERS=thread" if tsanIsEnabled();
2485+
push @args, "-DENABLE_SANITIZERS=undefined" if ubsanIsEnabled();
24732486

24742487
push @args, "-DLTO_MODE=$ltoMode" if ltoMode();
24752488

Tools/sanitizer/ubsan.xcconfig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "sanitizer.xcconfig"
2+
3+
ENABLE_UNDEFINED_BEHAVIOR_SANITIZER = $(ENABLE_UNDEFINED_BEHAVIOR_SANITIZER_$(WK_UBSAN_DISALLOWED));
4+
ENABLE_UNDEFINED_BEHAVIOR_SANITIZER_ = YES;
5+
ENABLE_UNDEFINED_BEHAVIOR_SANITIZER_NO = YES;
6+
7+
WK_ENABLE_SANITIZER = $(ENABLE_UNDEFINED_BEHAVIOR_SANITIZER);
8+
9+
// FIXME: Tune list of UBSan checkers: <https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html>.
10+
// FIXME: UBSan checker -fsanitize=vptr is incompatible with GCC_ENABLE_CPP_RTTI=NO.
11+
// -fno-delete-null-pointer-checks: do not let the compiler remove nullptr checks that could otherwise be removed because they are considered undefined behavior.
12+
// -fno-optimize-sibling-calls: disable tail call elimination for more accurate crash stacks.
13+
WK_SANITIZER_OTHER_CFLAGS_YES = $(inherited) -fno-delete-null-pointer-checks -fno-optimize-sibling-calls -fno-sanitize=vptr;

0 commit comments

Comments
 (0)