aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Dreier <roland@purestorage.com>2018-01-15 15:24:49 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-16 14:57:34 -0500
commit70eeff66c4696cee4076d6388b6bede5bd7ff71c (patch)
tree3e68c546ff184fea0b1b87a4af743720f3c9b34b
parent0d9c9f0f40ca262b67fc06a702b85f3976f5e1a1 (diff)
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>
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_spq.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c
index be48d9abd001..3588081b2e27 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_spq.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c
@@ -776,6 +776,7 @@ int qed_spq_post(struct qed_hwfn *p_hwfn,
776 int rc = 0; 776 int rc = 0;
777 struct qed_spq *p_spq = p_hwfn ? p_hwfn->p_spq : NULL; 777 struct qed_spq *p_spq = p_hwfn ? p_hwfn->p_spq : NULL;
778 bool b_ret_ent = true; 778 bool b_ret_ent = true;
779 bool eblock;
779 780
780 if (!p_hwfn) 781 if (!p_hwfn)
781 return -EINVAL; 782 return -EINVAL;
@@ -794,6 +795,11 @@ int qed_spq_post(struct qed_hwfn *p_hwfn,
794 if (rc) 795 if (rc)
795 goto spq_post_fail; 796 goto spq_post_fail;
796 797
798 /* Check if entry is in block mode before qed_spq_add_entry,
799 * which might kfree p_ent.
800 */
801 eblock = (p_ent->comp_mode == QED_SPQ_MODE_EBLOCK);
802
797 /* Add the request to the pending queue */ 803 /* Add the request to the pending queue */
798 rc = qed_spq_add_entry(p_hwfn, p_ent, p_ent->priority); 804 rc = qed_spq_add_entry(p_hwfn, p_ent, p_ent->priority);
799 if (rc) 805 if (rc)
@@ -811,7 +817,7 @@ int qed_spq_post(struct qed_hwfn *p_hwfn,
811 817
812 spin_unlock_bh(&p_spq->lock); 818 spin_unlock_bh(&p_spq->lock);
813 819
814 if (p_ent->comp_mode == QED_SPQ_MODE_EBLOCK) { 820 if (eblock) {
815 /* For entries in QED BLOCK mode, the completion code cannot 821 /* For entries in QED BLOCK mode, the completion code cannot
816 * perform the necessary cleanup - if it did, we couldn't 822 * perform the necessary cleanup - if it did, we couldn't
817 * access p_ent here to see whether it's successful or not. 823 * access p_ent here to see whether it's successful or not.