From: Barbara Skobiej <barbara.skobiej@intel.com>
An unchecked value used as a loop bound. Add verification if value of
'next_to_clean' variable is greater than 2^10 (next_to_clean is 10 bits).
Also, refactored loop so that it reads the head value only once, and also
checks if head is invalid.
Signed-off-by: Barbara Skobiej <barbara.skobiej@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
drivers/net/i40e/base/i40e_adminq.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
@@ -745,12 +745,26 @@ u16 i40e_clean_asq(struct i40e_hw *hw)
u16 ntc = asq->next_to_clean;
struct i40e_aq_desc desc_cb;
struct i40e_aq_desc *desc;
+ u32 head = 0;
+
+ if (ntc >= (1 << 10))
+ goto clean_asq_exit;
desc = I40E_ADMINQ_DESC(*asq, ntc);
details = I40E_ADMINQ_DETAILS(*asq, ntc);
- while (rd32(hw, hw->aq.asq.head) != ntc) {
+ while (true) {
+ head = rd32(hw, hw->aq.asq.head);
+
+ if (head >= asq->count) {
+ i40e_debug(hw, I40E_DEBUG_AQ_COMMAND, "Read head value is improper\n");
+ return 0;
+ }
+
+ if (head == ntc)
+ break;
+
i40e_debug(hw, I40E_DEBUG_AQ_COMMAND,
- "ntc %d head %d.\n", ntc, rd32(hw, hw->aq.asq.head));
+ "ntc %d head %d.\n", ntc, head);
if (details->callback) {
I40E_ADMINQ_CALLBACK cb_func =
@@ -770,6 +784,7 @@ u16 i40e_clean_asq(struct i40e_hw *hw)
asq->next_to_clean = ntc;
+clean_asq_exit:
return I40E_DESC_UNUSED(asq);
}