net/mlx5: check field size in modify field action
authorAlexander Kozyrev <akozyrev@nvidia.com>
Wed, 24 Mar 2021 15:04:34 +0000 (15:04 +0000)
committerRaslan Darawsheh <rasland@nvidia.com>
Wed, 31 Mar 2021 07:21:21 +0000 (09:21 +0200)
Add a validation check to make sure that the specified width
for MODIFY_FIELD RTE action is not bigger than a field size.

Fixes: 641dbe4fb053 ("net/mlx5: support modify field flow action")
Cc: stable@dpdk.org
Signed-off-by: Alexander Kozyrev <akozyrev@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
drivers/net/mlx5/mlx5_flow_dv.c

index 23e5849..84e1bb6 100644 (file)
@@ -4608,9 +4608,22 @@ flow_dv_validate_action_modify_field(const uint64_t action_flags,
        if (ret)
                return ret;
 
+       if (action_modify_field->width == 0)
+               return rte_flow_error_set(error, EINVAL,
+                                       RTE_FLOW_ERROR_TYPE_ACTION,
+                                       NULL,
+                                       "no bits are requested to be modified");
+       else if (action_modify_field->width > dst_width ||
+                action_modify_field->width > src_width)
+               return rte_flow_error_set(error, EINVAL,
+                                       RTE_FLOW_ERROR_TYPE_ACTION,
+                                       NULL,
+                                       "cannot modify more bits than"
+                                       " the width of a field");
        if (action_modify_field->dst.field != RTE_FLOW_FIELD_VALUE &&
            action_modify_field->dst.field != RTE_FLOW_FIELD_POINTER) {
-               if (action_modify_field->dst.offset >= dst_width ||
+               if ((action_modify_field->dst.offset +
+                    action_modify_field->width > dst_width) ||
                    (action_modify_field->dst.offset % 32))
                        return rte_flow_error_set(error, EINVAL,
                                                RTE_FLOW_ERROR_TYPE_ACTION,
@@ -4626,7 +4639,8 @@ flow_dv_validate_action_modify_field(const uint64_t action_flags,
        }
        if (action_modify_field->src.field != RTE_FLOW_FIELD_VALUE &&
            action_modify_field->src.field != RTE_FLOW_FIELD_POINTER) {
-               if (action_modify_field->src.offset >= src_width ||
+               if ((action_modify_field->src.offset +
+                    action_modify_field->width > src_width) ||
                    (action_modify_field->src.offset % 32))
                        return rte_flow_error_set(error, EINVAL,
                                                RTE_FLOW_ERROR_TYPE_ACTION,
@@ -4640,11 +4654,6 @@ flow_dv_validate_action_modify_field(const uint64_t action_flags,
                                                NULL,
                                                "cannot copy from inner headers");
        }
-       if (action_modify_field->width == 0)
-               return rte_flow_error_set(error, EINVAL,
-                                               RTE_FLOW_ERROR_TYPE_ACTION,
-                                               NULL,
-                                               "width is required for modify action");
        if (action_modify_field->dst.field ==
            action_modify_field->src.field)
                return rte_flow_error_set(error, EINVAL,