From 8bb7978e6e4fa17701b79224c24272134361f541 Mon Sep 17 00:00:00 2001 From: liangbotong Date: Thu, 31 Aug 2023 11:42:06 +0800 Subject: [PATCH] Resolved read out of bounds caused by skb_len flip Signed-off-by: liangbotong --- newip/src/common/nip_hdr.h | 3 ++- newip/third_party/linux-5.10/net/newip/nip_input.c | 2 +- newip/third_party/linux-5.10/net/newip/tcp_nip.c | 2 ++ newip/third_party/linux-5.10/net/newip/tcp_nip_input.c | 6 +++++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/newip/src/common/nip_hdr.h b/newip/src/common/nip_hdr.h index 5c77eff..03c16ef 100644 --- a/newip/src/common/nip_hdr.h +++ b/newip/src/common/nip_hdr.h @@ -34,7 +34,8 @@ */ #define NIP_HDR_MAX 24 #define NIP_UDP_HDR_LEN 8 -#define NIP_MIN_MTU (NIP_HDR_MAX + 20) // NewIP hdr + TCP hdr +#define NIP_TCP_HDR_LEN 20 +#define NIP_MIN_MTU (NIP_HDR_MAX + NIP_TCP_HDR_LEN) #define NIP_BYTE_ALIGNMENT 2 #define NIP_BITMAP_HAVE_MORE_BIT 0x01 diff --git a/newip/third_party/linux-5.10/net/newip/nip_input.c b/newip/third_party/linux-5.10/net/newip/nip_input.c index 462c300..3e35157 100644 --- a/newip/third_party/linux-5.10/net/newip/nip_input.c +++ b/newip/third_party/linux-5.10/net/newip/nip_input.c @@ -101,7 +101,7 @@ int nip_rcv(struct sk_buff *skb, struct net_device *dev, memset(nipcb(skb), 0, sizeof(struct ninet_skb_parm)); offset = nip_hdr_parse(skb->data, skb->len, &niph); - if (offset <= 0) { + if (offset <= 0 || offset > skb->len) { nip_dbg("check in failure, errcode=%d, Drop a packet (nexthdr=%u, hdr_len=%u)", offset, niph.nexthdr, niph.hdr_len); goto drop; diff --git a/newip/third_party/linux-5.10/net/newip/tcp_nip.c b/newip/third_party/linux-5.10/net/newip/tcp_nip.c index c38f08b..9aef6c7 100644 --- a/newip/third_party/linux-5.10/net/newip/tcp_nip.c +++ b/newip/third_party/linux-5.10/net/newip/tcp_nip.c @@ -1758,6 +1758,8 @@ static int tcp_nip_rcv(struct sk_buff *skb) nip_dbg("non-four byte alignment, drop skb"); goto discard_it; } + if (!pskb_may_pull(skb, th->doff * 4)) + goto discard_it; sk = __ninet_lookup_skb(&tcp_hashinfo, skb, __tcp_hdrlen(th), th->source, th->dest, dif, &refcounted); diff --git a/newip/third_party/linux-5.10/net/newip/tcp_nip_input.c b/newip/third_party/linux-5.10/net/newip/tcp_nip_input.c index a1efb28..4019483 100644 --- a/newip/third_party/linux-5.10/net/newip/tcp_nip_input.c +++ b/newip/third_party/linux-5.10/net/newip/tcp_nip_input.c @@ -1379,7 +1379,8 @@ static void tcp_nip_dup_ack_retrans(struct sock *sk, const struct sk_buff *skb, */ int mss = tcp_nip_current_mss(sk); struct tcphdr *th = (struct tcphdr *)skb->data; - u16 discard_num = htons(th->urg_ptr); + u16 discard_num = htons(th->urg_ptr) > PKT_DISCARD_MAX ? + 0 : htons(th->urg_ptr); u32 last_nip_ssthresh = ntp->nip_ssthresh; if (tp->selective_acks[0].end_seq) @@ -1730,6 +1731,9 @@ void tcp_nip_rcv_established(struct sock *sk, struct sk_buff *skb, if (unlikely(!rcu_access_pointer(sk->sk_rx_dst))) inet_csk(sk)->icsk_af_ops->sk_rx_dst_set(sk, skb); + if (skb->len < (th->doff << 2)) + return; + if (!tcp_nip_validate_incoming(sk, skb, th, 1)) return; -- Gitee