From 29af184eb7a79d2183307fbd4b685537aec3470b Mon Sep 17 00:00:00 2001 From: David Hendricks Date: Mon, 9 Jul 2012 18:18:19 -0700 Subject: [PATCH] copy reboot parameters in host_command_reboot() Currently host_command_reboot() casts the supplied buffer and access it directly. This works until about half-way thru the function when the same buffer potentially gets overwritten when sending the response code to the host. This CL gets around that by copying the reboot parameters into a separate buffer. Signed-off-by: David Hendricks BUG=none TEST=Tested using 'ectool reboot_ec' on Snow (see below) Before, EC console displayed "[Executing host reboot command]" and ectool showed no actual change (reboot command was being overwritten with EC_REBOOT_CANCEL): localhost ~ # ectool version | grep 'Firmware copy' Firmware copy: RO localhost ~ # ectool reboot_ec A localhost ~ # ectool version | grep 'Firmware copy' Firmware copy: RO With the patch applied, the EC console shows the EC boot-up messages and ectool confirms that the jump took place: localhost ~ # ectool version | grep 'Firmware copy' Firmware copy: RO localhost ~ # ectool reboot_ec A localhost ~ # ectool version | grep 'Firmware copy' Firmware copy: A Change-Id: I8aca8d468d1125c3fb8d320ec0fb79d2822b0b20 Reviewed-on: https://gerrit.chromium.org/gerrit/26998 Reviewed-by: Randall Spangler Tested-by: David Hendricks Commit-Ready: David Hendricks --- common/system_common.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/common/system_common.c b/common/system_common.c index 0792edcb68..701166c192 100644 --- a/common/system_common.c +++ b/common/system_common.c @@ -761,15 +761,21 @@ DECLARE_HOST_COMMAND(EC_CMD_GET_BOARD_VERSION, host_command_get_board_version); int host_command_reboot(uint8_t *data, int *resp_size) { - struct ec_params_reboot_ec *p = (struct ec_params_reboot_ec *)data; + struct ec_params_reboot_ec p; - if (p->cmd == EC_REBOOT_CANCEL) { + /* + * Ensure reboot parameters don't get clobbered when the response + * is sent in case data argument points to the host tx/rx buffer. + */ + memcpy(&p, data, sizeof(p)); + + if (p.cmd == EC_REBOOT_CANCEL) { /* Cancel pending reboot */ reboot_at_shutdown = EC_REBOOT_CANCEL; return EC_RES_SUCCESS; - } else if (p->flags & EC_REBOOT_FLAG_ON_AP_SHUTDOWN) { + } else if (p.flags & EC_REBOOT_FLAG_ON_AP_SHUTDOWN) { /* Store request for processing at chipset shutdown */ - reboot_at_shutdown = p->cmd; + reboot_at_shutdown = p.cmd; return EC_RES_SUCCESS; } @@ -786,7 +792,7 @@ int host_command_reboot(uint8_t *data, int *resp_size) #endif CPUTS("[Executing host reboot command]\n"); - switch (handle_pending_reboot(p->cmd)) { + switch (handle_pending_reboot(p.cmd)) { case EC_SUCCESS: return EC_RES_SUCCESS; case EC_ERROR_INVAL: