[PATCH] ethdev: fix pointer check in GENEVE and RAW flow copy
Denis Lyulin
lyulin.2003 at mail.ru
Thu May 7 13:20:11 CEST 2026
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 at nvidia.com
Cc: adrien.mazarguil at 6wind.com
Cc: stable at dpdk.org
Signed-off-by: Denis Lyulin <lyulin.2003 at mail.ru>
---
lib/ethdev/rte_flow.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index fe8f43caff..7cf585e6f5 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -672,13 +672,17 @@ rte_flow_conv_item_spec(void *buf, const size_t size,
}),
size > sizeof(*dst.raw) ? sizeof(*dst.raw) : size);
off = sizeof(*dst.raw);
- if (type == RTE_FLOW_CONV_ITEM_SPEC ||
- (type == RTE_FLOW_CONV_ITEM_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;
+ if (spec.raw && last.raw) {
+ if (type == RTE_FLOW_CONV_ITEM_SPEC ||
+ (type == RTE_FLOW_CONV_ITEM_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;
+ } else {
+ tmp = 0;
+ }
if (tmp) {
off = RTE_ALIGN_CEIL(off, sizeof(*dst.raw->pattern));
if (size >= off + tmp) {
@@ -696,8 +700,8 @@ rte_flow_conv_item_spec(void *buf, const size_t size,
spec.geneve_opt = item->spec;
src.geneve_opt = data;
dst.geneve_opt = buf;
- tmp = spec.geneve_opt->option_len << 2;
- if (size > 0 && src.geneve_opt->data) {
+ tmp = spec.geneve_opt ? (spec.geneve_opt->option_len << 2) : 0;
+ if (size > 0 && tmp > 0 && src.geneve_opt->data) {
deep_src = (void *)((uintptr_t)(dst.geneve_opt + 1));
dst.geneve_opt->data = rte_memcpy(deep_src,
src.geneve_opt->data,
--
2.34.1
More information about the stable
mailing list