From: Chinmay Rath <[email protected]> Add missing lower bound check for H_WATCHDOG H_CALL's watchdogNumber parameter as per PAPR documentation ver 12.10.00 section 14.15.5 'H_WATCHDOG'.
Closes : https://gitlab.com/qemu-project/qemu/-/work_items/3600 Reviewed-by: Amit Machhiwal <[email protected]> Reported-by: huntr bubble <[email protected]> Signed-off-by: Chinmay Rath <[email protected]> Link: https://lore.kernel.org/qemu-devel/[email protected] [harshpb: corrected title prefix to hw/watchdog] Signed-off-by: Harsh Prateek Bora <[email protected]> (cherry picked from commit eea4de1bd8e8bdaa9a69b130a1a154f7c113979f) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/watchdog/spapr_watchdog.c b/hw/watchdog/spapr_watchdog.c index 2bb1d3c5325..8a7991ca8fc 100644 --- a/hw/watchdog/spapr_watchdog.c +++ b/hw/watchdog/spapr_watchdog.c @@ -127,6 +127,12 @@ static void watchdog_expired(void *pw) } } +static inline bool watchdog_number_valid(target_ulong watchdogNumber, + SpaprMachineState *spapr) +{ + return watchdogNumber >= 1 && watchdogNumber <= ARRAY_SIZE(spapr->wds); +} + static target_ulong h_watchdog(PowerPCCPU *cpu, SpaprMachineState *spapr, target_ulong opcode, target_ulong *args) @@ -145,7 +151,7 @@ static target_ulong h_watchdog(PowerPCCPU *cpu, switch (operation) { case PSERIES_WDTF_OP_START: - if (watchdogNumber > ARRAY_SIZE(spapr->wds)) { + if (!watchdog_number_valid(watchdogNumber, spapr)) { return H_P2; } if (timeoutInMs <= WDT_MIN_TIMEOUT) { @@ -170,11 +176,11 @@ static target_ulong h_watchdog(PowerPCCPU *cpu, case PSERIES_WDTF_OP_STOP: if (watchdogNumber == PSERIES_WDT_STOP_ALL) { ret = watchdog_stop_all(spapr); - } else if (watchdogNumber <= ARRAY_SIZE(spapr->wds)) { + } else if (!watchdog_number_valid(watchdogNumber, spapr)) { + return H_P2; + } else { ret = watchdog_stop(watchdogNumber, &spapr->wds[watchdogNumber - 1]); - } else { - return H_P2; } break; case PSERIES_WDTF_OP_QUERY: @@ -184,7 +190,7 @@ static target_ulong h_watchdog(PowerPCCPU *cpu, trace_spapr_watchdog_query(args[0]); break; case PSERIES_WDTF_OP_QUERY_LPM: - if (watchdogNumber > ARRAY_SIZE(spapr->wds)) { + if (!watchdog_number_valid(watchdogNumber, spapr)) { return H_P2; } args[0] = PSERIES_WDTQL_QUERY_NOT_STOPPED; -- 2.47.3
