Message ID | 20240806053742.140304-1-michael.chan@broadcom.com (mailing list archive) |
---|---|
State | Accepted |
Commit | da03f5d1b2c319a2b74fe76edeadcd8fa5f44376 |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net] bnxt_en : Fix memory out-of-bounds in bnxt_fill_hw_rss_tbl() | expand |
On Mon, Aug 05, 2024 at 10:37:42PM -0700, Michael Chan wrote: > A recent commit has modified the code in __bnxt_reserve_rings() to > set the default RSS indirection table to default only when the number > of RX rings is changing. While this works for newer firmware that > requires RX ring reservations, it causes the regression on older > firmware not requiring RX ring resrvations (BNXT_NEW_RM() returns > false). > > With older firmware, RX ring reservations are not required and so > hw_resc->resv_rx_rings is not always set to the proper value. The > comparison: > > if (old_rx_rings != bp->hw_resc.resv_rx_rings) > > in __bnxt_reserve_rings() may be false even when the RX rings are > changing. This will cause __bnxt_reserve_rings() to skip setting > the default RSS indirection table to default to match the current > number of RX rings. This may later cause bnxt_fill_hw_rss_tbl() to > use an out-of-range index. > > We already have bnxt_check_rss_tbl_no_rmgr() to handle exactly this > scenario. We just need to move it up in bnxt_need_reserve_rings() > to be called unconditionally when using older firmware. Without the > fix, if the TX rings are changing, we'll skip the > bnxt_check_rss_tbl_no_rmgr() call and __bnxt_reserve_rings() may also > skip the bnxt_set_dflt_rss_indir_tbl() call for the reason explained > in the last paragraph. Without setting the default RSS indirection > table to default, it causes the regression: > > BUG: KASAN: slab-out-of-bounds in __bnxt_hwrm_vnic_set_rss+0xb79/0xe40 > Read of size 2 at addr ffff8881c5809618 by task ethtool/31525 > Call Trace: > __bnxt_hwrm_vnic_set_rss+0xb79/0xe40 > bnxt_hwrm_vnic_rss_cfg_p5+0xf7/0x460 > __bnxt_setup_vnic_p5+0x12e/0x270 > __bnxt_open_nic+0x2262/0x2f30 > bnxt_open_nic+0x5d/0xf0 > ethnl_set_channels+0x5d4/0xb30 > ethnl_default_set_doit+0x2f1/0x620 > > Reported-by: Breno Leitao <leitao@debian.org> > Closes: https://lore.kernel.org/netdev/ZrC6jpghA3PWVWSB@gmail.com/ > Fixes: 98ba1d931f61 ("bnxt_en: Fix RSS logic in __bnxt_reserve_rings()") > Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> > Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com> > Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com> > Signed-off-by: Michael Chan <michael.chan@broadcom.com> Tested-by: Breno Leitao <leitao@debian.org>
On Mon, Aug 05, 2024 at 10:37:42PM -0700, Michael Chan wrote: > A recent commit has modified the code in __bnxt_reserve_rings() to > set the default RSS indirection table to default only when the number > of RX rings is changing. While this works for newer firmware that > requires RX ring reservations, it causes the regression on older > firmware not requiring RX ring resrvations (BNXT_NEW_RM() returns > false). > > With older firmware, RX ring reservations are not required and so > hw_resc->resv_rx_rings is not always set to the proper value. The > comparison: > > if (old_rx_rings != bp->hw_resc.resv_rx_rings) > > in __bnxt_reserve_rings() may be false even when the RX rings are > changing. This will cause __bnxt_reserve_rings() to skip setting > the default RSS indirection table to default to match the current > number of RX rings. This may later cause bnxt_fill_hw_rss_tbl() to > use an out-of-range index. > > We already have bnxt_check_rss_tbl_no_rmgr() to handle exactly this > scenario. We just need to move it up in bnxt_need_reserve_rings() > to be called unconditionally when using older firmware. Without the > fix, if the TX rings are changing, we'll skip the > bnxt_check_rss_tbl_no_rmgr() call and __bnxt_reserve_rings() may also > skip the bnxt_set_dflt_rss_indir_tbl() call for the reason explained > in the last paragraph. Without setting the default RSS indirection > table to default, it causes the regression: > > BUG: KASAN: slab-out-of-bounds in __bnxt_hwrm_vnic_set_rss+0xb79/0xe40 > Read of size 2 at addr ffff8881c5809618 by task ethtool/31525 > Call Trace: > __bnxt_hwrm_vnic_set_rss+0xb79/0xe40 > bnxt_hwrm_vnic_rss_cfg_p5+0xf7/0x460 > __bnxt_setup_vnic_p5+0x12e/0x270 > __bnxt_open_nic+0x2262/0x2f30 > bnxt_open_nic+0x5d/0xf0 > ethnl_set_channels+0x5d4/0xb30 > ethnl_default_set_doit+0x2f1/0x620 > > Reported-by: Breno Leitao <leitao@debian.org> > Closes: https://lore.kernel.org/netdev/ZrC6jpghA3PWVWSB@gmail.com/ > Fixes: 98ba1d931f61 ("bnxt_en: Fix RSS logic in __bnxt_reserve_rings()") > Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> > Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com> > Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com> > Signed-off-by: Michael Chan <michael.chan@broadcom.com> Tested-by: Breno Leitao <leitao@debian.org>
On Mon, Aug 05, 2024 at 10:37:42PM -0700, Michael Chan wrote: > A recent commit has modified the code in __bnxt_reserve_rings() to > set the default RSS indirection table to default only when the number > of RX rings is changing. While this works for newer firmware that > requires RX ring reservations, it causes the regression on older > firmware not requiring RX ring resrvations (BNXT_NEW_RM() returns > false). > > With older firmware, RX ring reservations are not required and so > hw_resc->resv_rx_rings is not always set to the proper value. The > comparison: > > if (old_rx_rings != bp->hw_resc.resv_rx_rings) > > in __bnxt_reserve_rings() may be false even when the RX rings are > changing. This will cause __bnxt_reserve_rings() to skip setting > the default RSS indirection table to default to match the current > number of RX rings. This may later cause bnxt_fill_hw_rss_tbl() to > use an out-of-range index. > > We already have bnxt_check_rss_tbl_no_rmgr() to handle exactly this > scenario. We just need to move it up in bnxt_need_reserve_rings() > to be called unconditionally when using older firmware. Without the > fix, if the TX rings are changing, we'll skip the > bnxt_check_rss_tbl_no_rmgr() call and __bnxt_reserve_rings() may also > skip the bnxt_set_dflt_rss_indir_tbl() call for the reason explained > in the last paragraph. Without setting the default RSS indirection > table to default, it causes the regression: > > BUG: KASAN: slab-out-of-bounds in __bnxt_hwrm_vnic_set_rss+0xb79/0xe40 > Read of size 2 at addr ffff8881c5809618 by task ethtool/31525 > Call Trace: > __bnxt_hwrm_vnic_set_rss+0xb79/0xe40 > bnxt_hwrm_vnic_rss_cfg_p5+0xf7/0x460 > __bnxt_setup_vnic_p5+0x12e/0x270 > __bnxt_open_nic+0x2262/0x2f30 > bnxt_open_nic+0x5d/0xf0 > ethnl_set_channels+0x5d4/0xb30 > ethnl_default_set_doit+0x2f1/0x620 > > Reported-by: Breno Leitao <leitao@debian.org> > Closes: https://lore.kernel.org/netdev/ZrC6jpghA3PWVWSB@gmail.com/ > Fixes: 98ba1d931f61 ("bnxt_en: Fix RSS logic in __bnxt_reserve_rings()") > Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> > Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com> > Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com> > Signed-off-by: Michael Chan <michael.chan@broadcom.com> Tested-by: Breno Leitao <leitao@debian.org>
On Mon, Aug 05, 2024 at 10:37:42PM -0700, Michael Chan wrote: > A recent commit has modified the code in __bnxt_reserve_rings() to > set the default RSS indirection table to default only when the number > of RX rings is changing. While this works for newer firmware that > requires RX ring reservations, it causes the regression on older > firmware not requiring RX ring resrvations (BNXT_NEW_RM() returns > false). > > With older firmware, RX ring reservations are not required and so > hw_resc->resv_rx_rings is not always set to the proper value. The > comparison: > > if (old_rx_rings != bp->hw_resc.resv_rx_rings) > > in __bnxt_reserve_rings() may be false even when the RX rings are > changing. This will cause __bnxt_reserve_rings() to skip setting > the default RSS indirection table to default to match the current > number of RX rings. This may later cause bnxt_fill_hw_rss_tbl() to > use an out-of-range index. > > We already have bnxt_check_rss_tbl_no_rmgr() to handle exactly this > scenario. We just need to move it up in bnxt_need_reserve_rings() > to be called unconditionally when using older firmware. Without the > fix, if the TX rings are changing, we'll skip the > bnxt_check_rss_tbl_no_rmgr() call and __bnxt_reserve_rings() may also > skip the bnxt_set_dflt_rss_indir_tbl() call for the reason explained > in the last paragraph. Without setting the default RSS indirection > table to default, it causes the regression: > > BUG: KASAN: slab-out-of-bounds in __bnxt_hwrm_vnic_set_rss+0xb79/0xe40 > Read of size 2 at addr ffff8881c5809618 by task ethtool/31525 > Call Trace: > __bnxt_hwrm_vnic_set_rss+0xb79/0xe40 > bnxt_hwrm_vnic_rss_cfg_p5+0xf7/0x460 > __bnxt_setup_vnic_p5+0x12e/0x270 > __bnxt_open_nic+0x2262/0x2f30 > bnxt_open_nic+0x5d/0xf0 > ethnl_set_channels+0x5d4/0xb30 > ethnl_default_set_doit+0x2f1/0x620 > > Reported-by: Breno Leitao <leitao@debian.org> > Closes: https://lore.kernel.org/netdev/ZrC6jpghA3PWVWSB@gmail.com/ > Fixes: 98ba1d931f61 ("bnxt_en: Fix RSS logic in __bnxt_reserve_rings()") > Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> > Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com> > Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com> > Signed-off-by: Michael Chan <michael.chan@broadcom.com> Tested-by: Breno Leitao <leitao@debian.org>
On Mon, Aug 05, 2024 at 10:37:42PM -0700, Michael Chan wrote: > A recent commit has modified the code in __bnxt_reserve_rings() to > set the default RSS indirection table to default only when the number > of RX rings is changing. While this works for newer firmware that > requires RX ring reservations, it causes the regression on older > firmware not requiring RX ring resrvations (BNXT_NEW_RM() returns > false). > > With older firmware, RX ring reservations are not required and so > hw_resc->resv_rx_rings is not always set to the proper value. The > comparison: > > if (old_rx_rings != bp->hw_resc.resv_rx_rings) > > in __bnxt_reserve_rings() may be false even when the RX rings are > changing. This will cause __bnxt_reserve_rings() to skip setting > the default RSS indirection table to default to match the current > number of RX rings. This may later cause bnxt_fill_hw_rss_tbl() to > use an out-of-range index. > > We already have bnxt_check_rss_tbl_no_rmgr() to handle exactly this > scenario. We just need to move it up in bnxt_need_reserve_rings() > to be called unconditionally when using older firmware. Without the > fix, if the TX rings are changing, we'll skip the > bnxt_check_rss_tbl_no_rmgr() call and __bnxt_reserve_rings() may also > skip the bnxt_set_dflt_rss_indir_tbl() call for the reason explained > in the last paragraph. Without setting the default RSS indirection > table to default, it causes the regression: > > BUG: KASAN: slab-out-of-bounds in __bnxt_hwrm_vnic_set_rss+0xb79/0xe40 > Read of size 2 at addr ffff8881c5809618 by task ethtool/31525 > Call Trace: > __bnxt_hwrm_vnic_set_rss+0xb79/0xe40 > bnxt_hwrm_vnic_rss_cfg_p5+0xf7/0x460 > __bnxt_setup_vnic_p5+0x12e/0x270 > __bnxt_open_nic+0x2262/0x2f30 > bnxt_open_nic+0x5d/0xf0 > ethnl_set_channels+0x5d4/0xb30 > ethnl_default_set_doit+0x2f1/0x620 > > Reported-by: Breno Leitao <leitao@debian.org> > Closes: https://lore.kernel.org/netdev/ZrC6jpghA3PWVWSB@gmail.com/ > Fixes: 98ba1d931f61 ("bnxt_en: Fix RSS logic in __bnxt_reserve_rings()") > Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> > Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com> > Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com> > Signed-off-by: Michael Chan <michael.chan@broadcom.com> Tested-by: Breno Leitao <leitao@debian.org>
Hello: This patch was applied to netdev/net.git (main) by Jakub Kicinski <kuba@kernel.org>: On Mon, 5 Aug 2024 22:37:42 -0700 you wrote: > A recent commit has modified the code in __bnxt_reserve_rings() to > set the default RSS indirection table to default only when the number > of RX rings is changing. While this works for newer firmware that > requires RX ring reservations, it causes the regression on older > firmware not requiring RX ring resrvations (BNXT_NEW_RM() returns > false). > > [...] Here is the summary with links: - [net] bnxt_en : Fix memory out-of-bounds in bnxt_fill_hw_rss_tbl() https://git.kernel.org/netdev/net/c/da03f5d1b2c3 You are awesome, thank you!
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 23f74c6c88b9..e27e1082ee33 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -7591,19 +7591,20 @@ static bool bnxt_need_reserve_rings(struct bnxt *bp) int rx = bp->rx_nr_rings, stat; int vnic, grp = rx; - if (hw_resc->resv_tx_rings != bp->tx_nr_rings && - bp->hwrm_spec_code >= 0x10601) - return true; - /* Old firmware does not need RX ring reservations but we still * need to setup a default RSS map when needed. With new firmware * we go through RX ring reservations first and then set up the * RSS map for the successfully reserved RX rings when needed. */ - if (!BNXT_NEW_RM(bp)) { + if (!BNXT_NEW_RM(bp)) bnxt_check_rss_tbl_no_rmgr(bp); + + if (hw_resc->resv_tx_rings != bp->tx_nr_rings && + bp->hwrm_spec_code >= 0x10601) + return true; + + if (!BNXT_NEW_RM(bp)) return false; - } vnic = bnxt_get_total_vnics(bp, rx);