Message ID | 20250401-airoha-validate-egress-gdm-port-v4-1-c7315d33ce10@kernel.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [net,v4] net: airoha: Validate egress gdm port in airoha_ppe_foe_entry_prepare() | expand |
On Tue, Apr 01, 2025 at 11:42:30AM +0200, Lorenzo Bianconi wrote: > Dev pointer in airoha_ppe_foe_entry_prepare routine is not strictly > a device allocated by airoha_eth driver since it is an egress device > and the flowtable can contain even wlan, pppoe or vlan devices. E.g: > > flowtable ft { > hook ingress priority filter > devices = { eth1, lan1, lan2, lan3, lan4, wlan0 } > flags offload ^ > | > "not allocated by airoha_eth" -- > } > > In this case airoha_get_dsa_port() will just return the original device > pointer and we can't assume netdev priv pointer points to an > airoha_gdm_port struct. > Fix the issue validating egress gdm port in airoha_ppe_foe_entry_prepare > routine before accessing net_device priv pointer. > > Fixes: 00a7678310fe ("net: airoha: Introduce flowtable offload support") > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> > --- > Changes in v4: > - Return bool in airoha_is_valid_gdm_port() instead of int > - Link to v3: https://lore.kernel.org/r/20250331-airoha-validate-egress-gdm-port-v3-1-c14e6ba9733a@kernel.org Thanks for the update. Reviewed-by: Simon Horman <horms@kernel.org>
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c index c0a642568ac115ea9df6fbaf7133627a4405a36c..743f85a1ee380a92d22ba91f3ee42e5fcb59aec7 100644 --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c @@ -2454,6 +2454,19 @@ static void airoha_metadata_dst_free(struct airoha_gdm_port *port) } } +bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + struct airoha_gdm_port *port) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { + if (eth->ports[i] == port) + return true; + } + + return false; +} + static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np, int index) { diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h index 60690b685710c72a2e15c6c6c94240108dafa1c1..ec8908f904c61988c3dc973e187596c49af139fb 100644 --- a/drivers/net/ethernet/airoha/airoha_eth.h +++ b/drivers/net/ethernet/airoha/airoha_eth.h @@ -532,6 +532,9 @@ u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val); #define airoha_qdma_clear(qdma, offset, val) \ airoha_rmw((qdma)->regs, (offset), (val), 0) +bool airoha_is_valid_gdm_port(struct airoha_eth *eth, + struct airoha_gdm_port *port); + void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash); int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv); diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c index 8b55e871352d359fa692c253d3f3315c619472b3..f10dab935cab6fad747fdfaa70b67903904c1703 100644 --- a/drivers/net/ethernet/airoha/airoha_ppe.c +++ b/drivers/net/ethernet/airoha/airoha_ppe.c @@ -197,7 +197,8 @@ static int airoha_get_dsa_port(struct net_device **dev) #endif } -static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe, +static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth, + struct airoha_foe_entry *hwe, struct net_device *dev, int type, struct airoha_flow_data *data, int l4proto) @@ -225,6 +226,9 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe, struct airoha_gdm_port *port = netdev_priv(dev); u8 pse_port; + if (!airoha_is_valid_gdm_port(eth, port)) + return -EINVAL; + if (dsa_port >= 0) pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; else @@ -633,7 +637,7 @@ static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port, !is_valid_ether_addr(data.eth.h_dest)) return -EINVAL; - err = airoha_ppe_foe_entry_prepare(&hwe, odev, offload_type, + err = airoha_ppe_foe_entry_prepare(eth, &hwe, odev, offload_type, &data, l4proto); if (err) return err;
Dev pointer in airoha_ppe_foe_entry_prepare routine is not strictly a device allocated by airoha_eth driver since it is an egress device and the flowtable can contain even wlan, pppoe or vlan devices. E.g: flowtable ft { hook ingress priority filter devices = { eth1, lan1, lan2, lan3, lan4, wlan0 } flags offload ^ | "not allocated by airoha_eth" -- } In this case airoha_get_dsa_port() will just return the original device pointer and we can't assume netdev priv pointer points to an airoha_gdm_port struct. Fix the issue validating egress gdm port in airoha_ppe_foe_entry_prepare routine before accessing net_device priv pointer. Fixes: 00a7678310fe ("net: airoha: Introduce flowtable offload support") Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> --- Changes in v4: - Return bool in airoha_is_valid_gdm_port() instead of int - Link to v3: https://lore.kernel.org/r/20250331-airoha-validate-egress-gdm-port-v3-1-c14e6ba9733a@kernel.org Changes in v3: - Rebase on top of net tree - Fix commit log - Link to v2: https://lore.kernel.org/r/20250315-airoha-flowtable-null-ptr-fix-v2-1-94b923d30234@kernel.org Changes in v2: - Avoid checking netdev_priv pointer since it is always not NULL - Link to v1: https://lore.kernel.org/r/20250312-airoha-flowtable-null-ptr-fix-v1-1-6363fab884d0@kernel.org --- drivers/net/ethernet/airoha/airoha_eth.c | 13 +++++++++++++ drivers/net/ethernet/airoha/airoha_eth.h | 3 +++ drivers/net/ethernet/airoha/airoha_ppe.c | 8 ++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) --- base-commit: f278b6d5bb465c7fd66f3d103812947e55b376ed change-id: 20250331-airoha-validate-egress-gdm-port-336c879960ca Best regards,