about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWilliam Brown <firstyear@redhat.com>2017-06-17 13:42:56 +1000
committerWilliam Brown <firstyear@redhat.com>2017-07-15 08:22:46 +1000
commit0af5c002a25688e826f5821b495e415f6f941bb4 (patch)
treecb97acec92074bb1556281760369037515c56687
parentcd71ea733849e1a130f965f8f5f3515fdcd4b961 (diff)
downloadrust-0af5c002a25688e826f5821b495e415f6f941bb4.tar.gz
rust-0af5c002a25688e826f5821b495e415f6f941bb4.zip
Add support for dylibs with Address Sanitizer. This supports cdylibs and staticlibs on gnu-linux targets.
-rw-r--r--src/librustc_metadata/creader.rs57
-rw-r--r--src/test/run-make/sanitizer-address/overflow.rs2
-rw-r--r--src/test/run-make/sanitizer-cdylib-link/Makefile19
-rw-r--r--src/test/run-make/sanitizer-cdylib-link/library.rs15
-rw-r--r--src/test/run-make/sanitizer-cdylib-link/program.rs17
-rw-r--r--src/test/run-make/sanitizer-dylib-link/Makefile19
-rw-r--r--src/test/run-make/sanitizer-dylib-link/library.rs15
-rw-r--r--src/test/run-make/sanitizer-dylib-link/program.rs17
-rw-r--r--src/test/run-make/sanitizer-dylib/Makefile8
-rw-r--r--src/test/run-make/sanitizer-invalid-cratetype/Makefile18
-rw-r--r--src/test/run-make/sanitizer-invalid-cratetype/hello.rs (renamed from src/test/run-make/sanitizer-dylib/hello.rs)0
-rw-r--r--src/test/run-make/sanitizer-staticlib-link/Makefile18
-rw-r--r--src/test/run-make/sanitizer-staticlib-link/library.rs15
-rw-r--r--src/test/run-make/sanitizer-staticlib-link/program.c8
14 files changed, 205 insertions, 23 deletions
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index ac39da48ac1..d15843b4f31 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -856,21 +856,48 @@ impl<'a> CrateLoader<'a> {
                 return
             }
 
-            if !self.sess.crate_types.borrow().iter().all(|ct| {
-                match *ct {
-                    // Link the runtime
-                    config::CrateTypeExecutable => true,
-                    // This crate will be compiled with the required
-                    // instrumentation pass
-                    config::CrateTypeRlib => false,
-                    _ => {
-                        self.sess.err(&format!("Only executables and rlibs can be \
-                                                compiled with `-Z sanitizer`"));
-                        false
+            // firstyear 2017 - during testing I was unable to access an OSX machine
+            // to make this work on different crate types. As a result, today I have
+            // only been able to test and support linux as a target.
+            if self.sess.target.target.llvm_target == "x86_64-unknown-linux-gnu" {
+                if !self.sess.crate_types.borrow().iter().all(|ct| {
+                    match *ct {
+                        // Link the runtime
+                        config::CrateTypeStaticlib |
+                        config::CrateTypeExecutable => true,
+                        // This crate will be compiled with the required
+                        // instrumentation pass
+                        config::CrateTypeRlib |
+                        config::CrateTypeDylib |
+                        config::CrateTypeCdylib =>
+                            false,
+                        _ => {
+                            self.sess.err(&format!("Only executables, staticlibs, \
+                                cdylibs, dylibs and rlibs can be compiled with \
+                                `-Z sanitizer`"));
+                            false
+                        }
                     }
+                }) {
+                    return
+                }
+            } else {
+                if !self.sess.crate_types.borrow().iter().all(|ct| {
+                    match *ct {
+                        // Link the runtime
+                        config::CrateTypeExecutable => true,
+                        // This crate will be compiled with the required
+                        // instrumentation pass
+                        config::CrateTypeRlib => false,
+                        _ => {
+                            self.sess.err(&format!("Only executables and rlibs can be \
+                                                    compiled with `-Z sanitizer`"));
+                            false
+                        }
+                    }
+                }) {
+                    return
                 }
-            }) {
-                return
             }
 
             let mut uses_std = false;
@@ -890,7 +917,7 @@ impl<'a> CrateLoader<'a> {
                 info!("loading sanitizer: {}", name);
 
                 let symbol = Symbol::intern(name);
-                let dep_kind = DepKind::Implicit;
+                let dep_kind = DepKind::Explicit;
                 let (_, data) =
                     self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP,
                                        PathKind::Crate, dep_kind);
@@ -900,6 +927,8 @@ impl<'a> CrateLoader<'a> {
                     self.sess.err(&format!("the crate `{}` is not a sanitizer runtime",
                                            name));
                 }
+            } else {
+                self.sess.err(&format!("Must link std to be compiled with `-Z sanitizer`"));
             }
         }
     }
