summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluwenpeng <[email protected]>2023-09-14 16:45:20 +0800
committerluwenpeng <[email protected]>2023-09-14 18:35:17 +0800
commit9387c343d38c00efb432cfb419a3c669f4d65b3a (patch)
treed0bbede4100ea76dfce93f710b942bcab92e2f46
parent59263281be1ebcd61d45b2049aee738af5df70f1 (diff)
[bugfix] Add boundary checks to avoid overflow attacks
-rw-r--r--src/packet/packet.rs4
-rw-r--r--src/protocol/gtpv1.rs5
-rw-r--r--src/protocol/l2tp.rs3
3 files changed, 10 insertions, 2 deletions
diff --git a/src/packet/packet.rs b/src/packet/packet.rs
index 781d89b..ce7456b 100644
--- a/src/packet/packet.rs
+++ b/src/packet/packet.rs
@@ -501,7 +501,7 @@ fn handle_udp<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), Packet
match dest_port {
// GTP-U
- 2152 => handle_gtpv1_c(packet, payload),
+ 2152 => handle_gtpv1(packet, payload),
// L2TPv2
1701 => handle_l2tp(packet, payload),
_ => Ok(()),
@@ -541,7 +541,7 @@ fn handle_icmpv6<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), Pac
}
}
-fn handle_gtpv1_c<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> {
+fn handle_gtpv1<'a>(packet: &mut Packet<'a>, input: &'a [u8]) -> Result<(), PacketError> {
let result = Gtpv1Header::decode(input);
match result {
Ok((payload, header)) => {
diff --git a/src/protocol/gtpv1.rs b/src/protocol/gtpv1.rs
index 3791a58..a38da21 100644
--- a/src/protocol/gtpv1.rs
+++ b/src/protocol/gtpv1.rs
@@ -74,6 +74,11 @@ fn option_decode(input: &[u8]) -> IResult<&[u8], Gtpv1Option> {
fn extension_decode(input: &[u8]) -> IResult<&[u8], Gtpv1ExtensionHeader> {
let (input, length) = number::streaming::be_u8(input)?;
+ if length * 4 < 2 {
+ return Err(nom::Err::Incomplete(nom::Needed::new(
+ (2 - length * 4).into(),
+ )));
+ }
let (input, contents) = bytes::streaming::take(length * 4 - 2)(input)?;
let (input, next_header_type) = number::streaming::be_u8(input)?;
Ok((
diff --git a/src/protocol/l2tp.rs b/src/protocol/l2tp.rs
index fdf2b69..0496f2b 100644
--- a/src/protocol/l2tp.rs
+++ b/src/protocol/l2tp.rs
@@ -303,6 +303,9 @@ fn avp_decode(input: &[u8]) -> IResult<&[u8], AvpHeader> {
* data in a single AVP. The minimum Length of an AVP is 6. If the
* length is 6, then the Attribute Value field is absent.
*/
+ if length < 6 {
+ return Err(nom::Err::Incomplete(nom::Needed::new((6 - length).into())));
+ }
let (input, attribute_value) = bytes::streaming::take(length - 6)(input)?;
Ok((