Message ID | 20250331-airoha-validate-egress-gdm-port-v3-1-c14e6ba9733a@kernel.org (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net,v3] net: airoha: Validate egress gdm port in airoha_ppe_foe_entry_prepare() | expand |
On Mon, Mar 31, 2025 at 12:14:09PM +0200, Lorenzo Bianconi wrote: > Device pointer in airoha_ppe_foe_entry_prepare routine is not strictly > necessary a device allocated by airoha_eth driver since it is an egress nit: I think it would be clearer if "necessary" was dropped from the line above. > 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 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 | 10 ++++++++-- > 3 files changed, 24 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c > index c0a642568ac115ea9df6fbaf7133627a4405a36c..bf9c882e9c8b087dbf5e907636547a0117d1b96a 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) > } > } > > +int airoha_is_valid_gdm_port(struct airoha_eth *eth, > + struct airoha_gdm_port *port) nit: given the name of the function, perhaps returning a bool is more appropriate. > +{ > + int i; > + > + for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { > + if (eth->ports[i] == port) > + return 0; > + } > + > + return -EINVAL; > +} > + ...
> On Mon, Mar 31, 2025 at 12:14:09PM +0200, Lorenzo Bianconi wrote: > > Device pointer in airoha_ppe_foe_entry_prepare routine is not strictly > > necessary a device allocated by airoha_eth driver since it is an egress > > nit: I think it would be clearer if "necessary" was dropped from the line > above. ack, I will fix it in v4. > > > 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 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 | 10 ++++++++-- > > 3 files changed, 24 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c > > index c0a642568ac115ea9df6fbaf7133627a4405a36c..bf9c882e9c8b087dbf5e907636547a0117d1b96a 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) > > } > > } > > > > +int airoha_is_valid_gdm_port(struct airoha_eth *eth, > > + struct airoha_gdm_port *port) > > nit: given the name of the function, perhaps returning a bool is more > appropriate. ack, I will fix it in v4. Regards, Lorenzo > > > +{ > > + int i; > > + > > + for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { > > + if (eth->ports[i] == port) > > + return 0; > > + } > > + > > + return -EINVAL; > > +} > > + > > ...
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c index c0a642568ac115ea9df6fbaf7133627a4405a36c..bf9c882e9c8b087dbf5e907636547a0117d1b96a 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) } } +int 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 0; + } + + return -EINVAL; +} + 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..d199b8adffc0b25c369dc19cdc074c50af40e3bf 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) +int 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..65833e2058194a64569eafec08b80df8190bba6c 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) @@ -224,6 +225,11 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe, if (dev) { struct airoha_gdm_port *port = netdev_priv(dev); u8 pse_port; + int err; + + err = airoha_is_valid_gdm_port(eth, port); + if (err) + return err; if (dsa_port >= 0) pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id; @@ -633,7 +639,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;
Device pointer in airoha_ppe_foe_entry_prepare routine is not strictly necessary 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 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 | 10 ++++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) --- base-commit: 2ea396448f26d0d7d66224cb56500a6789c7ed07 change-id: 20250331-airoha-validate-egress-gdm-port-336c879960ca Best regards,