Skip to content
Snippets Groups Projects
Commit bed7a272 authored by Stephen D's avatar Stephen D
Browse files

fix routing bugs & fix fuzzing

parent 5cfd79fc
No related branches found
No related tags found
No related merge requests found
......@@ -4,5 +4,7 @@ use libfuzzer_sys::fuzz_target;
use ham_cats::packet::Packet;
fuzz_target!(|data: &[u8]| {
let _ = Packet::<1024>::fully_decode(data);
let mut buf = [0; 1024];
let _ = Packet::<1024>::fully_decode(data, &mut buf);
});
#![no_main]
use libfuzzer_sys::fuzz_target;
use ham_cats::packet::Packet;
use std::convert::TryInto;
use ham_cats::{buffer::Buffer, packet::Packet};
fuzz_target!(|data: &[u8]| {
if let Ok(data) = data.try_into() {
let _ = Packet::<1024>::semi_decode(data);
let mut buf = [0; 1024];
let mut buf = Buffer::new_empty(&mut buf);
if buf.try_extend_from_slice(data).is_ok() {
let _ = Packet::<1024>::semi_decode(buf);
}
});
#![no_main]
use libfuzzer_sys::fuzz_target;
use ham_cats::packet::Packet;
use std::convert::TryInto;
use ham_cats::{buffer::Buffer, packet::Packet};
fuzz_target!(|data: &[u8]| {
if let Ok(data) = data.try_into() {
let _ = Packet::<1024>::decode(data);
let mut buf = [0; 1024];
let mut buf = Buffer::new_empty(&mut buf);
if buf.try_extend_from_slice(data).is_ok() {
let _ = Packet::<1024>::decode(buf);
}
});
......@@ -318,7 +318,7 @@ fn try_lock<'a, const N: usize, T, E, F: Fn(&mut Buffer<'a, N>) -> Result<T, E>>
#[cfg(test)]
mod tests {
use arrayvec::{ArrayString, ArrayVec};
use arrayvec::ArrayString;
use super::*;
......@@ -504,7 +504,7 @@ mod tests {
#[test]
fn semi_decode_fuzz_tests() {
let data: ArrayVec<u8, 1024> = ArrayVec::try_from(
let cases = [
&[
42, 64, 64, 64, 229, 40, 64, 64, 0, 0, 173, 173, 173, 173, 173, 173, 173, 173, 64,
64, 0, 0, 173, 187, 187, 187, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
......@@ -544,18 +544,29 @@ mod tests {
187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 126,
][..],
)
.unwrap();
&[
48, 5, 4, 255, 5, 5, 5, 5, 5, 5, 5, 37, 5, 7, 5, 5, 35, 5, 5, 5, 5, 4, 5, 7, 5, 5,
5, 5, 5, 5, 5, 5, 11, 126, 3, 101, 5, 3, 3, 96, 192, 128, 192, 192,
][..],
];
let mut buf = [0; 1024];
let _ = Packet::<1024>::fully_decode(&data, &mut buf);
for data in cases {
let mut buf = [0; 1024];
let mut buf = Buffer::new_empty(&mut buf);
buf.extend(data);
let _ = Packet::<1024>::semi_decode(buf);
}
}
#[test]
fn decode_fuzz_tests() {
let data = [4, 0, 0, 0];
let cases = [&[4, 0, 0, 0][..], &[4, 5, 0, 0, 0, 10, 255, 255, 0, 0][..]];
let mut buf = [0; 1024];
let _ = Packet::<1024>::fully_decode(&data, &mut buf);
for data in cases {
let mut buf = [0; 1024];
let mut buf = Buffer::new_empty(&mut buf);
buf.extend(&data);
let _ = Packet::<1024>::decode(buf);
}
}
}
......@@ -90,7 +90,7 @@ impl Route {
has_future,
};
if UntrustedRouteIter::new(&s).any(|v| v.is_none()) {
if UntrustedRouteIter::new(&s).any(|v| v.is_err()) {
return None;
}
......@@ -104,12 +104,6 @@ pub enum RouteNode<'a> {
Identity(&'a str, u8, bool),
}
enum UntrustedRoute<'a> {
Some(RouteNode<'a>),
None,
Invalid,
}
#[derive(Debug)]
struct UntrustedRouteIter<'a> {
route: &'a Route,
......@@ -128,55 +122,56 @@ impl<'a> UntrustedRouteIter<'a> {
}
}
fn maybe_next(&mut self) -> UntrustedRoute<'a> {
if self.i == self.route.path.len() {
return UntrustedRoute::None;
}
// Returns Err(()) if invalid
fn maybe_next(&mut self) -> Result<RouteNode<'a>, ()> {
let i_start = self.i;
self.i += 1;
if self.route.path[i_start] == 0xFE {
return UntrustedRoute::Some(RouteNode::Internet);
if *self.route.path.get(i_start).ok_or(())? == 0xFE {
return Ok(RouteNode::Internet);
}
while self.route.path[self.i] != 0xFD && self.route.path[self.i] != 0xFF {
while *self.route.path.get(self.i).ok_or(())? != 0xFD && self.route.path[self.i] != 0xFF {
self.i += 1;
}
let callsign = match core::str::from_utf8(&self.route.path[i_start..self.i]) {
Ok(x) => x,
Err(_) => return UntrustedRoute::Invalid,
};
let callsign = core::str::from_utf8(self.route.path.get(i_start..self.i).ok_or(())?)
.map_err(|_| ())?;
let is_future = self.route.path[self.i] == 0xFD;
let is_future = *self.route.path.get(self.i).ok_or(())? == 0xFD;
if self.seen_future && !is_future {
// past after future - not allowed
return UntrustedRoute::Invalid;
return Err(());
}
self.seen_future |= is_future;
self.i += 1;
let ssid = self.route.path[self.i];
let ssid = *self.route.path.get(self.i).ok_or(())?;
self.i += 1;
UntrustedRoute::Some(RouteNode::Identity(callsign, ssid, is_future))
Ok(RouteNode::Identity(callsign, ssid, is_future))
}
}
impl<'a> Iterator for UntrustedRouteIter<'a> {
type Item = Option<RouteNode<'a>>;
type Item = Result<RouteNode<'a>, ()>;
fn next(&mut self) -> Option<Self::Item> {
if self.dead {
return None;
}
match self.maybe_next() {
UntrustedRoute::Some(v) => Some(Some(v)),
UntrustedRoute::None => None,
UntrustedRoute::Invalid => Some(None),
if self.i == self.route.path.len() {
return None;
}
let r = self.maybe_next();
if r.is_err() {
self.dead = true;
}
Some(r)
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment