Skip to content

Commit 912cf64

Browse files
committed
some more status vectors, fixed empty array crash
1 parent 7cba278 commit 912cf64

File tree

7 files changed

+71
-27
lines changed

7 files changed

+71
-27
lines changed

src/block/decoder.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,20 @@ mod test {
4343

4444
#[test]
4545
fn test_blkdec_alloc() {
46-
BlockDecoder::new(&ConfigBuilder::new(&mut [0; 0]).finish()).unwrap();
46+
let kek = &mut [1; 2];
47+
BlockDecoder::new(
48+
&ConfigBuilder::new(kek).unwrap().finish()
49+
).unwrap();
4750
}
4851

4952
#[test ]
5053
fn test_blkdec_props() {
54+
let kek = &mut [1; 2];
5155
// this just checks memory safety for property access
5256
// usage can be found in the integration tests
5357
let mut b = BlockDecoder::new(
54-
&ConfigBuilder::new(&mut [0; 0]).finish()).unwrap();
58+
&ConfigBuilder::new(kek).unwrap().finish()
59+
).unwrap();
5560
let a = b.asid().unwrap();
5661
assert!(a.cr3().is_none());
5762
assert!(a.vmcs().is_none());
@@ -195,8 +200,9 @@ impl<'a, T> BlockDecoder<'a, T> {
195200
})
196201
}
197202

