[v3] gro: add missing invalid TCP header length check
Checks
Commit Message
When the TCP header length of input packets is invalid (i.e., less
than 20 bytes or greater than 60 bytes), check_seq_option() will
access illegal memory area when compare TCP Options, which may
cause a segmentation fault.
This patch adds missing invalid TCP header length check to avoid
illegal memory accesses.
Fixes: 0d2cbe59b719 ("lib/gro: support TCP/IPv4")
Fixes: 9e0b9d2ec0f4 ("gro: support VxLAN GRO")
Cc: stable@dpdk.org
Signed-off-by: Jiayu Hu <jiayu.hu@intel.com>
Tested-by: Yinan Wang <yinan.wang@intel.com>
---
changes in v3:
- remove l2 and l3 length checks
- rename macro
changes in v2:
- fix VxLAN header length check bug for VxLAN GRO;
- fix ethernet header length check bug;
- use sizeof() and macro to present valid header length;
- add VLAN related comments since GRO cannot process VLAN tagged packets.
lib/librte_gro/gro_tcp4.c | 7 +++++++
lib/librte_gro/gro_tcp4.h | 5 +++++
lib/librte_gro/gro_vxlan_tcp4.c | 7 +++++++
3 files changed, 19 insertions(+)
Comments
> -----Original Message-----
> From: Hu, Jiayu
> Sent: Wednesday, January 16, 2019 12:46 AM
> To: dev@dpdk.org
> Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; thomas@monjalon.net; Hu, Jiayu <jiayu.hu@intel.com>; stable@dpdk.org
> Subject: [PATCH v3] gro: add missing invalid TCP header length check
>
> When the TCP header length of input packets is invalid (i.e., less
> than 20 bytes or greater than 60 bytes), check_seq_option() will
> access illegal memory area when compare TCP Options, which may
> cause a segmentation fault.
>
> This patch adds missing invalid TCP header length check to avoid
> illegal memory accesses.
>
> Fixes: 0d2cbe59b719 ("lib/gro: support TCP/IPv4")
> Fixes: 9e0b9d2ec0f4 ("gro: support VxLAN GRO")
> Cc: stable@dpdk.org
>
> Signed-off-by: Jiayu Hu <jiayu.hu@intel.com>
> Tested-by: Yinan Wang <yinan.wang@intel.com>
> ---
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> --
> 2.7.4
16/01/2019 10:49, Ananyev, Konstantin:
> From: Hu, Jiayu
> >
> > When the TCP header length of input packets is invalid (i.e., less
> > than 20 bytes or greater than 60 bytes), check_seq_option() will
> > access illegal memory area when compare TCP Options, which may
> > cause a segmentation fault.
> >
> > This patch adds missing invalid TCP header length check to avoid
> > illegal memory accesses.
> >
> > Fixes: 0d2cbe59b719 ("lib/gro: support TCP/IPv4")
> > Fixes: 9e0b9d2ec0f4 ("gro: support VxLAN GRO")
> > Cc: stable@dpdk.org
> >
> > Signed-off-by: Jiayu Hu <jiayu.hu@intel.com>
> > Tested-by: Yinan Wang <yinan.wang@intel.com>
>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Applied, thanks
@@ -208,6 +208,13 @@ gro_tcp4_reassemble(struct rte_mbuf *pkt,
int cmp;
uint8_t find;
+ /*
+ * Don't process the packet whose TCP header length is greater
+ * than 60 bytes or less than 20 bytes.
+ */
+ if (unlikely(INVALID_TCP_HDRLEN(pkt->l4_len)))
+ return -1;
+
eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
ipv4_hdr = (struct ipv4_hdr *)((char *)eth_hdr + pkt->l2_len);
tcp_hdr = (struct tcp_hdr *)((char *)ipv4_hdr + pkt->l3_len);
@@ -17,6 +17,11 @@
*/
#define MAX_IPV4_PKT_LENGTH UINT16_MAX
+/* The maximum TCP header length */
+#define MAX_TCP_HLEN 60
+#define INVALID_TCP_HDRLEN(len) \
+ (((len) < sizeof(struct tcp_hdr)) || ((len) > MAX_TCP_HLEN))
+
/* Header fields representing a TCP/IPv4 flow */
struct tcp4_flow_key {
struct ether_addr eth_saddr;
@@ -306,6 +306,13 @@ gro_vxlan_tcp4_reassemble(struct rte_mbuf *pkt,
uint16_t hdr_len;
uint8_t find;
+ /*
+ * Don't process the packet whose TCP header length is greater
+ * than 60 bytes or less than 20 bytes.
+ */
+ if (unlikely(INVALID_TCP_HDRLEN(pkt->l4_len)))
+ return -1;
+
outer_eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
outer_ipv4_hdr = (struct ipv4_hdr *)((char *)outer_eth_hdr +
pkt->outer_l2_len);