From: Pavan Nikhilesh <[email protected]>

The devargs parsing helpers wrote to the parameter structure for as
long as tokens remained, so supplying more tokens than expected
overflowed the fixed-size structures. Bound each loop to the
structure size and reject input that contains extra tokens.

Likewise, cnxk_sso_xstats_get() and cnxk_sso_xstats_reset() indexed
the xstats array with caller-supplied IDs that were never validated,
so out-of-range IDs could access past the array. Skip any ID that
falls outside the valid range.

cnxk_tim_add_entry_tmo_hwwqe() used cnt as a count of LMT lines, not
timers, when computing the remainder, so nb_timers >= 8 wrote past
the LMT line. Convert cnt to a timer count first.

Fixes: 38c2e3240ba8 ("event/cnxk: add option to control SSO HWGRP QoS")
Fixes: 20345cbda6d3 ("event/cnxk: support WQE stashing")
Fixes: b5a52c9d97e2 ("event/cnxk: add event port and queue xstats")
Fixes: 8a3d58c189fd ("event/cnxk: add option to control timer adapters")
Fixes: 822d4ef519f6 ("event/cnxk: add CN20K timer adapter")
Cc: [email protected]

Signed-off-by: Pavan Nikhilesh <[email protected]>
---
 drivers/event/cnxk/cnxk_eventdev.c       |  8 +--
 drivers/event/cnxk/cnxk_eventdev_stats.c | 64 +++++++++++++++++-------
 drivers/event/cnxk/cnxk_tim_evdev.c      |  4 +-
 drivers/event/cnxk/cnxk_tim_worker.h     |  1 +
 4 files changed, 52 insertions(+), 25 deletions(-)

diff --git a/drivers/event/cnxk/cnxk_eventdev.c 
b/drivers/event/cnxk/cnxk_eventdev.c
index 41079af2a95c..e3a3134264fe 100644
--- a/drivers/event/cnxk/cnxk_eventdev.c
+++ b/drivers/event/cnxk/cnxk_eventdev.c
@@ -488,13 +488,13 @@ parse_queue_param(char *value, void *opaque)
        if (!strlen(value))
                return;
 
