Skip to content

Commit b3eea40

Browse files
committed
Add initial support for DataFlowSanitizer
Adds initial support for DataFlowSanitizer to the Rust compiler. It currenctly supports `-Zsanitizer-dataflow-abilist` and other options can be specified using `-C llvm-args=`.
1 parent 5ad7454 commit b3eea40

File tree

16 files changed

+91
-8
lines changed

16 files changed

+91
-8
lines changed

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,12 +519,22 @@ pub(crate) unsafe fn llvm_optimize(
519519
let pgo_sample_use_path = get_pgo_sample_use_path(config);
520520
let is_lto = opt_stage == llvm::OptStage::ThinLTO || opt_stage == llvm::OptStage::FatLTO;
521521
let instr_profile_output_path = get_instr_profile_output_path(config);
522+
let sanitize_dataflow_abilist: Vec<_> = config
523+
.sanitizer_dataflow_abilist
524+
.iter()
525+
.map(|file| CString::new(file.as_str()).unwrap())
526+
.collect();
527+
let sanitize_dataflow_abilist1: Vec<_> =
528+
sanitize_dataflow_abilist.iter().map(|file| file.as_ptr()).collect();
522529
// Sanitizer instrumentation is only inserted during the pre-link optimization stage.
523530
let sanitizer_options = if !is_lto {
524531
Some(llvm::SanitizerOptions {
525532
sanitize_address: config.sanitizer.contains(SanitizerSet::ADDRESS),
526533
sanitize_address_recover: config.sanitizer_recover.contains(SanitizerSet::ADDRESS),
527534
sanitize_cfi: config.sanitizer.contains(SanitizerSet::CFI),
535+
sanitize_dataflow: config.sanitizer.contains(SanitizerSet::DATAFLOW),
536+
sanitize_dataflow_abilist: sanitize_dataflow_abilist1.as_ptr(),
537+
sanitize_dataflow_abilist_len: sanitize_dataflow_abilist1.len(),
528538
sanitize_kcfi: config.sanitizer.contains(SanitizerSet::KCFI),
529539
sanitize_memory: config.sanitizer.contains(SanitizerSet::MEMORY),
530540
sanitize_memory_recover: config.sanitizer_recover.contains(SanitizerSet::MEMORY),

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,9 @@ pub struct SanitizerOptions {
482482
pub sanitize_address: bool,
483483
pub sanitize_address_recover: bool,
484484
pub sanitize_cfi: bool,
485+
pub sanitize_dataflow: bool,
486+
pub sanitize_dataflow_abilist: *const *const c_char,
487+
pub sanitize_dataflow_abilist_len: size_t,
485488
pub sanitize_kcfi: bool,
486489
pub sanitize_memory: bool,
487490
pub sanitize_memory_recover: bool,

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,9 @@ fn add_sanitizer_libraries(
12221222
if sanitizer.contains(SanitizerSet::ADDRESS) {
12231223
link_sanitizer_runtime(sess, flavor, linker, "asan");
12241224
}
1225+
if sanitizer.contains(SanitizerSet::DATAFLOW) {
1226+
link_sanitizer_runtime(sess, flavor, linker, "dfsan");
1227+
}
12251228
if sanitizer.contains(SanitizerSet::LEAK) {
12261229
link_sanitizer_runtime(sess, flavor, linker, "lsan");
12271230
}

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ pub struct ModuleConfig {
9696

9797
pub sanitizer: SanitizerSet,
9898
pub sanitizer_recover: SanitizerSet,
99+
pub sanitizer_dataflow_abilist: Vec<String>,
99100
pub sanitizer_memory_track_origins: usize,
100101

101102
// Flags indicating which outputs to produce.
@@ -198,6 +199,10 @@ impl ModuleConfig {
198199
),
199200

200201
sanitizer: if_regular!(sess.opts.unstable_opts.sanitizer, SanitizerSet::empty()),
202+
sanitizer_dataflow_abilist: if_regular!(
203+
sess.opts.unstable_opts.sanitizer_dataflow_abilist.clone(),
204+
Vec::new()
205+
),
201206
sanitizer_recover: if_regular!(
202207
sess.opts.unstable_opts.sanitizer_recover,
203208
SanitizerSet::empty()

compiler/rustc_interface/src/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,7 @@ fn test_unstable_options_tracking_hash() {
810810
tracked!(sanitizer_cfi_canonical_jump_tables, None);
811811
tracked!(sanitizer_cfi_generalize_pointers, Some(true));
812812
tracked!(sanitizer_cfi_normalize_integers, Some(true));
813+
tracked!(sanitizer_dataflow_abilist, Vec::new());
813814
tracked!(sanitizer_memory_track_origins, 2);
814815
tracked!(sanitizer_recover, SanitizerSet::ADDRESS);
815816
tracked!(saturating_float_casts, Some(true));

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#endif
4343
#include "llvm/Transforms/Instrumentation.h"
4444
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
45+
#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
4546
#include "llvm/Support/TimeProfiler.h"
4647
#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
4748
#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
@@ -683,6 +684,9 @@ struct LLVMRustSanitizerOptions {
683684
bool SanitizeAddress;
684685
bool SanitizeAddressRecover;
685686
bool SanitizeCFI;
687+
bool SanitizeDataFlow;
688+
char** SanitizeDataFlowABIList;
689+
size_t SanitizeDataFlowABIListLen;
686690
bool SanitizeKCFI;
687691
bool SanitizeMemory;
688692
bool SanitizeMemoryRecover;
@@ -868,6 +872,18 @@ LLVMRustOptimize(
868872
}
869873

870874
if (SanitizerOptions) {
875+
if (SanitizerOptions->SanitizeDataFlow) {
876+
std::vector<std::string> ABIListFiles(
877+
SanitizerOptions->SanitizeDataFlowABIList,
878+
SanitizerOptions->SanitizeDataFlowABIList +
879+
SanitizerOptions->SanitizeDataFlowABIListLen);
880+
OptimizerLastEPCallbacks.push_back(
881+
[ABIListFiles](ModulePassManager &MPM, OptimizationLevel Level) {
882+
MPM.addPass(DataFlowSanitizerPass(ABIListFiles));
883+
}
884+
);
885+
}
886+
871887
if (SanitizerOptions->SanitizeMemory) {
872888
MemorySanitizerOptions Options(
873889
SanitizerOptions->SanitizeMemoryTrackOrigins,

compiler/rustc_session/src/options.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ mod desc {
381381
pub const parse_opt_panic_strategy: &str = parse_panic_strategy;
382382
pub const parse_oom_strategy: &str = "either `panic` or `abort`";
383383
pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`";
384-
pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, or `thread`";
384+
pub const parse_sanitizers: &str = "comma separated list of sanitizers: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, or `thread`";
385385
pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2";
386386
pub const parse_cfguard: &str =
387387
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
@@ -718,6 +718,7 @@ mod parse {
718718
*slot |= match s {
719719
"address" => SanitizerSet::ADDRESS,
720720
"cfi" => SanitizerSet::CFI,
721+
"dataflow" => SanitizerSet::DATAFLOW,
721722
"kcfi" => SanitizerSet::KCFI,
722723
"kernel-address" => SanitizerSet::KERNELADDRESS,
723724
"leak" => SanitizerSet::LEAK,
@@ -1841,6 +1842,8 @@ written to standard error output)"),
18411842
"enable generalizing pointer types (default: no)"),
18421843
sanitizer_cfi_normalize_integers: Option<bool> = (None, parse_opt_bool, [TRACKED],
18431844
"enable normalizing integer types (default: no)"),
1845+
sanitizer_dataflow_abilist: Vec<String> = (Vec::new(), parse_list, [UNTRACKED],
1846+
"additional ABI list files that control how shadow parameters are passed (space separated)"),
18441847
sanitizer_memory_track_origins: usize = (0, parse_sanitizer_memory_track_origins, [TRACKED],
18451848
"enable origins tracking in MemorySanitizer"),
18461849
sanitizer_recover: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],

compiler/rustc_target/src/spec/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,7 @@ bitflags::bitflags! {
12211221
const KCFI = 1 << 8;
12221222
const KERNELADDRESS = 1 << 9;
12231223
const SAFESTACK = 1 << 10;
1224+
const DATAFLOW = 1 << 11;
12241225
}
12251226
}
12261227
rustc_data_structures::external_bitflags_debug! { SanitizerSet }
@@ -1233,6 +1234,7 @@ impl SanitizerSet {
12331234
Some(match self {
12341235
SanitizerSet::ADDRESS => "address",
12351236
SanitizerSet::CFI => "cfi",
1237+
SanitizerSet::DATAFLOW => "dataflow",
12361238
SanitizerSet::KCFI => "kcfi",
12371239
SanitizerSet::KERNELADDRESS => "kernel-address",
12381240
SanitizerSet::LEAK => "leak",
@@ -2782,6 +2784,7 @@ impl Target {
27822784
base.$key_name |= match s.as_str() {
27832785
Some("address") => SanitizerSet::ADDRESS,
27842786
Some("cfi") => SanitizerSet::CFI,
2787+
Some("dataflow") => SanitizerSet::DATAFLOW,
27852788
Some("kcfi") => SanitizerSet::KCFI,
27862789
Some("kernel-address") => SanitizerSet::KERNELADDRESS,
27872790
Some("leak") => SanitizerSet::LEAK,

compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub fn target() -> Target {
1010
base.static_position_independent_executables = true;
1111
base.supported_sanitizers = SanitizerSet::ADDRESS
1212
| SanitizerSet::CFI
13+
| SanitizerSet::DATAFLOW
1314
| SanitizerSet::LEAK
1415
| SanitizerSet::MEMORY
1516
| SanitizerSet::SAFESTACK

src/bootstrap/configure.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def v(*args):
4848
o("ninja", "llvm.ninja", "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)")
4949
o("locked-deps", "build.locked-deps", "force Cargo.lock to be up to date")
5050
o("vendor", "build.vendor", "enable usage of vendored Rust crates")
51-
o("sanitizers", "build.sanitizers", "build the sanitizer runtimes (asan, lsan, msan, tsan, hwasan)")
51+
o("sanitizers", "build.sanitizers", "build the sanitizer runtimes (asan, dfsan, lsan, msan, tsan, hwasan)")
5252
o("dist-src", "rust.dist-src", "when building tarballs enables building a source tarball")
5353
o("cargo-native-static", "build.cargo-native-static", "static native libraries in cargo")
5454
o("profiler", "build.profiler", "build the profiler runtime")

0 commit comments

Comments
 (0)