Skip to content

Commit a285aba

Browse files
committed
route: Fix panic of integer underflow in RouteNextHopBuffer
For buffer `[0u8; 8]`, the `RouteNextHopBuffer::attributes()` will panic on `self.length() - 8` as `0u16 -8` will trigger underflow. Fixed by raising error when `self.length() < PAYLOAD_OFFSET`. We consider above all zero buffer as invalid data type instead of skipping it during pasing is because: 1. The length property is invalid, it should always bigger or equal than 8 because it is the length of payload plus header. 2. The same data will cause error in iproute2 also: The iproute code `print_rta_multipath()` has: ```c while (len >= sizeof(*nh)) { ... len -= NLMSG_ALIGN(nh->rtnh_len); nh = RTNH_NEXT(nh); close_json_object(); } ``` The `RTNH_NEXT` is defined as ```c ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len))) ``` It will cause dead loop in iproute2 for `[0u8;8]` above as NLMSG_ALIGN(0) is still 0. Resolves: #152 Signed-off-by: Gris Ge <[email protected]>
1 parent d44d500 commit a285aba

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

src/route/next_hops.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ impl<T: AsRef<[u8]>> RouteNextHopBuffer<T> {
6767
)
6868
.into());
6969
}
70+
if (self.length() as usize) < PAYLOAD_OFFSET {
71+
return Err(format!(
72+
"invalid RouteNextHopBuffer: length {} < {}",
73+
self.length(),
74+
PAYLOAD_OFFSET
75+
)
76+
.into());
77+
}
7078
Ok(())
7179
}
7280
}

src/route/tests/route_flags.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,15 @@ fn test_next_hop_max_buffer_len() {
6666
let buffer = [0xff, 0xff, 0, 0, 0, 0, 0, 0];
6767
assert!(RouteNextHopBuffer::new_checked(buffer).is_err());
6868
}
69+
70+
#[test]
71+
fn test_invalid_next_hop() {
72+
let buffer = [
73+
0, 0, // length
74+
0, // flags,
75+
0, // hops
76+
0, 0, 0, 0, // interface index
77+
0, 0, 0, 0, 0, 0, 0, 0, // payload
78+
];
79+
assert!(RouteNextHopBuffer::new_checked(buffer).is_err());
80+
}

0 commit comments

Comments
 (0)