-       while (tok != NULL) {
+       while (tok != NULL && val < (&queue_qos.iaq_prcnt + 1)) {
                *val = atoi(tok);
                tok = strtok(NULL, "-");
                val++;
        }
 
-       if (val != (&queue_qos.iaq_prcnt + 1)) {
+       if (tok != NULL || val != (&queue_qos.iaq_prcnt + 1)) {
                plt_err("Invalid QoS parameter expected [Qx-TAQ-IAQ]");
                return;
        }
@@ -525,13 +525,13 @@ parse_stash_param(char *value, void *opaque)
                return;
 
        val = (uint16_t *)&queue_stash;
-       while (tok != NULL) {
+       while (tok != NULL && val < (&queue_stash.stash_length + 1)) {
                *val = atoi(tok);
                tok = strtok(NULL, "|");
                val++;
        }
 
-       if (val != (&queue_stash.stash_length + 1)) {
+       if (tok != NULL || val != (&queue_stash.stash_length + 1)) {
                plt_err("Invalid QoS parameter expected 
[Qx|stash_offset|stash_length]");
                return;
        }
diff --git a/drivers/event/cnxk/cnxk_eventdev_stats.c 
b/drivers/event/cnxk/cnxk_eventdev_stats.c
index 6dea91aedf31..d88e6130b9dd 100644
--- a/drivers/event/cnxk/cnxk_eventdev_stats.c
+++ b/drivers/event/cnxk/cnxk_eventdev_stats.c
@@ -157,6 +157,8 @@ cnxk_sso_xstats_get(const struct rte_eventdev *event_dev,
        };
 
        for (i = 0; i < n && i < xstats_mode_count; i++) {
+               if (ids[i] < start_offset || (ids[i] - start_offset) >= 
xstats_mode_count)
+                       goto invalid_value;
                xstat = &xstats[ids[i] - start_offset];
                value = *(uint64_t *)((char *)rsp + xstat->offset);
                value = (value >> xstat->shift) & xstat->mask;
@@ -181,6 +183,7 @@ cnxk_sso_xstats_reset(struct rte_eventdev *event_dev,
        struct cnxk_sso_xstats_name *xstat;
        struct roc_sso_hws_stats hws_stats;
        uint32_t xstats_mode_count = 0;
+       int16_t first_id, last_id, id;
        uint32_t start_offset = 0;
        unsigned int i;
        uint64_t value;
@@ -191,44 +194,67 @@ cnxk_sso_xstats_reset(struct rte_eventdev *event_dev,
        case RTE_EVENT_DEV_XSTATS_DEVICE:
                return 0;
        case RTE_EVENT_DEV_XSTATS_PORT:
-               if (queue_port_id >= (signed int)dev->nb_event_ports)
+               if (queue_port_id >= (int16_t)dev->nb_event_ports)
                        goto invalid_value;
 
                xstats_mode_count = CNXK_SSO_NUM_HWS_XSTATS;
                xstats = sso_hws_xstats;
-               rc = roc_sso_hws_stats_get(&dev->sso, queue_port_id,
-                                          &hws_stats);
-               if (rc < 0)
-                       goto invalid_value;
-               rsp = &hws_stats;
+               /* Negative id requests a reset of all ports. */
+               first_id = (queue_port_id < 0) ? 0 : queue_port_id;
+               last_id = (queue_port_id < 0) ? (int16_t)dev->nb_event_ports - 
1 : queue_port_id;
                break;
        case RTE_EVENT_DEV_XSTATS_QUEUE:
-               if (queue_port_id >= (signed int)dev->nb_event_queues)
+               if (queue_port_id >= (int16_t)dev->nb_event_queues)
                        goto invalid_value;
 
                xstats_mode_count = CNXK_SSO_NUM_GRP_XSTATS;
                start_offset = CNXK_SSO_NUM_HWS_XSTATS;
                xstats = sso_hwgrp_xstats;
-
-               rc = roc_sso_hwgrp_stats_get(&dev->sso, queue_port_id,
-                                            &hwgrp_stats);
-               if (rc < 0)
-                       goto invalid_value;
-               rsp = &hwgrp_stats;
+               /* Negative id requests a reset of all queues. */
+               first_id = (queue_port_id < 0) ? 0 : queue_port_id;
+               last_id = (queue_port_id < 0) ? (int16_t)dev->nb_event_queues - 
1 : queue_port_id;
                break;
        default:
                plt_err("Invalid mode received");
                goto invalid_value;
        };
 
-       for (i = 0; i < n && i < xstats_mode_count; i++) {
-               xstat = &xstats[ids[i] - start_offset];
-               value = *(uint64_t *)((char *)rsp + xstat->offset);
-               value = (value >> xstat->shift) & xstat->mask;
+       for (id = first_id; id <= last_id; id++) {
+               if (mode == RTE_EVENT_DEV_XSTATS_PORT) {
+                       rc = roc_sso_hws_stats_get(&dev->sso, id, &hws_stats);
+                       if (rc < 0)
+                               goto invalid_value;
+                       rsp = &hws_stats;
+               } else {
+                       rc = roc_sso_hwgrp_stats_get(&dev->sso, id, 
&hwgrp_stats);
+                       if (rc < 0)
+                               goto invalid_value;
+                       rsp = &hwgrp_stats;
+               }
 
-               xstat->reset_snap[queue_port_id] = value;
+               if (ids == NULL) {
+                       for (i = 0; i < xstats_mode_count; i++) {
+                               xstat = &xstats[i];
+                               value = *(uint64_t *)((char *)rsp + 
xstat->offset);
+                               value = (value >> xstat->shift) & xstat->mask;
+
+                               xstat->reset_snap[id] = value;
+                       }
+                       continue;
+               }
+
+               for (i = 0; i < n; i++) {
+                       if (ids[i] < start_offset || (ids[i] - start_offset) >= 
xstats_mode_count)
+                               goto invalid_value;
+                       xstat = &xstats[ids[i] - start_offset];
+                       value = *(uint64_t *)((char *)rsp + xstat->offset);
+                       value = (value >> xstat->shift) & xstat->mask;
+
+                       xstat->reset_snap[id] = value;
+               }
        }
-       return i;
+
+       return 0;
 invalid_value:
        return -EINVAL;
 }
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c 
b/drivers/event/cnxk/cnxk_tim_evdev.c
index 75414408776d..44acd4ef5170 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.c
+++ b/drivers/event/cnxk/cnxk_tim_evdev.c
@@ -471,13 +471,13 @@ cnxk_tim_parse_ring_param(char *value, void *opaque)
        if (!strlen(value))
                return;
 
-       while (tok != NULL) {
+       while (tok != NULL && val < (&ring_ctl.enable_stats + 1)) {
                *val = atoi(tok);
                tok = strtok(NULL, "-");
                val++;
        }
 
-       if (val != (&ring_ctl.enable_stats + 1)) {
+       if (tok != NULL || val != (&ring_ctl.enable_stats + 1)) {
                plt_err("Invalid ring param expected 
[ring-chunk_sz-disable_npa-enable_stats]");
                return;
        }
diff --git a/drivers/event/cnxk/cnxk_tim_worker.h 
b/drivers/event/cnxk/cnxk_tim_worker.h
index 6a9099a23f3a..9e33ff58d683 100644
--- a/drivers/event/cnxk/cnxk_tim_worker.h
+++ b/drivers/event/cnxk/cnxk_tim_worker.h
@@ -726,6 +726,7 @@ cnxk_tim_add_entry_tmo_hwwqe(struct cnxk_tim_ring *const 
tim_ring,
                }
        }
 
+       cnt *= CNXK_TIM_ENT_PER_LMT;
        /* SIZEM1 is 0 */
        pa = (tim_ring->tbase & ~0xFF) + TIM_LF_SCHED_TIMER0;
        pa |= (uint64_t)((nb_timers - cnt) << 4);
-- 
2.50.1 (Apple Git-155)

Reply via email to