198-
pub fn sync_backward(&mut self) -> Result<(), PtError> {
199-
ensure_ptok(unsafe { pt_blk_sync_backward(self.0) })
203+
pub fn sync_backward(&mut self) -> Result<Status, PtError> {
204+
extract_pterr(unsafe { pt_blk_sync_backward(self.0) })
205+
.map(|s| Status::from_bits(s).unwrap())
200206
}
201207

202208
/// Synchronize an Intel PT block decoder.
@@ -207,8 +213,9 @@ impl<'a, T> BlockDecoder<'a, T> {
207213
/// Returns BadOpc if an unknown packet is encountered.
208214
/// Returns BadPacket if an unknown packet payload is encountered.
209215
/// Returns Eos if no further synchronization point is found.
210-
pub fn sync_forward(&mut self) -> Result<(), PtError> {
211-
ensure_ptok(unsafe { pt_blk_sync_forward(self.0) })
216+
pub fn sync_forward(&mut self) -> Result<Status, PtError> {
217+
extract_pterr(unsafe { pt_blk_sync_forward(self.0) })
218+
.map(|s| Status::from_bits(s).unwrap())
212219
}
213220

214221
/// Manually synchronize an Intel PT block decoder.

src/config/config.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use super::cpu::Cpu;
22
use super::freqency::Frequency;
33
use super::filter::AddrFilter;
44
use crate::packet::Unknown;
5+
use crate::error::{ PtError, PtErrorCode };
56

67
use std::mem;
78
use std::borrow::Cow;
@@ -22,8 +23,9 @@ mod test {
2223
use crate::packet::Unknown;
2324

2425
#[test]
26+
#[should_panic]
2527
fn test_config_empty() {
26-
let c = ConfigBuilder::new(&mut [0; 0]).finish();
28+
let c = ConfigBuilder::new(&mut [0; 0]).unwrap().finish();
2729
assert_eq!(c.0.begin, c.0.end);
2830
assert_eq!(c.0.size, mem::size_of::<pt_config>());
2931
}
@@ -32,7 +34,7 @@ mod test {
3234
fn test_config_buf() {
3335
let mut data = [0; 16];
3436
let len = data.len();
35-
let c = ConfigBuilder::new(&mut data).finish();
37+
let c = ConfigBuilder::new(&mut data).unwrap().finish();
3638
assert_eq!(c.0.end as usize - c.0.begin as usize, len);
3739
}
3840

@@ -42,6 +44,7 @@ mod test {
4244
let c = ConfigBuilder::with_callback(
4345
&mut data, |c, p| {
4446
(Unknown::new(c.0.cpu.model + p[0]), 1) })
47+
.unwrap()
4548
.filter(AddrFilterBuilder::new()
4649
.addr0(AddrRange::new(1, 2, AddrConfig::STOP))
4750
.addr1(AddrRange::new(3, 4, AddrConfig::FILTER))
@@ -120,7 +123,9 @@ mod test {
120123
let mut cfg = ConfigBuilder::with_callback(
121124
&mut kektop,
122125
|c, p,| { (Unknown::new(c.0.cpu.stepping + p[8]), 17) })
123-
.cpu(Cpu::intel(1, 2, 3)).finish();
126+
.unwrap()
127+
.cpu(Cpu::intel(1, 2, 3))
128+
.finish();
124129

125130
for _ in 0..10 { assert!(check_callback(&mut cfg, 13, 17)) }
126131
}
@@ -134,7 +139,7 @@ mod test {
134139
if let Cow::Owned(_) = c.0 { panic!("BUG!") }
135140
// assert_eq!(c.0.as_ref() as *const _, raw);
136141
(Unknown::new(p[100]), 17)
137-
}).cpu(Cpu::intel(1, 2, 3)).finish();
142+
}).unwrap().cpu(Cpu::intel(1, 2, 3)).finish();
138143

139144
unsafe {
140145
let mut ukn: pt_packet_unknown = std::mem::zeroed();
@@ -149,7 +154,7 @@ mod test {
149154
let mut x = [10; 10];
150155
let a : Config<()>;
151156
{
152-
let mut c = ConfigBuilder::new(&mut x);
157+
let mut c = ConfigBuilder::new(&mut x).unwrap();
153158
a = c.finish();
154159
c.cpu(Cpu::intel(1, 2, 3));
155160
let b = c.finish();
@@ -183,17 +188,22 @@ unsafe extern "C" fn decode_callback<'a, F, C>(ukn: *mut pt_packet_unknown,
183188
/// A helper type to create the libipt Configuration instance
184189
pub struct ConfigBuilder<'a, T> (pt_config, PhantomData<&'a mut T>);
185190
impl<'a, T> ConfigBuilder<'a, T> {
191+
// when theres a bug here, there might be on in `new` too.
186192
/// Initializes a Config instance with a buffer and decoder callback
187193
pub fn with_callback<F>(buf: &'a mut [u8], mut cb: F) -> Result<Self, PtError>
188194
where F: FnMut(&Config<T>, &[u8]) -> (Unknown<T>, u32),
189195
F: 'a {
196+
// yeah.. libipt doesnt handle this -_-
197+
if buf.len() < 1 { return Err(
198+
PtError::new(PtErrorCode::Invalid, "buffer cant be empty!")
199+
)}
190200
let mut cfg: pt_config = unsafe { mem::zeroed() };
191201
cfg.size = mem::size_of::<pt_config>();
192202
cfg.begin = buf.as_mut_ptr();
193203
cfg.end = unsafe { buf.as_mut_ptr().offset(buf.len() as isize) };
194204
cfg.decode.callback = Some(decode_callback::<F, T>);
195205
cfg.decode.context = &mut cb as *mut _ as *mut c_void;
196-
ConfigBuilder::<T>(cfg, PhantomData)
206+
Ok(ConfigBuilder::<T>(cfg, PhantomData))
197207
}
198208

199209
/// The cpu used for capturing the data.
@@ -238,12 +248,16 @@ impl<'a> ConfigBuilder<'a, ()> {
238248
/// Initializes a Config instance with only a buffer.
239249
/// If you want to use a decoder callback,
240250
/// use the `with_callback` function
241-
pub fn new(buf: &'a mut [u8]) -> ConfigBuilder<()> {
251+
/// returns `Invalid` when buf is empty
252+
pub fn new(buf: &'a mut [u8]) -> Result<ConfigBuilder<()>, PtError> {
253+
if buf.len() < 1 { return Err(
254+
PtError::new(PtErrorCode::Invalid, "buffer cant be empty!")
255+
)}
242256
let mut cfg: pt_config = unsafe { mem::zeroed() };
243257
cfg.size = mem::size_of::<pt_config>();
244258
cfg.begin = buf.as_mut_ptr();
245259
cfg.end = unsafe { buf.as_mut_ptr().offset(buf.len() as isize) };
246-
ConfigBuilder::<()>(cfg, PhantomData)
260+
Ok(ConfigBuilder::<()>(cfg, PhantomData))
247261
}
248262
}
249263

src/event/qry.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,20 @@ mod test {
3737

3838
#[test]
3939
fn test_qrydec_alloc() {
40-
QueryDecoder::new(&ConfigBuilder::new(&mut [0; 0]).finish()).unwrap();
40+
let kek = &mut [2; 1];
41+
QueryDecoder::new(
42+
&ConfigBuilder::new(kek).unwrap().finish()
43+
).unwrap();
4144
}
4245

4346
#[test ]
4447
fn test_qrydec_props() {
48+
let kek = &mut [2; 3];
4549
// this just checks memory safety for property access
4650
// usage can be found in the integration tests
4751
let mut b = QueryDecoder::new(
48-
&ConfigBuilder::new(&mut [0; 0]).finish()).unwrap();
52+
&ConfigBuilder::new(kek).unwrap().finish()
53+
).unwrap();
4954

5055
assert!(b.cond_branch().is_err());
5156
assert!(b.indirect_branch().is_err());

src/insn/decoder.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,20 @@ mod test {
4343

4444
#[test]
4545
fn test_insndec_alloc() {
46-
InsnDecoder::new(&ConfigBuilder::new(&mut [0; 0]).finish()).unwrap();
46+
let kek = &mut [1; 2];
47+
InsnDecoder::new(&ConfigBuilder::new(kek).unwrap().finish())
48+
.unwrap();
4749
}
4850

4951
#[test ]
5052
fn test_insndec_props() {
53+
let kek = &mut [1; 2];
5154
// this just checks memory safety for property access
5255
// usage can be found in the integration tests
5356
let mut b = InsnDecoder::new(
54-
&ConfigBuilder::new(&mut [0; 0]).finish()).unwrap();
57+
&ConfigBuilder::new(kek).unwrap().finish()
58+
).unwrap();
59+
5560
let a = b.asid().unwrap();
5661
assert!(a.cr3().is_none());
5762
assert!(a.vmcs().is_none());
@@ -187,8 +192,9 @@ impl<'a, T> InsnDecoder<'a, T> {
187192
})
188193
}
189194

190-
pub fn sync_backward(&mut self) -> Result<(), PtError> {
191-
ensure_ptok(unsafe { pt_insn_sync_backward(self.0) })
195+
pub fn sync_backward(&mut self) -> Result<Status, PtError> {
196+
extract_pterr(unsafe { pt_insn_sync_backward(self.0) })
197+
.map(|s| Status::from_bits(s).unwrap())
192198
}
193199

194200
/// Synchronize an Intel PT instruction flow decoder.
@@ -201,8 +207,9 @@ impl<'a, T> InsnDecoder<'a, T> {
201207
/// Returns BadOpc if an unknown packet is encountered.
202208
/// Returns BadPacket if an unknown packet payload is encountered.
203209
/// Returns Eos if no further synchronization point is found.
204-
pub fn sync_forward(&mut self) -> Result<(), PtError> {
205-
ensure_ptok(unsafe { pt_insn_sync_forward(self.0) })
210+
pub fn sync_forward(&mut self) -> Result<Status, PtError> {
211+
extract_pterr(unsafe { pt_insn_sync_forward(self.0) })
212+
.map(|s| Status::from_bits(s).unwrap())
206213
}
207214

208215
/// Manually synchronize an Intel PT instruction flow decoder.

src/packet/decoder.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,21 @@ mod test {
3030

3131
#[test]
3232
fn test_pktdec_alloc() {
33-
PacketDecoder::new(&ConfigBuilder::new(&mut [0; 0]).finish()).unwrap();
33+
let daturu = &mut [11; 11];
34+
PacketDecoder::new(&ConfigBuilder::new(daturu)
35+
.unwrap()
36+
.finish()
37+
).unwrap();
3438
}
3539

3640
#[test ]
3741
fn test_pktdec_props() {
42+
let daturu = &mut [11; 11];
3843
// this just checks memory safety for property access
3944
// usage can be found in the integration tests
4045
let mut p = PacketDecoder::new(
41-
&ConfigBuilder::new(&mut [0; 0]).finish()).unwrap();
46+
&ConfigBuilder::new(daturu).unwrap().finish()
47+
).unwrap();
4248
assert!(p.config().is_ok());
4349
assert!(p.offset().is_err());
4450
assert!(p.sync_offset().is_err());

src/packet/encoder.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,19 @@ mod tests {
2626

2727
#[test]
2828
fn test_pktdec_alloc() {
29-
Encoder::new(&mut ConfigBuilder::new(&mut [0; 0]).finish()).unwrap();
29+
let kek = &mut [1; 2];
30+
Encoder::new(&mut ConfigBuilder::new(kek).unwrap().finish())
31+
.unwrap();
3032
}
3133

3234
#[test ]
3335
fn test_pktdec_props() {
36+
let kek = &mut [1; 2];
3437
// this just checks memory safety for property access
3538
// usage can be found in the integration tests
36-
let mut p = Encoder::new(&mut ConfigBuilder::new(&mut [0; 0]).finish())
37-
.unwrap();
39+
let mut p = Encoder::new(
40+
&mut ConfigBuilder::new(kek).unwrap().finish()
41+
).unwrap();
3842

3943
assert!(p.config().is_ok());
4044
assert_eq!(p.offset().unwrap(), 0);

tests/integration_encoding.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use libipt::packet::*;
55
fn test_encoder_all_packets() {
66
let mut inp = [0; 132];
77
let mut cfg = ConfigBuilder::new(&mut inp)
8+
.unwrap()
89
.cpu(Cpu::intel(1, 2, 3))
910
.finish();
1011

0 commit comments

Comments
 (0)