diff options
author | Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | 2024-12-09 15:27:55 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-02-17 10:05:20 +0100 |
commit | fee921e3c641f64185abee83f9a6e65f0b380682 (patch) | |
tree | 9228c05e70a1626e58126cc503dcf9ddebf18059 | |
parent | 0d712f9b4b306aa146b811c21b3f85ea09415351 (diff) |
firmware: qcom: scm: Fix missing read barrier in qcom_scm_get_tzmem_pool()
commit b628510397b5cafa1f5d3e848a28affd1c635302 upstream.
Commit 2e4955167ec5 ("firmware: qcom: scm: Fix __scm and waitq
completion variable initialization") introduced a write barrier in probe
function to store global '__scm' variable. We all known barriers are
paired (see memory-barriers.txt: "Note that write barriers should
normally be paired with read or address-dependency barriers"), therefore
accessing it from concurrent contexts requires read barrier. Previous
commit added such barrier in qcom_scm_is_available(), so let's use that
directly.
Lack of this read barrier can result in fetching stale '__scm' variable
value, NULL, and dereferencing it.
Note that barrier in qcom_scm_is_available() satisfies here the control
dependency.
Fixes: ca61d6836e6f ("firmware: qcom: scm: fix a NULL-pointer dereference")
Fixes: 449d0d84bcd8 ("firmware: qcom: scm: smc: switch to using the SCM allocator")
Cc: stable@vger.kernel.org
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20241209-qcom-scm-missing-barriers-and-all-sort-of-srap-v2-2-9061013c8d92@linaro.org
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/firmware/qcom/qcom_scm.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index c1a79e81cf0b..2e093c39b610 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -217,7 +217,10 @@ static DEFINE_SPINLOCK(scm_query_lock); struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void) { - return __scm ? __scm->mempool : NULL; + if (!qcom_scm_is_available()) + return NULL; + + return __scm->mempool; } static enum qcom_scm_convention __get_convention(void) |