All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: Denis Lyulin <lyulin.2003@mail.ru>
Cc: Ori Kam <orika@nvidia.com>, Thomas Monjalon <thomas@monjalon.net>,
	Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>,
	Ferruh Yigit <ferruh.yigit@amd.com>,
	Michael Baum <michaelba@nvidia.com>,
	dev@dpdk.org, stable@dpdk.org, adrien.mazarguil@6wind.com
Subject: Re: [PATCH] ethdev: fix pointer check in GENEVE and RAW flow copy
Date: Sun, 17 May 2026 19:45:41 -0700	[thread overview]
Message-ID: <20260517194541.577dbba0@phoenix.local> (raw)
In-Reply-To: <20260507112012.119140-1-lyulin.2003@mail.ru>

On Thu,  7 May 2026 14:20:11 +0300
Denis Lyulin <lyulin.2003@mail.ru> wrote:

> When rte_flow_conv_item_spec() is called from rte_flow_conv_pattern(),
> the spec, last and mask pointers are checked separately. If the API
> is used incorrectly, the spec pointer may be NULL while last and mask
> may be valid pointers.
> 
> In rte_flow_conv_item_spec() for GENVE_OPT and RAW item types the spec
> pointer is used even if the function is called to copy last or mask.
> It may cause a NULL pointer (spec) dereference.
> 
> This commit adds extra check of item->spec and if it is NULL, does not
> copy further data relying on it
> 
> Fixes: 841a0445442d ("ethdev: fix GENEVE option item conversion")
> Cc: michaelba@nvidia.com
> Cc: adrien.mazarguil@6wind.com
> Cc: stable@dpdk.org
> 
> Signed-off-by: Denis Lyulin <lyulin.2003@mail.ru>
> ---

AI spotted a couple issues here, please address.

Warnings
========

* lib/ethdev/rte_flow.c: RAW case guard is overly broad and regresses
  the LAST-without-spec path.

  The new wrapper `if (spec.raw && last.raw) { ... } else { tmp = 0; }`
  is too coarse. The original code only dereferences spec.raw on the
  SPEC and MASK paths:

    if (type == RTE_FLOW_CONV_ITEM_SPEC ||                  // uses spec, mask
        (type == RTE_FLOW_CONV_ITEM_MASK &&                 // uses spec, last, mask
         ((spec.raw->length & mask.raw->length) >=
          (last.raw->length & mask.raw->length))))
            tmp = spec.raw->length & mask.raw->length;
    else
            tmp = last.raw->length & mask.raw->length;      // uses last, mask only

  For type == RTE_FLOW_CONV_ITEM_LAST the else branch is taken and
  spec.raw is never touched. With the patch, when an item has
  item->last set but item->spec == NULL, the wrapper short-circuits
  to tmp = 0 and the `last` pattern is silently dropped (dst.raw->
  pattern stays NULL after the struct-initializer memcpy). The
  original code copied it correctly.

  rte_flow_conv_pattern() calls this function with type=LAST whenever
  src->last is non-NULL, regardless of src->spec, so this path is
  reachable through the public conv API.

  Note also that mask.raw is guaranteed non-NULL by the
  `item->mask ? item->mask : &rte_flow_item_raw_mask` fallback two
  lines above, so it does not need to participate in the guard.

  A more surgical guard preserves the LAST behaviour, e.g.:

    if (type == RTE_FLOW_CONV_ITEM_SPEC && spec.raw)
            tmp = spec.raw->length & mask.raw->length;
    else if (type == RTE_FLOW_CONV_ITEM_MASK && spec.raw && last.raw &&
             ((spec.raw->length & mask.raw->length) >=
              (last.raw->length & mask.raw->length)))
            tmp = spec.raw->length & mask.raw->length;
    else if (last.raw)
            tmp = last.raw->length & mask.raw->length;
    else
            tmp = 0;

Info
====

* The commit message attributes the bug only to calls from
  rte_flow_conv_pattern(), but the more directly reachable path is
  rte_flow_conv() with RTE_FLOW_CONV_OP_ITEM_MASK (rte_flow.c around
  line 1144), which validates only item->mask and leaves item->spec
  potentially NULL before invoking rte_flow_conv_item_spec() with
  type=MASK. Worth mentioning so reviewers can locate the trigger.

* The GENEVE_OPT hunk uses spec.geneve_opt->option_len to size the
  copy of src.geneve_opt->data, even when src is the mask (type=MASK)
  or the last (type=LAST). This pre-existing assumption (that
  spec.option_len describes the layout for all three) is preserved by
  the patch and is out of scope here, but worth a sanity check that
  the spec.option_len fallback to 0 (no copy) is the desired
  behaviour when only a mask is supplied via OP_ITEM_MASK.

      reply	other threads:[~2026-05-18  2:45 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-07 11:20 [PATCH] ethdev: fix pointer check in GENEVE and RAW flow copy Denis Lyulin
2026-05-18  2:45 ` Stephen Hemminger [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260517194541.577dbba0@phoenix.local \
    --to=stephen@networkplumber.org \
    --cc=adrien.mazarguil@6wind.com \
    --cc=andrew.rybchenko@oktetlabs.ru \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@amd.com \
    --cc=lyulin.2003@mail.ru \
    --cc=michaelba@nvidia.com \
    --cc=orika@nvidia.com \
    --cc=stable@dpdk.org \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.