Add a build flavor to opt-out of BTCFI on OpenBSD.

To work-around #80059, we need to stop return address signing and
opt-out of BTCFI enforcement via enabling a platform linker option.

We don't want to completely undo the BTCFI work in the rare case that
we later figure out how to properly address the above issue, or allow
users who might want to benefit from BTCFI enforcement and won't use
Concurrency. To do this, condition the existing BTCFI flag enforcement
into a configuration option that defaults to off for now.

Because the new swift-driver needs to "know" whether the frontend is
configured to opt-out or not, and since the new driver communicates with
the frontend via the target info JSON to begin with, we add a field
that emits the build flavor to signal the right behavior.
This commit is contained in:
3405691582
2025-03-27 19:57:24 -04:00
parent d1737b9c20
commit a341ce5570
7 changed files with 52 additions and 1 deletions

View File

@@ -575,6 +575,17 @@ set(SWIFT_DARWIN_XCRUN_TOOLCHAIN "XcodeDefault" CACHE STRING
set(SWIFT_DARWIN_STDLIB_INSTALL_NAME_DIR "/usr/lib/swift" CACHE STRING set(SWIFT_DARWIN_STDLIB_INSTALL_NAME_DIR "/usr/lib/swift" CACHE STRING
"The directory of the install_name for standard library dylibs") "The directory of the install_name for standard library dylibs")
#
# User-configurable OpenBSD-specific options.
#
option(SWIFT_OPENBSD_BTCFI
"Emit branch target identification instructions and sign return addresses when available"
FALSE)
if(SWIFT_OPENBSD_BTCFI)
add_definitions("-DSWIFT_OPENBSD_BTCFI")
endif()
# We don't want to use the same install_name_dir as the standard library which # We don't want to use the same install_name_dir as the standard library which
# will be installed in /usr/lib/swift. These private libraries should continue # will be installed in /usr/lib/swift. These private libraries should continue
# to use @rpath for now. # to use @rpath for now.

View File

@@ -71,6 +71,10 @@ namespace swift {
/// (eg. in /usr/lib/swift). /// (eg. in /usr/lib/swift).
bool tripleRequiresRPathForSwiftLibrariesInOS(const llvm::Triple &triple); bool tripleRequiresRPathForSwiftLibrariesInOS(const llvm::Triple &triple);
/// Returns true if the given triple represents a version of OpenBSD
/// that enforces BTCFI by default.
bool tripleBTCFIByDefaultInOpenBSD(const llvm::Triple &triple);
/// Returns the platform name for a given target triple. /// Returns the platform name for a given target triple.
/// ///
/// For example, the iOS simulator has the name "iphonesimulator", while real /// For example, the iOS simulator has the name "iphonesimulator", while real

View File

@@ -140,6 +140,10 @@ bool swift::tripleRequiresRPathForSwiftLibrariesInOS(
return false; return false;
} }
bool swift::tripleBTCFIByDefaultInOpenBSD(const llvm::Triple &triple) {
return triple.isOSOpenBSD() && triple.getArch() == llvm::Triple::aarch64;
}
DarwinPlatformKind swift::getDarwinPlatformKind(const llvm::Triple &triple) { DarwinPlatformKind swift::getDarwinPlatformKind(const llvm::Triple &triple) {
if (triple.isiOS()) { if (triple.isiOS()) {
if (triple.isTvOS()) { if (triple.isTvOS()) {

View File

@@ -171,6 +171,16 @@ void printTripleInfo(const CompilerInvocation &invocation,
out << " \"compatibilityLibraries\": [ ],\n"; out << " \"compatibilityLibraries\": [ ],\n";
} }
if (tripleBTCFIByDefaultInOpenBSD(triple)) {
#if SWIFT_OPENBSD_BTCFI
out << " \"openbsdBTCFIEnabled\": true,\n";
#else
out << " \"openbsdBTCFIEnabled\": false,\n";
#endif
} else {
out << " \"openbsdBTCFIEnabled\": false,\n";
}
out << " \"librariesRequireRPath\": " out << " \"librariesRequireRPath\": "
<< (tripleRequiresRPathForSwiftLibrariesInOS(triple) ? "true" : "false") << (tripleRequiresRPathForSwiftLibrariesInOS(triple) ? "true" : "false")
<< "\n"; << "\n";

View File

@@ -205,12 +205,14 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
} }
if (Triple.isOSOpenBSD() && Triple.getArch() == llvm::Triple::aarch64) { if (Triple.isOSOpenBSD() && Triple.getArch() == llvm::Triple::aarch64) {
#ifdef SWIFT_OPENBSD_BTCFI
arguments.push_back("-Xcc"); arguments.push_back("-Xcc");
arguments.push_back("-Xclang=-mbranch-target-enforce"); arguments.push_back("-Xclang=-mbranch-target-enforce");
arguments.push_back("-Xcc"); arguments.push_back("-Xcc");
arguments.push_back("-Xclang=-msign-return-address=non-leaf"); arguments.push_back("-Xclang=-msign-return-address=non-leaf");
arguments.push_back("-Xcc"); arguments.push_back("-Xcc");
arguments.push_back("-Xclang=-msign-return-address-key=a_key"); arguments.push_back("-Xclang=-msign-return-address-key=a_key");
#endif
} }
if (inputArgs.getLastArg(options::OPT_experimental_serialize_debug_info)) { if (inputArgs.getLastArg(options::OPT_experimental_serialize_debug_info)) {

View File

@@ -211,6 +211,15 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job,
#endif #endif
} }
if (tripleBTCFIByDefaultInOpenBSD(getTriple())) {
#ifndef SWIFT_OPENBSD_BTCFI
Arguments.push_back("-Xlinker");
Arguments.push_back("-z");
Arguments.push_back("-Xlinker");
Arguments.push_back("nobtcfi");
#endif
}
// Configure the toolchain. // Configure the toolchain.
if (const Arg *A = context.Args.getLastArg(options::OPT_tools_directory)) { if (const Arg *A = context.Args.getLastArg(options::OPT_tools_directory)) {
StringRef toolchainPath(A->getValue()); StringRef toolchainPath(A->getValue());

View File

@@ -124,6 +124,9 @@ KNOWN_SETTINGS=(
darwin-toolchain-require-use-os-runtime "0" "When setting up a plist for a toolchain, require the users of the toolchain to link against the OS instead of the packaged toolchain runtime. 0 for false, 1 for true" darwin-toolchain-require-use-os-runtime "0" "When setting up a plist for a toolchain, require the users of the toolchain to link against the OS instead of the packaged toolchain runtime. 0 for false, 1 for true"
darwin-xcrun-toolchain "default" "the name of the toolchain to use on Darwin" darwin-xcrun-toolchain "default" "the name of the toolchain to use on Darwin"
## OpenBSD options
openbsd-btcfi "" "enables BTCFI when possible. May cause stability problems."
## Runtime options ## Runtime options
min-runtime-version "" "Used to specify the minimum host runtime version when building the compiler on non-Darwin platforms" min-runtime-version "" "Used to specify the minimum host runtime version when building the compiler on non-Darwin platforms"
@@ -877,6 +880,12 @@ function set_build_options_for_host() {
swift_cmake_options+=( swift_cmake_options+=(
-DCOVERAGE_DB="${COVERAGE_DB}" -DCOVERAGE_DB="${COVERAGE_DB}"
) )
if [[ "${OPENBSD_BTCFI}" ]]; then
swift_cmake_options+=(
-DSWIFT_OPENBSD_BTCFI:BOOL=TRUE
)
fi
} }
function configure_default_options() { function configure_default_options() {
@@ -1383,7 +1392,9 @@ function swift_c_flags() {
echo -n " -D_GNU_SOURCE -DHAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME" echo -n " -D_GNU_SOURCE -DHAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME"
;; ;;
openbsd-aarch64) openbsd-aarch64)
echo -n " -Xclang=-msign-return-address=non-leaf -Xclang=-msign-return-address-key=a_key -Xclang=-mbranch-target-enforce" if [[ "${OPENBSD_BTCFI}" ]]; then
echo -n " -Xclang=-msign-return-address=non-leaf -Xclang=-msign-return-address-key=a_key -Xclang=-mbranch-target-enforce"
fi
;; ;;
esac esac
} }