From b547e96b443a1049718700e5c2c440eb6515dc45 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Fri, 13 Oct 2017 15:19:55 +1100 Subject: [PATCH 1/2] Write poison to canary when removing item from diagnostic hashmap --- components/hashglobe/src/diagnostic.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/components/hashglobe/src/diagnostic.rs b/components/hashglobe/src/diagnostic.rs index 0c4df266b34..668a36f7ad2 100644 --- a/components/hashglobe/src/diagnostic.rs +++ b/components/hashglobe/src/diagnostic.rs @@ -1,6 +1,7 @@ use hash_map::HashMap; use std::borrow::Borrow; use std::hash::{BuildHasher, Hash}; +use std::ptr; use FailedAllocationError; @@ -9,6 +10,11 @@ const CANARY: usize = 0x42cafe99; #[cfg(target_pointer_width = "64")] const CANARY: usize = 0x42cafe9942cafe99; +#[cfg(target_pointer_width = "32")] +const POISON: usize = 0xdeadbeef; +#[cfg(target_pointer_width = "64")] +const POISON: usize = 0xdeadbeefdeadbeef; + #[derive(Clone, Debug)] enum JournalEntry { Insert(usize), @@ -130,6 +136,9 @@ impl DiagnosticHashMap { assert!(!self.readonly); self.journal.push(JournalEntry::Remove(self.map.make_hash(k).inspect())); + if let Some(v) = self.map.get_mut(k) { + unsafe { ptr::write_volatile(&mut v.0, POISON); } + } self.map.remove(k).map(|x| x.1) } From cb2772b46c0001948f5f9426d57ecf1308c3db3f Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Fri, 13 Oct 2017 15:20:17 +1100 Subject: [PATCH 2/2] Correct the position and record count of broken canary --- components/hashglobe/src/diagnostic.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/components/hashglobe/src/diagnostic.rs b/components/hashglobe/src/diagnostic.rs index 668a36f7ad2..f761e31a6ab 100644 --- a/components/hashglobe/src/diagnostic.rs +++ b/components/hashglobe/src/diagnostic.rs @@ -60,17 +60,19 @@ impl DiagnosticHashMap fn verify(&self) { let mut position = 0; - let mut bad_canary: Option<(usize, *const usize)> = None; + let mut count = 0; + let mut bad_canary = None; for (_,v) in self.map.iter() { let canary_ref = &v.0; + position += 1; if *canary_ref == CANARY { - position += 1; continue; } - bad_canary = Some((*canary_ref, canary_ref)); + count += 1; + bad_canary = Some((*canary_ref, canary_ref, position)); } if let Some(c) = bad_canary { - self.report_corruption(c.0, c.1, position); + self.report_corruption(c.0, c.1, c.2, count); } } @@ -158,7 +160,8 @@ impl DiagnosticHashMap &self, canary: usize, canary_addr: *const usize, - position: usize + position: usize, + count: usize, ) { use ::std::ffi::CString; let key = b"HashMapJournal\0"; @@ -170,11 +173,13 @@ impl DiagnosticHashMap ); } panic!( - "HashMap Corruption (sz={}, cap={}, pairsz={}, cnry={:#x}, pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})", + concat!("HashMap Corruption (sz={}, cap={}, pairsz={}, cnry={:#x}, count={}, ", + "last_pos={}, base_addr={:?}, cnry_addr={:?}, jrnl_len={})"), self.map.len(), self.map.raw_capacity(), ::std::mem::size_of::<(K, (usize, V))>(), canary, + count, position, self.map.raw_buffer(), canary_addr,