diff --git a/changelog/dmd.intel-cet-ibt-protection.dd b/changelog/dmd.intel-cet-ibt-protection.dd new file mode 100644 index 000000000000..784eb491c8e5 --- /dev/null +++ b/changelog/dmd.intel-cet-ibt-protection.dd @@ -0,0 +1,22 @@ +Added support for Intel CET (Control-flow Enforcement Technology) IBT (Indirect Branch Tracking) protection + +CET is a technology that is useful for preventing an attacker from redirecting a program's control flow, +specifically IBT prevents an attacker from causing an indirect branch to go to an unintended place. + +Intel IBT expects the compiler to emit special instructions (`endbr32` and `endbr64`) which in older processors +that do not support IBT are equivalent to `nop` instructions, consequently a program compiled with active IBT +will be compatible on any x86 processor and the protection will be opportunistically active on supported processors. + +To enable Intel IBT protection in DMD you need to pass the `-fIBT` flag to the compiler, consequently the compiler +will manage the emission of instructions for IBT by itself. +Be careful when using inline assembly, the compiler will not automatically handle IBT inside an inline assembly. + +To find out within a D program whether IBT has been activated or not use the traits getTargetInfo as follows: + +--- +// IBT active +static assert(__traits(getTargetInfo, "CET") == 1); // CET == 1 if IBT is active + +// IBT not active +static assert(__traits(getTargetInfo, "CET") == 0); // CET == 0 if IBT is not active +--- diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index 938513833f5b..0a3e89d58350 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -8256,6 +8256,7 @@ struct Target final cppStd = 1, floatAbi = 2, objectFormat = 3, + CET = 4, }; public: diff --git a/compiler/src/dmd/target.d b/compiler/src/dmd/target.d index e7c3dbc9d68b..b198edf642bc 100644 --- a/compiler/src/dmd/target.d +++ b/compiler/src/dmd/target.d @@ -1206,6 +1206,7 @@ extern (C++) struct Target cppStd, floatAbi, objectFormat, + CET } /** @@ -1248,6 +1249,8 @@ extern (C++) struct Target return stringExp(""); case cppStd.stringof: return new IntegerExp(params.cplusplus); + case CET.stringof: + return new IntegerExp(driverParams.ibt); default: return null; diff --git a/compiler/test/compilable/cet_disabled.d b/compiler/test/compilable/cet_disabled.d new file mode 100644 index 000000000000..4a5c420aa4ad --- /dev/null +++ b/compiler/test/compilable/cet_disabled.d @@ -0,0 +1,3 @@ +// Test for Intel CET protection disabled + +static assert(__traits(getTargetInfo, "CET") == 0); diff --git a/compiler/test/compilable/cet_ibt.d b/compiler/test/compilable/cet_ibt.d new file mode 100644 index 000000000000..a1040a03c676 --- /dev/null +++ b/compiler/test/compilable/cet_ibt.d @@ -0,0 +1,5 @@ +// REQUIRED_ARGS: -fIBT + +// Test for Intel CET IBT (branch) protection + +static assert(__traits(getTargetInfo, "CET") == 1);