Skip to content

Commit 36c7481

Browse files
WorksButNotTestedYour Name
andauthored
Change GuestTracking to use a BTreeSet to remove performance bottleneck (#3112)
Co-authored-by: Your Name <you@example.com>
1 parent b67bd17 commit 36c7481

File tree

3 files changed

+18
-40
lines changed

3 files changed

+18
-40
lines changed

libafl_qemu/librasan/asan/src/tracking/guest.rs

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! This implementation performs guest memory tracking by use of a simple sorted
33
//! list residing in the guest's user space. Hence no interaction with the host
44
//! is required.
5-
use alloc::vec::Vec;
5+
use alloc::collections::BTreeSet;
66
use core::cmp::Ordering;
77

88
use log::debug;
@@ -44,7 +44,7 @@ impl Ord for Range {
4444
}
4545
}
4646

47-
type Ranges = Vec<Range>;
47+
type Ranges = BTreeSet<Range>;
4848

4949
#[derive(Debug)]
5050
pub struct GuestTracking {
@@ -66,41 +66,29 @@ impl Tracking for GuestTracking {
6666

6767
let item = Range { start, len };
6868

69-
let pos = self.ranges.binary_search(&item);
70-
match pos {
71-
Ok(pos) => {
72-
let conflict = &self.ranges[pos];
73-
Err(GuestTrackingError::TrackingConflict(
74-
conflict.start,
75-
conflict.len,
76-
item.start,
77-
item.len,
78-
))?;
79-
}
80-
Err(pos) => {
81-
self.ranges.insert(pos, item);
82-
}
69+
if !self.ranges.insert(item) {
70+
Err(GuestTrackingError::TrackingConflict(start, len))?;
8371
}
8472

8573
Ok(())
8674
}
8775

8876
fn untrack(&mut self, start: GuestAddr) -> Result<(), Self::Error> {
8977
debug!("dealloc - start: 0x{:x}", start);
90-
let pos = self.ranges.binary_search_by(|item| item.start.cmp(&start));
91-
match pos {
92-
Ok(pos) => {
93-
self.ranges.remove(pos);
94-
Ok(())
95-
}
96-
Err(_pos) => Err(GuestTrackingError::AllocationNotFound(start)),
78+
let item = Range { start, len: 1 };
79+
80+
if !self.ranges.remove(&item) {
81+
Err(GuestTrackingError::AllocationNotFound(start))?;
9782
}
83+
Ok(())
9884
}
9985
}
10086

10187
impl GuestTracking {
10288
pub fn new() -> Result<Self, GuestTrackingError> {
103-
Ok(GuestTracking { ranges: Vec::new() })
89+
Ok(GuestTracking {
90+
ranges: BTreeSet::new(),
91+
})
10492
}
10593

10694
pub fn is_out_of_bounds(addr: GuestAddr, len: usize) -> bool {
@@ -118,8 +106,8 @@ pub enum GuestTrackingError {
118106
AddressRangeOverflow(GuestAddr, usize),
119107
#[error("Allocation not found: {0:x}")]
120108
AllocationNotFound(GuestAddr),
121-
#[error("Tracking conflict")]
122-
TrackingConflict(GuestAddr, usize, GuestAddr, usize),
109+
#[error("Tracking conflict: {0:x}, len: {1:x}")]
110+
TrackingConflict(GuestAddr, usize),
123111
#[error("Zero Length")]
124112
ZeroLength(GuestAddr),
125113
}

libafl_qemu/librasan/asan/tests/guest_tracking.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ mod tests {
4646
assert_eq!(tracking.track(0x1000, 0x1000), Ok(()));
4747
assert_eq!(
4848
tracking.track(0x1000, 0x1000),
49-
Err(GuestTrackingError::TrackingConflict(
50-
0x1000, 0x1000, 0x1000, 0x1000
51-
))
49+
Err(GuestTrackingError::TrackingConflict(0x1000, 0x1000))
5250
);
5351
}
5452

@@ -72,9 +70,7 @@ mod tests {
7270
assert_eq!(tracking.track(0x1000, 0x1000), Ok(()));
7371
assert_eq!(
7472
tracking.track(0x0000, 0x1001),
75-
Err(GuestTrackingError::TrackingConflict(
76-
0x1000, 0x1000, 0x0000, 0x1001
77-
))
73+
Err(GuestTrackingError::TrackingConflict(0x0000, 0x1001))
7874
);
7975
}
8076

@@ -84,9 +80,7 @@ mod tests {
8480
assert_eq!(tracking.track(0x1000, 0x1000), Ok(()));
8581
assert_eq!(
8682
tracking.track(0x1fff, 0x1001),
87-
Err(GuestTrackingError::TrackingConflict(
88-
0x1000, 0x1000, 0x1fff, 0x1001
89-
))
83+
Err(GuestTrackingError::TrackingConflict(0x1fff, 0x1001))
9084
);
9185
}
9286

@@ -100,8 +94,6 @@ mod tests {
10094
assert_eq!(
10195
tracking.track(0xffffffffb5b60107, 0xdb),
10296
Err(GuestTrackingError::TrackingConflict(
103-
0xffffffffb5b5ff21,
104-
0x3ff,
10597
0xffffffffb5b60107,
10698
0xdb
10799
))

libafl_qemu/librasan/fuzz/fuzz_targets/guest_tracking.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,7 @@ fuzz_target!(|data: Vec<GuestAddr>| {
8686
if overlaps {
8787
assert_eq!(
8888
test_result,
89-
Err(GuestTrackingError::TrackingConflict(
90-
start, len, test_start, test_len
91-
))
89+
Err(GuestTrackingError::TrackingConflict(test_start, test_len))
9290
);
9391
} else {
9492
assert_eq!(test_result, Ok(()));

0 commit comments

Comments
 (0)