Currently, ixgbe IPsec session private data stores an ethdev pointer.
That pointer is process local, but the session private data is shared,
so a secondary process can read an invalid pointer value.

Fix this by storing ethdev data pointer in session private data instead,
and using it for session/device binding checks and dev_private lookups
when adding SAs.

Fixes: 9a0752f498d2 ("net/ixgbe: enable inline IPsec")
Cc: [email protected]
Cc: [email protected]

Signed-off-by: Anatoly Burakov <[email protected]>
---
 drivers/net/intel/ixgbe/ixgbe_ipsec.c | 10 +++++-----
 drivers/net/intel/ixgbe/ixgbe_ipsec.h |  3 ++-
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/net/intel/ixgbe/ixgbe_ipsec.c 
b/drivers/net/intel/ixgbe/ixgbe_ipsec.c
index fe9a96c54d..88225bccc0 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/intel/ixgbe/ixgbe_ipsec.c
@@ -88,10 +88,10 @@ ixgbe_crypto_clear_ipsec_tables(struct rte_eth_dev *dev)
 static int
 ixgbe_crypto_add_sa(struct ixgbe_crypto_session *ic_session)
 {
-       struct rte_eth_dev *dev = ic_session->dev;
-       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct rte_eth_dev_data *dev_data = ic_session->dev_data;
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev_data->dev_private);
        struct ixgbe_ipsec *priv = IXGBE_DEV_PRIVATE_TO_IPSEC(
-                       dev->data->dev_private);
+                       dev_data->dev_private);
        uint32_t reg_val;
        int sa_index = -1;
 
@@ -405,7 +405,7 @@ ixgbe_crypto_create_session(void *device,
        memcpy(&ic_session->salt,
               &aead_xform->key.data[aead_xform->key.length], 4);
        ic_session->spi = conf->ipsec.spi;
-       ic_session->dev = eth_dev;
+       ic_session->dev_data = eth_dev->data;
 
        if (ic_session->op == IXGBE_OP_AUTHENTICATED_ENCRYPTION) {
                if (ixgbe_crypto_add_sa(ic_session)) {
@@ -430,7 +430,7 @@ ixgbe_crypto_remove_session(void *device,
        struct rte_eth_dev *eth_dev = device;
        struct ixgbe_crypto_session *ic_session = 
SECURITY_GET_SESS_PRIV(session);
 
-       if (eth_dev != ic_session->dev) {
+       if (eth_dev->data != ic_session->dev_data) {
                PMD_DRV_LOG(ERR, "Session not bound to this device");
                return -ENODEV;
        }
diff --git a/drivers/net/intel/ixgbe/ixgbe_ipsec.h 
b/drivers/net/intel/ixgbe/ixgbe_ipsec.h
index e7c7186264..356817c61b 100644
--- a/drivers/net/intel/ixgbe/ixgbe_ipsec.h
+++ b/drivers/net/intel/ixgbe/ixgbe_ipsec.h
@@ -5,6 +5,7 @@
 #ifndef IXGBE_IPSEC_H_
 #define IXGBE_IPSEC_H_
 
+#include <ethdev_driver.h>
 #include <rte_security.h>
 #include <rte_security_driver.h>
 
@@ -72,7 +73,7 @@ struct __rte_cache_aligned ixgbe_crypto_session {
        uint32_t spi;
        struct ipaddr src_ip;
        struct ipaddr dst_ip;
-       struct rte_eth_dev *dev;
+       struct rte_eth_dev_data *dev_data;
 };
 
 struct ixgbe_crypto_rx_ip_table {
-- 
2.47.3

Reply via email to