Skip to content

Commit a148585

Browse files
authored
Merge pull request #10000 from owenv/owenv/fuzz
[Swift Build] Address libFuzzer support TODO
2 parents ee091d3 + 5b4ea94 commit a148585

6 files changed

Lines changed: 60 additions & 4 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// swift-tools-version: 6.2
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "Fuzzer",
7+
targets: [
8+
.executableTarget(
9+
name: "Fuzzer",
10+
),
11+
]
12+
)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@_cdecl("LLVMFuzzerTestOneInput")
2+
public func test(_ start: UnsafeRawPointer, _ count: Int) -> CInt {
3+
let bytes = UnsafeRawBufferPointer(start: start, count: count)
4+
_ = bytes.first
5+
return 0
6+
}
7+
8+
@main
9+
struct Fuzzer {
10+
static func main() {
11+
print("regular main called")
12+
}
13+
}

Sources/SwiftBuildSupport/PackagePIFProjectBuilder+Products.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ extension PackagePIFProjectBuilder {
167167
settings[.INSTALL_PATH] = "/usr/local/bin"
168168
settings[.LD_RUNPATH_SEARCH_PATHS] = ["$(inherited)", "@executable_path/../lib"]
169169
}
170+
171+
// When the fuzzing is enabled via build request overrides, rename the entry point of executables
172+
// so that we use the libFuzzer entrypoint.
173+
settings[.OTHER_SWIFT_FLAGS].lazilyInitializeAndMutate(initialValue: ["$(inherited)"]) {
174+
$0.append("$(OTHER_SWIFT_FLAGS_ENABLE_LIBFUZZER_$(ENABLE_LIBFUZZER))")
175+
}
176+
settings[multiple: "OTHER_SWIFT_FLAGS_ENABLE_LIBFUZZER_YES"] = ["-Xfrontend", "-entry-point-function-name", "-Xfrontend", "\(mainModule.c99name)_main"]
170177
}
171178

172179
mainModule.addParseAsLibrarySettings(to: &settings, toolsVersion: package.manifest.toolsVersion, fileSystem: pifBuilder.fileSystem)

Sources/SwiftBuildSupport/SwiftBuildSystem.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
850850
case .scudo:
851851
settings["ENABLE_SCUDO_SANITIZER"] = "YES"
852852
case .fuzzer:
853-
throw StringError("\(sanitizer) is not currently supported with this build system.")
853+
settings["ENABLE_LIBFUZZER"] = "YES"
854854
}
855855
}
856856

Tests/FunctionalTests/MiscellaneousTests.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,31 @@ struct MiscellaneousTestCase {
12991299
ProcessInfo.hostOperatingSystem == .windows && buildSystem == .swiftbuild
13001300
}
13011301
}
1302+
1303+
@Test(
1304+
.tags(
1305+
.Feature.Command.Build,
1306+
),
1307+
.skipHostOS(.windows, "libFuzzer is not included in the Windows distribution"),
1308+
)
1309+
func libFuzzerSupport() async throws {
1310+
try await withKnownIssue {
1311+
let configuration = BuildConfiguration.debug
1312+
try await fixture(name: "Miscellaneous/Fuzzer") { fixturePath in
1313+
let (stdout, stderr) = try await executeSwiftRun(
1314+
fixturePath,
1315+
nil,
1316+
configuration: configuration,
1317+
extraArgs: ["--sanitize", "fuzzer", "Fuzzer", "--", "-runs=10"],
1318+
buildSystem: .swiftbuild
1319+
)
1320+
#expect(stderr.contains("Done 10 runs"))
1321+
#expect(!stdout.contains("regular main called"))
1322+
}
1323+
} when: {
1324+
ProcessInfo.isHostAmazonLinux2() // libFuzzer link issues occur on AL2
1325+
}
1326+
}
13021327
}
13031328

13041329
@Suite

Tests/SwiftBuildSupportTests/SwiftBuildSystemTests.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ func withInstantiatedSwiftBuildSystem(
117117
extension PackageModel.Sanitizer {
118118
var hasSwiftBuildSupport: Bool {
119119
switch self {
120-
case .address, .thread, .undefined, .scudo: true
121-
case .fuzzer: false
120+
case .address, .thread, .undefined, .scudo, .fuzzer: true
122121
}
123122
}
124123

@@ -128,7 +127,7 @@ extension PackageModel.Sanitizer {
128127
case .thread: "ENABLE_THREAD_SANITIZER"
129128
case .undefined: "ENABLE_UNDEFINED_BEHAVIOR_SANITIZER"
130129
case .scudo: "ENABLE_SCUDO_SANITIZER"
131-
case .fuzzer: nil
130+
case .fuzzer: "ENABLE_LIBFUZZER"
132131
}
133132

134133
}

0 commit comments

Comments
 (0)