summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-09-04 15:23:18 -0700
committerRandall Spangler <rspangler@chromium.org>2012-09-05 08:54:14 -0700
commit3a8324977272c0165792843d8d4b4f72e5b27e31 (patch)
tree2b8a3b81e7e0d613427c71a221d1a5b404b225ed
parenta55ea2ec5fb744633cab710d9e88f890ab6dc709 (diff)
downloadchrome-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.c26
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,