DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH] raw/cnxk_gpio: fix out of bound access
@ 2025-06-25 11:22 Tomasz Duszynski
  0 siblings, 0 replies; only message in thread
From: Tomasz Duszynski @ 2025-06-25 11:22 UTC (permalink / raw)
  To: dev, Jakub Palider, Tomasz Duszynski

In rare circumstances such as when underlying gpio device is being
removed while userspace access is still ongoing flags returned from
ioctl() may be invalid.

Coverity issue: 469060
Coverity issue: 469061
Coverity issue: 469067
Coverity issue: 469068
Fixes: 9a5ce79325da ("raw/cnxk_gpio: switch to character-based GPIO interface")

Signed-off-by: Tomasz Duszynski <tduszynski@marvell.com>
---
 drivers/raw/cnxk_gpio/cnxk_gpio.c | 38 ++++++++++++++++++++++++-------
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c
index bb2dca5441..0549e326f9 100644
--- a/drivers/raw/cnxk_gpio/cnxk_gpio.c
+++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c
@@ -513,7 +513,7 @@ static const struct {
 	{ CNXK_GPIO_PIN_EDGE_BOTH, GPIO_V2_LINE_FLAG_EDGE_FALLING | GPIO_V2_LINE_FLAG_EDGE_RISING },
 };
 
-static enum gpio_v2_line_flag
+static int
 cnxk_gpio_edge_to_flag(enum cnxk_gpio_pin_edge edge)
 {
 	unsigned int i;
@@ -522,11 +522,13 @@ cnxk_gpio_edge_to_flag(enum cnxk_gpio_pin_edge edge)
 		if (cnxk_gpio_edge_flag[i].edge == edge)
 			break;
 	}
+	if (i == RTE_DIM(cnxk_gpio_edge_flag))
+		return -EINVAL;
 
 	return cnxk_gpio_edge_flag[i].flag;
 }
 
-static enum cnxk_gpio_pin_edge
+static int
 cnxk_gpio_flag_to_edge(enum gpio_v2_line_flag flag)
 {
 	unsigned int i;
@@ -535,6 +537,8 @@ cnxk_gpio_flag_to_edge(enum gpio_v2_line_flag flag)
 		if ((cnxk_gpio_edge_flag[i].flag & flag) == cnxk_gpio_edge_flag[i].flag)
 			break;
 	}
+	if (i == RTE_DIM(cnxk_gpio_edge_flag))
+		return -EINVAL;
 
 	return cnxk_gpio_edge_flag[i].edge;
 }
@@ -549,7 +553,7 @@ static const struct {
 	{ CNXK_GPIO_PIN_DIR_LOW, GPIO_V2_LINE_FLAG_OUTPUT },
 };
 
-static enum gpio_v2_line_flag
+static int
 cnxk_gpio_dir_to_flag(enum cnxk_gpio_pin_dir dir)
 {
 	unsigned int i;
@@ -558,11 +562,13 @@ cnxk_gpio_dir_to_flag(enum cnxk_gpio_pin_dir dir)
 		if (cnxk_gpio_dir_flag[i].dir == dir)
 			break;
 	}
+	if (i == RTE_DIM(cnxk_gpio_dir_flag))
+		return -EINVAL;
 
 	return cnxk_gpio_dir_flag[i].flag;
 }
 
-static enum cnxk_gpio_pin_dir
+static int
 cnxk_gpio_flag_to_dir(enum gpio_v2_line_flag flag)
 {
 	unsigned int i;
@@ -571,6 +577,8 @@ cnxk_gpio_flag_to_dir(enum gpio_v2_line_flag flag)
 		if ((cnxk_gpio_dir_flag[i].flag & flag) == cnxk_gpio_dir_flag[i].flag)
 			break;
 	}
+	if (i == RTE_DIM(cnxk_gpio_dir_flag))
+		return -EINVAL;
 
 	return cnxk_gpio_dir_flag[i].dir;
 }
@@ -675,7 +683,10 @@ cnxk_gpio_process_buf(struct cnxk_gpio *gpio, struct rte_rawdev_buf *rbuf)
 	case CNXK_GPIO_MSG_TYPE_SET_PIN_EDGE:
 		edge = *(enum cnxk_gpio_pin_edge *)msg->data;
 		info.flags &= ~(GPIO_V2_LINE_FLAG_EDGE_RISING | GPIO_V2_LINE_FLAG_EDGE_FALLING);
-		info.flags |= cnxk_gpio_edge_to_flag(edge);
+		ret = cnxk_gpio_edge_to_flag(edge);
+		if (ret < 0)
+			break;
+		info.flags |= ret;
 
 		config.attrs[config.num_attrs].attr.id = GPIO_V2_LINE_ATTR_ID_FLAGS;
 		config.attrs[config.num_attrs].attr.flags = info.flags;
@@ -687,7 +698,10 @@ cnxk_gpio_process_buf(struct cnxk_gpio *gpio, struct rte_rawdev_buf *rbuf)
 	case CNXK_GPIO_MSG_TYPE_SET_PIN_DIR:
 		dir = *(enum cnxk_gpio_pin_dir *)msg->data;
 		config.attrs[config.num_attrs].attr.id = GPIO_V2_LINE_ATTR_ID_FLAGS;
-		config.attrs[config.num_attrs].attr.flags = cnxk_gpio_dir_to_flag(dir);
+		ret = cnxk_gpio_dir_to_flag(dir);
+		if (ret < 0)
+			break;
+		config.attrs[config.num_attrs].attr.flags = ret;
 		config.attrs[config.num_attrs].mask = RTE_BIT64(gpio->num);
 		config.num_attrs++;
 
@@ -727,18 +741,26 @@ cnxk_gpio_process_buf(struct cnxk_gpio *gpio, struct rte_rawdev_buf *rbuf)
 		*(int *)rsp = !!(values.bits & RTE_BIT64(gpio->num));
 		break;
 	case CNXK_GPIO_MSG_TYPE_GET_PIN_EDGE:
+		ret = cnxk_gpio_flag_to_edge(info.flags);
+		if (ret < 0)
+			return ret;
+
 		rsp = rte_zmalloc(NULL, sizeof(enum cnxk_gpio_pin_edge), 0);
 		if (!rsp)
 			return -ENOMEM;
 
-		*(enum cnxk_gpio_pin_edge *)rsp = cnxk_gpio_flag_to_edge(info.flags);
+		*(enum cnxk_gpio_pin_edge *)rsp = ret;
 		break;
 	case CNXK_GPIO_MSG_TYPE_GET_PIN_DIR:
+		ret = cnxk_gpio_flag_to_dir(info.flags);
+		if (ret < 0)
+			return ret;
+
 		rsp = rte_zmalloc(NULL, sizeof(enum cnxk_gpio_pin_edge), 0);
 		if (!rsp)
 			return -ENOMEM;
 
-		*(enum cnxk_gpio_pin_dir *)rsp = cnxk_gpio_flag_to_dir(info.flags);
+		*(enum cnxk_gpio_pin_dir *)rsp = ret;
 		break;
 	case CNXK_GPIO_MSG_TYPE_GET_PIN_ACTIVE_LOW:
 		rsp = rte_zmalloc(NULL, sizeof(int), 0);
-- 
2.34.1


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2025-06-25 11:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-25 11:22 [PATCH] raw/cnxk_gpio: fix out of bound access Tomasz Duszynski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).