summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSandrine Bailleux <sandrine.bailleux@arm.com>2016-06-22 16:35:01 +0100
committerSandrine Bailleux <sandrine.bailleux@arm.com>2016-07-25 12:57:42 +0100
commita1c3faa6c7f877bd81efce5b5c426393f7107104 (patch)
tree79d62138c8aca5f5f5dc7d7af0b03fcf81755e43 /lib
parent3dd9835f8ab3c2e7f57ddc92505d6c800bbacd47 (diff)
Validate psci_find_target_suspend_lvl() result
This patch adds a runtime check that psci_find_target_suspend_lvl() returns a valid value back to psci_cpu_suspend() and psci_get_stat(). If it is invalid, BL31 will now panic. Note that on the PSCI CPU suspend path there is already a debug assertion checking the validity of the target composite power state, which effectively also checks the validity of the target suspend level. Therefore, the error condition would already be caught in debug builds, but in a release build this assertion would be compiled out. On the PSCI stat path, there is currently no debug assertion checking the validity of the power state before using it as an index into the power domain state array. Although BL31 platforms ports are responsible for validating the power state parameter, the security impact (i.e. an out-of-bounds array access) of a potential platform port bug in this code would be quite high, given that this parameter comes from an untrusted source. The cost of checking this in runtime generic code is low. Change-Id: Icea85b8020e39928ac03ec0cd49805b5857b3906
Diffstat (limited to 'lib')
-rw-r--r--lib/psci/psci_main.c4
-rw-r--r--lib/psci/psci_stat.c6
2 files changed, 8 insertions, 2 deletions
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index d412be3c..3ad3dd40 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -97,6 +97,10 @@ int psci_cpu_suspend(unsigned int power_state,
== PSCI_E_SUCCESS);
target_pwrlvl = psci_find_target_suspend_lvl(&state_info);
+ if (target_pwrlvl == PSCI_INVALID_PWR_LVL) {
+ ERROR("Invalid target power level for suspend operation\n");
+ panic();
+ }
/* Fast path for CPU standby.*/
if (is_cpu_standby_req(is_power_down_state, target_pwrlvl)) {
diff --git a/lib/psci/psci_stat.c b/lib/psci/psci_stat.c
index 155bbb07..ecbe592b 100644
--- a/lib/psci/psci_stat.c
+++ b/lib/psci/psci_stat.c
@@ -259,8 +259,10 @@ int psci_get_stat(u_register_t target_cpu, unsigned int power_state,
/* Find the highest power level */
pwrlvl = psci_find_target_suspend_lvl(&state_info);
- if (pwrlvl == PSCI_INVALID_PWR_LVL)
- return PSCI_E_INVALID_PARAMS;
+ if (pwrlvl == PSCI_INVALID_PWR_LVL) {
+ ERROR("Invalid target power level for PSCI statistics operation\n");
+ panic();
+ }
/* Get the index into the stats array */
local_state = state_info.pwr_domain_state[pwrlvl];