diff options
author | Randall Spangler <rspangler@chromium.org> | 2012-09-04 15:23:18 -0700 |
---|---|---|
committer | Randall Spangler <rspangler@chromium.org> | 2012-09-05 08:54:14 -0700 |
commit | 3a8324977272c0165792843d8d4b4f72e5b27e31 (patch) | |
tree | 2b8a3b81e7e0d613427c71a221d1a5b404b225ed | |
parent | a55ea2ec5fb744633cab710d9e88f890ab6dc709 (diff) | |
download | chrome-ec-3a8324977272c0165792843d8d4b4f72e5b27e31.tar.gz |
Fix stack overflow in hostcmd command
It was putting the entire parameter buffer for a host command on the
stack. Now it uses shared memory.
BUG=chrome-os-partner:13613
TEST='hostcmd 4' should not cause a crash several seconds later
BRANCH=link (snow is also affected, but doesn't have enough shared memory to put the command buffer there either)
Change-Id: I8405d88857ee92a5cee429e156df5e645d5d864d
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/32181
Reviewed-by: Vic Yang <victoryang@chromium.org>
(cherry picked from commit e2de50ee7645b07eb70149748b51f5fc8b32b12d)
Reviewed-on: https://gerrit.chromium.org/gerrit/32191
Reviewed-by: Che-Liang Chiou <clchiou@chromium.org>
-rw-r--r-- | common/host_command.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/common/host_command.c b/common/host_command.c index c7fabeef3f..389bb537de 100644 --- a/common/host_command.c +++ b/common/host_command.c @@ -11,6 +11,7 @@ #include "host_command.h" #include "link_defs.h" #include "lpc.h" +#include "shared_mem.h" #include "system.h" #include "task.h" #include "timer.h" @@ -286,33 +287,47 @@ static int parse_params(char *s, uint8_t *params) static int command_host_command(int argc, char **argv) { struct host_cmd_handler_args args; - uint8_t cmd_params[EC_HOST_PARAM_SIZE]; + char *cmd_params; enum ec_status res; char *e; int rv; + /* Use shared memory for command params space */ + if (shared_mem_acquire(EC_HOST_PARAM_SIZE, &cmd_params)) { + ccputs("Can't acquire shared memory buffer.\n"); + return EC_ERROR_UNKNOWN; + } + /* Assume no version or params unless proven otherwise */ args.version = 0; args.params_size = 0; args.params = cmd_params; - if (argc < 2) + if (argc < 2) { + shared_mem_release(cmd_params); return EC_ERROR_PARAM_COUNT; + } args.command = strtoi(argv[1], &e, 0); - if (*e) + if (*e) { + shared_mem_release(cmd_params); return EC_ERROR_PARAM1; + } if (argc > 2) { args.version = strtoi(argv[2], &e, 0); - if (*e) + if (*e) { + shared_mem_release(cmd_params); return EC_ERROR_PARAM2; + } } if (argc > 3) { rv = parse_params(argv[3], cmd_params); - if (rv < 0) + if (rv < 0) { + shared_mem_release(cmd_params); return EC_ERROR_PARAM3; + } args.params_size = rv; } @@ -329,6 +344,7 @@ static int command_host_command(int argc, char **argv) else ccprintf("Command succeeded; no response.\n"); + shared_mem_release(cmd_params); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(hostcmd, command_host_command, |