From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
To: Kyungwook Boo <bookyungwook@gmail.com>
Cc: <intel-wired-lan@lists.osuosl.org>,
<linux-kernel@vger.kernel.org>,
"Tony Nguyen" <anthony.l.nguyen@intel.com>
Subject: Re: [Intel-wired-lan] MMIO write access to an invalid page in i40e_clear_hw()
Date: Wed, 5 Mar 2025 11:27:19 +0100 [thread overview]
Message-ID: <aba0a368-b2cf-42bf-b2b5-eb09779fb214@intel.com> (raw)
In-Reply-To: <ffc91764-1142-4ba2-91b6-8c773f6f7095@gmail.com>
On 3/3/25 11:19, Kyungwook Boo wrote:
> Hello,
>
> It seems that there are invalid page MMIO write access in i40e_clear_hw()
Hi,
is this something that actually occurred, or just a theoretical bug?
(depending on that we will apply it to different tree)
please send a proper patch anyway, as it looks legit to don't go bananas
when HW gives you 0
(and CC netdev instead of generic kernel ML, perhaps that's the reason
this mail was tagged as spam for me)
> due to an integer underflow from num_pf_int(also num_vf_int seems possible).
>
> The following is a sample code in i40e_clear_hw():
>
> val = rd32(hw, I40E_GLPCI_CNF2); // (1)
> num_pf_int = FIELD_GET(I40E_GLPCI_CNF2_MSI_X_PF_N_MASK, val); // (2)
> num_vf_int = FIELD_GET(I40E_GLPCI_CNF2_MSI_X_VF_N_MASK, val);
> ...
> for (i = 0; i < num_pf_int - 2; i++) // (3)
> wr32(hw, I40E_PFINT_DYN_CTLN(i), val); // (4)
> ...
> for (i = 0; i < num_pf_int - 2; i++) // (5)
> wr32(hw, I40E_PFINT_LNKLSTN(i), val);
> ...
> for (i = 0; i < num_vf_int - 2; i++) // (6)
> wr32(hw, I40E_VPINT_LNKLSTN(i), val);
>
> An example scenario for num_pf_int:
> (1) val = 0 (if MMIO read value was 0)
> (2) num_pf_int = 0 (also zero after bit field extraction from val)
> (3) An integer underflow occurs (num_pf_int - 2 == 0xfffffffe)
> (4) Out-of-bounds MMIO write access if access address exceeds the expected
> range.
>
> From above example scenario, the maximum access offset value can be around
> 0x4000347f8(=172G) which seems like this underflow is not intended(also there
> are masking operations like (2) for num_pf_int), so I report this issue.
>
> I think similar issue also could happen at (5) and (6).
>
> The following is the patch method I propose:
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
> index 370b4bddee44..97ef79be39b3 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_common.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
> @@ -848,19 +848,25 @@ void i40e_clear_hw(struct i40e_hw *hw)
> /* stop all the interrupts */
> wr32(hw, I40E_PFINT_ICR0_ENA, 0);
> val = 0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
> - for (i = 0; i < num_pf_int - 2; i++)
> - wr32(hw, I40E_PFINT_DYN_CTLN(i), val);
> + if (num_pf_int > 1) {
instead of adding if conditions, I would simply change the type
to be signed
> + for (i = 0; i < num_pf_int - 2; i++)
> + wr32(hw, I40E_PFINT_DYN_CTLN(i), val);
> + }
>
> /* Set the FIRSTQ_INDX field to 0x7FF in PFINT_LNKLSTx */
> val = eol << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT;
> wr32(hw, I40E_PFINT_LNKLST0, val);
> - for (i = 0; i < num_pf_int - 2; i++)
> - wr32(hw, I40E_PFINT_LNKLSTN(i), val);
> + if (num_pf_int > 1) {
> + for (i = 0; i < num_pf_int - 2; i++)
> + wr32(hw, I40E_PFINT_LNKLSTN(i), val);
> + }
> val = eol << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT;
> for (i = 0; i < num_vfs; i++)
> wr32(hw, I40E_VPINT_LNKLST0(i), val);
> - for (i = 0; i < num_vf_int - 2; i++)
> - wr32(hw, I40E_VPINT_LNKLSTN(i), val);
> + if (num_vf_int > 1) {
> + for (i = 0; i < num_vf_int - 2; i++)
> + wr32(hw, I40E_VPINT_LNKLSTN(i), val);
> + }
>
> /* warn the HW of the coming Tx disables */
> for (i = 0; i < num_queues; i++) {
>
>
> Could you check this?
>
> Best regards,
> Kyungwook Boo
WARNING: multiple messages have this Message-ID (diff)
From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
To: Kyungwook Boo <bookyungwook@gmail.com>
Cc: <intel-wired-lan@lists.osuosl.org>,
<linux-kernel@vger.kernel.org>,
"Tony Nguyen" <anthony.l.nguyen@intel.com>
Subject: Re: MMIO write access to an invalid page in i40e_clear_hw()
Date: Wed, 5 Mar 2025 11:27:19 +0100 [thread overview]
Message-ID: <aba0a368-b2cf-42bf-b2b5-eb09779fb214@intel.com> (raw)
In-Reply-To: <ffc91764-1142-4ba2-91b6-8c773f6f7095@gmail.com>
On 3/3/25 11:19, Kyungwook Boo wrote:
> Hello,
>
> It seems that there are invalid page MMIO write access in i40e_clear_hw()
Hi,
is this something that actually occurred, or just a theoretical bug?
(depending on that we will apply it to different tree)
please send a proper patch anyway, as it looks legit to don't go bananas
when HW gives you 0
(and CC netdev instead of generic kernel ML, perhaps that's the reason
this mail was tagged as spam for me)
> due to an integer underflow from num_pf_int(also num_vf_int seems possible).
>
> The following is a sample code in i40e_clear_hw():
>
> val = rd32(hw, I40E_GLPCI_CNF2); // (1)
> num_pf_int = FIELD_GET(I40E_GLPCI_CNF2_MSI_X_PF_N_MASK, val); // (2)
> num_vf_int = FIELD_GET(I40E_GLPCI_CNF2_MSI_X_VF_N_MASK, val);
> ...
> for (i = 0; i < num_pf_int - 2; i++) // (3)
> wr32(hw, I40E_PFINT_DYN_CTLN(i), val); // (4)
> ...
> for (i = 0; i < num_pf_int - 2; i++) // (5)
> wr32(hw, I40E_PFINT_LNKLSTN(i), val);
> ...
> for (i = 0; i < num_vf_int - 2; i++) // (6)
> wr32(hw, I40E_VPINT_LNKLSTN(i), val);
>
> An example scenario for num_pf_int:
> (1) val = 0 (if MMIO read value was 0)
> (2) num_pf_int = 0 (also zero after bit field extraction from val)
> (3) An integer underflow occurs (num_pf_int - 2 == 0xfffffffe)
> (4) Out-of-bounds MMIO write access if access address exceeds the expected
> range.
>
> From above example scenario, the maximum access offset value can be around
> 0x4000347f8(=172G) which seems like this underflow is not intended(also there
> are masking operations like (2) for num_pf_int), so I report this issue.
>
> I think similar issue also could happen at (5) and (6).
>
> The following is the patch method I propose:
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
> index 370b4bddee44..97ef79be39b3 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_common.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
> @@ -848,19 +848,25 @@ void i40e_clear_hw(struct i40e_hw *hw)
> /* stop all the interrupts */
> wr32(hw, I40E_PFINT_ICR0_ENA, 0);
> val = 0x3 << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
> - for (i = 0; i < num_pf_int - 2; i++)
> - wr32(hw, I40E_PFINT_DYN_CTLN(i), val);
> + if (num_pf_int > 1) {
instead of adding if conditions, I would simply change the type
to be signed
> + for (i = 0; i < num_pf_int - 2; i++)
> + wr32(hw, I40E_PFINT_DYN_CTLN(i), val);
> + }
>
> /* Set the FIRSTQ_INDX field to 0x7FF in PFINT_LNKLSTx */
> val = eol << I40E_PFINT_LNKLST0_FIRSTQ_INDX_SHIFT;
> wr32(hw, I40E_PFINT_LNKLST0, val);
> - for (i = 0; i < num_pf_int - 2; i++)
> - wr32(hw, I40E_PFINT_LNKLSTN(i), val);
> + if (num_pf_int > 1) {
> + for (i = 0; i < num_pf_int - 2; i++)
> + wr32(hw, I40E_PFINT_LNKLSTN(i), val);
> + }
> val = eol << I40E_VPINT_LNKLST0_FIRSTQ_INDX_SHIFT;
> for (i = 0; i < num_vfs; i++)
> wr32(hw, I40E_VPINT_LNKLST0(i), val);
> - for (i = 0; i < num_vf_int - 2; i++)
> - wr32(hw, I40E_VPINT_LNKLSTN(i), val);
> + if (num_vf_int > 1) {
> + for (i = 0; i < num_vf_int - 2; i++)
> + wr32(hw, I40E_VPINT_LNKLSTN(i), val);
> + }
>
> /* warn the HW of the coming Tx disables */
> for (i = 0; i < num_queues; i++) {
>
>
> Could you check this?
>
> Best regards,
> Kyungwook Boo
next prev parent reply other threads:[~2025-03-05 10:27 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-03 10:19 [Intel-wired-lan] MMIO write access to an invalid page in i40e_clear_hw() Kyungwook Boo
2025-03-03 10:19 ` Kyungwook Boo
2025-03-05 10:13 ` [Intel-wired-lan] " Loktionov, Aleksandr
2025-03-05 10:13 ` Loktionov, Aleksandr
2025-03-06 0:19 ` Kyungwook Boo
2025-03-05 10:27 ` Przemek Kitszel [this message]
2025-03-05 10:27 ` Przemek Kitszel
2025-03-05 12:11 ` [Intel-wired-lan] " Loktionov, Aleksandr
2025-03-05 12:11 ` Loktionov, Aleksandr
2025-03-06 0:41 ` Kyungwook Boo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aba0a368-b2cf-42bf-b2b5-eb09779fb214@intel.com \
--to=przemyslaw.kitszel@intel.com \
--cc=anthony.l.nguyen@intel.com \
--cc=bookyungwook@gmail.com \
--cc=intel-wired-lan@lists.osuosl.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.