about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2023-05-09 12:33:44 +0530
committerGitHub <noreply@github.com>2023-05-09 12:33:44 +0530
commit02a85bd038546d040efca42a313e44051b078f9c (patch)
treeefd98c1d8e32a7eb1d4b5baad037690370e4aa3d
parent33a01e2e93bfdd0c37649c6f82172644b8315b55 (diff)
parent37f3e2f4b115b166518a208950ecaaef1434830b (diff)
downloadrust-02a85bd038546d040efca42a313e44051b078f9c.tar.gz
rust-02a85bd038546d040efca42a313e44051b078f9c.zip
Rollup merge of #110304 - cchiw:master, r=davidtwco
Add GNU Property Note

Fix #103001

Generates the missing property note:
```
Displaying notes found in: .note.gnu.property
  Owner                Data size 	Description
  GNU                  0x00000010	NT_GNU_PROPERTY_TYPE_0	      Properties: x86 feature: IBT
```
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs50
-rw-r--r--tests/run-make/branch-protection-check-IBT/Makefile15
-rw-r--r--tests/run-make/branch-protection-check-IBT/main.rs3
3 files changed, 68 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index d5d843702c0..8968133bac5 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -12,6 +12,7 @@ use object::{
 
 use snap::write::FrameEncoder;
 
+use object::elf::NT_GNU_PROPERTY_TYPE_0;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::owned_slice::try_slice_owned;
 use rustc_data_structures::sync::MetadataRef;
@@ -93,6 +94,54 @@ pub(super) fn search_for_section<'a>(
         .map_err(|e| format!("failed to read {} section in '{}': {}", section, path.display(), e))
 }
 
+fn add_gnu_property_note(
+    file: &mut write::Object<'static>,
+    architecture: Architecture,
+    binary_format: BinaryFormat,
+    endianness: Endianness,
+) {
+    // check bti protection
+    if binary_format != BinaryFormat::Elf
+        || !matches!(architecture, Architecture::X86_64 | Architecture::Aarch64)
+    {
+        return;
+    }
+
+    let section = file.add_section(
+        file.segment_name(StandardSegment::Data).to_vec(),
+        b".note.gnu.property".to_vec(),
+        SectionKind::Note,
+    );
+    let mut data: Vec<u8> = Vec::new();
+    let n_namsz: u32 = 4; // Size of the n_name field
+    let n_descsz: u32 = 16; // Size of the n_desc field
+    let n_type: u32 = NT_GNU_PROPERTY_TYPE_0; // Type of note descriptor
+    let header_values = [n_namsz, n_descsz, n_type];
+    header_values.iter().for_each(|v| {
+        data.extend_from_slice(&match endianness {
+            Endianness::Little => v.to_le_bytes(),
+            Endianness::Big => v.to_be_bytes(),
+        })
+    });
+    data.extend_from_slice(b"GNU\0"); // Owner of the program property note
+    let pr_type: u32 = match architecture {
+        Architecture::X86_64 => 0xc0000002,
+        Architecture::Aarch64 => 0xc0000000,
+        _ => unreachable!(),
+    };
+    let pr_datasz: u32 = 4; //size of the pr_data field
+    let pr_data: u32 = 3; //program property descriptor
+    let pr_padding: u32 = 0;
+    let property_values = [pr_type, pr_datasz, pr_data, pr_padding];
+    property_values.iter().for_each(|v| {
+        data.extend_from_slice(&match endianness {
+            Endianness::Little => v.to_le_bytes(),
+            Endianness::Big => v.to_be_bytes(),
+        })
+    });
+    file.append_section_data(section, &data, 8);
+}
+
 pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static>> {
     let endianness = match sess.target.options.endian {
         Endian::Little => Endianness::Little,
@@ -205,6 +254,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
         _ => elf::ELFOSABI_NONE,
     };
     let abi_version = 0;
+    add_gnu_property_note(&mut file, architecture, binary_format, endianness);
     file.flags = FileFlags::Elf { os_abi, abi_version, e_flags };
     Some(file)
 }
diff --git a/tests/run-make/branch-protection-check-IBT/Makefile b/tests/run-make/branch-protection-check-IBT/Makefile
new file mode 100644
index 00000000000..cabe951e1c5
--- /dev/null
+++ b/tests/run-make/branch-protection-check-IBT/Makefile
@@ -0,0 +1,15 @@
+# Check for GNU Property Note
+
+include ../tools.mk
+
+# How to run this
+# python3 x.py test --target x86_64-unknown-linux-gnu  tests/run-make/branch-protection-check-IBT/
+
+# only-x86_64
+
+all:
+ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86_64)
+	$(RUSTC) --target x86_64-unknown-linux-gnu -Z cf-protection=branch -L$(TMPDIR) -C link-args='-nostartfiles'  -C save-temps  ./main.rs -o $(TMPDIR)/rsmain
+	 readelf -nW $(TMPDIR)/rsmain | $(CGREP) -e ".note.gnu.property"
+endif
+
diff --git a/tests/run-make/branch-protection-check-IBT/main.rs b/tests/run-make/branch-protection-check-IBT/main.rs
new file mode 100644
index 00000000000..ad379d6ea43
--- /dev/null
+++ b/tests/run-make/branch-protection-check-IBT/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+    println!("hello world");
+}