diff --git a/src/test/run-make/sanitizer-address/overflow.rs b/src/test/run-make/sanitizer-address/overflow.rs
index e35c3873f7e..1f3c64c8c32 100644
--- a/src/test/run-make/sanitizer-address/overflow.rs
+++ b/src/test/run-make/sanitizer-address/overflow.rs
@@ -10,5 +10,5 @@
 
 fn main() {
     let xs = [0, 1, 2, 3];
-    let y = unsafe { *xs.as_ptr().offset(4) };
+    let _y = unsafe { *xs.as_ptr().offset(4) };
 }
diff --git a/src/test/run-make/sanitizer-cdylib-link/Makefile b/src/test/run-make/sanitizer-cdylib-link/Makefile
new file mode 100644
index 00000000000..9b0470fb277
--- /dev/null
+++ b/src/test/run-make/sanitizer-cdylib-link/Makefile
@@ -0,0 +1,19 @@
+-include ../tools.mk
+
+# This test builds a shared object, then an executable that links it as a native
+# rust library (constrast to an rlib). The shared library and executable both
+# are compiled with address sanitizer, and we assert that a fault in the cdylib
+# is correctly detected.
+
+ifeq ($(TARGET),x86_64-unknown-linux-gnu)
+ASAN_SUPPORT=$(SANITIZER_SUPPORT)
+EXTRA_RUSTFLAG=
+endif
+
+all:
+ifeq ($(ASAN_SUPPORT),1)
+	$(RUSTC) -g -Z sanitizer=address --crate-type cdylib --target $(TARGET) library.rs
+	$(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) -llibrary program.rs
+	LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | grep -q stack-buffer-overflow
+endif
+
diff --git a/src/test/run-make/sanitizer-cdylib-link/library.rs b/src/test/run-make/sanitizer-cdylib-link/library.rs
new file mode 100644
index 00000000000..4ceef5d3f52
--- /dev/null
+++ b/src/test/run-make/sanitizer-cdylib-link/library.rs
@@ -0,0 +1,15 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[no_mangle]
+pub extern fn overflow() {
+    let xs = [0, 1, 2, 3];
+    let _y = unsafe { *xs.as_ptr().offset(4) };
+}
diff --git a/src/test/run-make/sanitizer-cdylib-link/program.rs b/src/test/run-make/sanitizer-cdylib-link/program.rs
new file mode 100644
index 00000000000..9f52817c851
--- /dev/null
+++ b/src/test/run-make/sanitizer-cdylib-link/program.rs
@@ -0,0 +1,17 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern {
+    fn overflow();
+}
+
+fn main() {
+    unsafe { overflow() }
+}
diff --git a/src/test/run-make/sanitizer-dylib-link/Makefile b/src/test/run-make/sanitizer-dylib-link/Makefile
new file mode 100644
index 00000000000..d75241f0971
--- /dev/null
+++ b/src/test/run-make/sanitizer-dylib-link/Makefile
@@ -0,0 +1,19 @@
+-include ../tools.mk
+
+# This test builds a shared object, then an executable that links it as a native
+# rust library (constrast to an rlib). The shared library and executable both
+# are compiled with address sanitizer, and we assert that a fault in the dylib
+# is correctly detected.
+
+ifeq ($(TARGET),x86_64-unknown-linux-gnu)
+ASAN_SUPPORT=$(SANITIZER_SUPPORT)
+EXTRA_RUSTFLAG=
+endif
+
+all:
+ifeq ($(ASAN_SUPPORT),1)
+	$(RUSTC) -g -Z sanitizer=address --crate-type dylib --target $(TARGET) library.rs
+	$(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) -llibrary program.rs
+	LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | grep -q stack-buffer-overflow
+endif
+
diff --git a/src/test/run-make/sanitizer-dylib-link/library.rs b/src/test/run-make/sanitizer-dylib-link/library.rs
new file mode 100644
index 00000000000..4ceef5d3f52
--- /dev/null
+++ b/src/test/run-make/sanitizer-dylib-link/library.rs
@@ -0,0 +1,15 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[no_mangle]
+pub extern fn overflow() {
+    let xs = [0, 1, 2, 3];
+    let _y = unsafe { *xs.as_ptr().offset(4) };
+}
diff --git a/src/test/run-make/sanitizer-dylib-link/program.rs b/src/test/run-make/sanitizer-dylib-link/program.rs
new file mode 100644
index 00000000000..9f52817c851
--- /dev/null
+++ b/src/test/run-make/sanitizer-dylib-link/program.rs
@@ -0,0 +1,17 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern {
+    fn overflow();
+}
+
+fn main() {
+    unsafe { overflow() }
+}
diff --git a/src/test/run-make/sanitizer-dylib/Makefile b/src/test/run-make/sanitizer-dylib/Makefile
deleted file mode 100644
index 835d5b0d9d8..00000000000
--- a/src/test/run-make/sanitizer-dylib/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
--include ../tools.mk
-
-ifeq ($(TARGET),x86_64-unknown-linux-gnu)
-all:
-	$(RUSTC) -Z sanitizer=leak --crate-type dylib --target $(TARGET) hello.rs 2>&1 | grep -q 'Only executables and rlibs can be compiled with `-Z sanitizer`'
-else
-all:
-endif
diff --git a/src/test/run-make/sanitizer-invalid-cratetype/Makefile b/src/test/run-make/sanitizer-invalid-cratetype/Makefile
new file mode 100644
index 00000000000..d03bbf84c1d
--- /dev/null
+++ b/src/test/run-make/sanitizer-invalid-cratetype/Makefile
@@ -0,0 +1,18 @@
+-include ../tools.mk
+
+# NOTE the address sanitizer only supports x86_64 linux and macOS
+
+ifeq ($(TARGET),x86_64-apple-darwin)
+ASAN_SUPPORT=$(SANITIZER_SUPPORT)
+EXTRA_RUSTFLAG=-C rpath
+else
+ifeq ($(TARGET),x86_64-unknown-linux-gnu)
+ASAN_SUPPORT=$(SANITIZER_SUPPORT)
+EXTRA_RUSTFLAG=
+endif
+endif
+
+all:
+ifeq ($(ASAN_SUPPORT),1)
+	$(RUSTC) -Z sanitizer=address --crate-type proc-macro --target $(TARGET) hello.rs 2>&1 | grep -q -- '-Z sanitizer'
+endif
diff --git a/src/test/run-make/sanitizer-dylib/hello.rs b/src/test/run-make/sanitizer-invalid-cratetype/hello.rs
index 41782851a1a..41782851a1a 100644
--- a/src/test/run-make/sanitizer-dylib/hello.rs
+++ b/src/test/run-make/sanitizer-invalid-cratetype/hello.rs
diff --git a/src/test/run-make/sanitizer-staticlib-link/Makefile b/src/test/run-make/sanitizer-staticlib-link/Makefile
new file mode 100644
index 00000000000..f92dc52b445
--- /dev/null
+++ b/src/test/run-make/sanitizer-staticlib-link/Makefile
@@ -0,0 +1,18 @@
+-include ../tools.mk
+
+# This test builds a staticlib, then an executable that links to it.
+# The staticlib and executable both  are compiled with address sanitizer, 
+# and we assert that a fault in the staticlib is correctly detected.
+
+ifeq ($(TARGET),x86_64-unknown-linux-gnu)
+ASAN_SUPPORT=$(SANITIZER_SUPPORT)
+EXTRA_RUSTFLAG=
+endif
+
+all:
+ifeq ($(ASAN_SUPPORT),1)
+	$(RUSTC) -g -Z sanitizer=address --crate-type staticlib --target $(TARGET) library.rs
+	$(CC) program.c $(call STATICLIB,library) $(call OUT_EXE,program) $(EXTRACFLAGS) $(EXTRACXXFLAGS)
+	LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | grep -q stack-buffer-overflow
+endif
+
diff --git a/src/test/run-make/sanitizer-staticlib-link/library.rs b/src/test/run-make/sanitizer-staticlib-link/library.rs
new file mode 100644
index 00000000000..4ceef5d3f52
--- /dev/null
+++ b/src/test/run-make/sanitizer-staticlib-link/library.rs
@@ -0,0 +1,15 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[no_mangle]
+pub extern fn overflow() {
+    let xs = [0, 1, 2, 3];
+    let _y = unsafe { *xs.as_ptr().offset(4) };
+}
diff --git a/src/test/run-make/sanitizer-staticlib-link/program.c b/src/test/run-make/sanitizer-staticlib-link/program.c
new file mode 100644
index 00000000000..abd5d508e72
--- /dev/null
+++ b/src/test/run-make/sanitizer-staticlib-link/program.c
@@ -0,0 +1,8 @@
+// ignore-license
+void overflow();
+
+int main() {
+    overflow();
+    return 0;
+}
+