diff options
author | Roland Dreier <roland@purestorage.com> | 2018-01-15 15:24:49 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-16 14:57:34 -0500 |
commit | 70eeff66c4696cee4076d6388b6bede5bd7ff71c (patch) | |
tree | 3e68c546ff184fea0b1b87a4af743720f3c9b34b | |
parent | 0d9c9f0f40ca262b67fc06a702b85f3976f5e1a1 (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.c | 8 |
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. |