> The reassembled total length of a packet must not exceed 65535.
> A fragment with a high offset could drive the sum past that,
> causing silent truncation since IP payload_len/total_length is 16 bits.
> 
> When reassembling a packet the total length should not be allowed
> to exceed 65535. A fragment with high offset could drive the sum
> past that, causing silent truncation.
> 
> A valid datagram never exceeds 65535 bytes, so reject any fragment
> whose resulting length would exceed that.
> Fold the test into the existing zero-length check.
> 
> Fixes: cc8f4d020c0b ("examples/ip_reassembly: initial import")
> Cc: [email protected]
> 
> Signed-off-by: Stephen Hemminger <[email protected]>
> ---
>  lib/ip_frag/rte_ipv4_reassembly.c | 9 +++++++--
>  lib/ip_frag/rte_ipv6_reassembly.c | 9 +++++++--
>  2 files changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/lib/ip_frag/rte_ipv4_reassembly.c 
> b/lib/ip_frag/rte_ipv4_reassembly.c
> index 980f7a3b77..727fc58243 100644
> --- a/lib/ip_frag/rte_ipv4_reassembly.c
> +++ b/lib/ip_frag/rte_ipv4_reassembly.c
> @@ -136,8 +136,13 @@ rte_ipv4_frag_reassemble_packet(struct rte_ip_frag_tbl
> *tbl,
>               tbl, tbl->max_cycles, tbl->entry_mask, tbl->max_entries,
>               tbl->use_entries);
> 
> -     /* check that fragment length is greater then zero. */
> -     if (ip_len <= 0) {
> +     /*
> +      * Drop fragments with no payload, and any fragment whose end would
> +      * make the reassembled datagram exceed the maximum IPv4 size. The
> +      * total_length field is 16 bits, so otherwise it is silently
> +      * truncated while the mbuf still holds the full length.
> +      */
> +     if (ip_len <= 0 || ip_ofs + ip_len + mb->l3_len > UINT16_MAX) {
>               IP_FRAG_MBUF2DR(dr, mb);
>               return NULL;
>       }
> diff --git a/lib/ip_frag/rte_ipv6_reassembly.c 
> b/lib/ip_frag/rte_ipv6_reassembly.c
> index 7c1659002b..0b44275b37 100644
> --- a/lib/ip_frag/rte_ipv6_reassembly.c
> +++ b/lib/ip_frag/rte_ipv6_reassembly.c
> @@ -174,8 +174,13 @@ rte_ipv6_frag_reassemble_packet(struct rte_ip_frag_tbl
> *tbl,
>               tbl, tbl->max_cycles, tbl->entry_mask, tbl->max_entries,
>               tbl->use_entries);
> 
> -     /* check that fragment length is greater then zero. */
> -     if (ip_len <= 0) {
> +     /*
> +      * Drop fragments with no payload, and any fragment whose end would
> +      * make the reassembled payload exceed 65535 bytes. The payload_len
> +      * field is 16 bits, so otherwise it is silently truncated while the
> +      * mbuf still holds the full length.
> +      */
> +     if (ip_len <= 0 || ip_ofs + ip_len > UINT16_MAX) {
>               IP_FRAG_MBUF2DR(dr, mb);
>               return NULL;
>       }
> --

Acked-by: Konstantin Ananyev <[email protected]>

> 2.53.0

Reply via email to