qed: Fix potential use-after-free in qed_spq_post()

We need to check if p_ent->comp_mode is QED_SPQ_MODE_EBLOCK before
calling qed_spq_add_entry(). The test is fine is the mode is EBLOCK,
but if it isn't then qed_spq_add_entry() might kfree(p_ent).

Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Roland Dreier and committed by David S. Miller 70eeff66 0d9c9f0f

+7 -1
+7 -1
drivers/net/ethernet/qlogic/qed/qed_spq.c
··· 776 int rc = 0; 777 struct qed_spq *p_spq = p_hwfn ? p_hwfn->p_spq : NULL; 778 bool b_ret_ent = true; 779 780 if (!p_hwfn) 781 return -EINVAL; ··· 795 if (rc) 796 goto spq_post_fail; 797 798 /* Add the request to the pending queue */ 799 rc = qed_spq_add_entry(p_hwfn, p_ent, p_ent->priority); 800 if (rc) ··· 817 818 spin_unlock_bh(&p_spq->lock); 819 820 - if (p_ent->comp_mode == QED_SPQ_MODE_EBLOCK) { 821 /* For entries in QED BLOCK mode, the completion code cannot 822 * perform the necessary cleanup - if it did, we couldn't 823 * access p_ent here to see whether it's successful or not.
··· 776 int rc = 0; 777 struct qed_spq *p_spq = p_hwfn ? p_hwfn->p_spq : NULL; 778 bool b_ret_ent = true; 779 + bool eblock; 780 781 if (!p_hwfn) 782 return -EINVAL; ··· 794 if (rc) 795 goto spq_post_fail; 796 797 + /* Check if entry is in block mode before qed_spq_add_entry, 798 + * which might kfree p_ent. 799 + */ 800 + eblock = (p_ent->comp_mode == QED_SPQ_MODE_EBLOCK); 801 + 802 /* Add the request to the pending queue */ 803 rc = qed_spq_add_entry(p_hwfn, p_ent, p_ent->priority); 804 if (rc) ··· 811 812 spin_unlock_bh(&p_spq->lock); 813 814 + if (eblock) { 815 /* For entries in QED BLOCK mode, the completion code cannot 816 * perform the necessary cleanup - if it did, we couldn't 817 * access p_ent here to see whether it's successful or not.