From 70341959e677328dc5d62a94a7df4e79523e5e24 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 25 Aug 2016 14:25:33 -0700 Subject: [PATCH] Add console support for restricted commands This adds support for CONFIG_RESTRICTED_CONSOLE_COMMANDS. If the appropriate options are configured, restricted commands can be prevented from running. Nothing in this CL actually uses that, but it works if you turn it on. BUG=chrome-os-partner:55322 BRANCH=none TEST=make buildall, test on Cr50 hardware I also tested it manually. If you add this to board.h: #define CONFIG_CONSOLE_COMMAND_FLAGS #define CONFIG_RESTRICTED_CONSOLE_COMMANDS #define CONFIG_CONSOLE_COMMAND_FLAGS_DEFAULT CMD_FLAG_RESTRICTED and this to board.c: static int restricted_state; int console_is_restricted(void) { return restricted_state; } static int command_lock(int argc, char **argv) { int enabled; if (argc > 1) { if (!parse_bool(argv[1], &enabled)) return EC_ERROR_PARAM1; restricted_state = enabled; } ccprintf("The restricted console lock is %s\n", restricted_state ? "enabled" : "disabled"); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND_FLAGS(lock, command_lock, "[]", "Get/Set the restricted console lock", 0); /* no restrictions */ then you can use the "lock" command to enable and disable every other console command except for it and "help". Change-Id: Ic9517f9ea7a9867f15e5d14b302246070163d558 Signed-off-by: Bill Richardson Reviewed-on: https://chromium-review.googlesource.com/376186 Reviewed-by: Randall Spangler --- common/console.c | 21 +++++++++++---- include/console.h | 66 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 67 insertions(+), 20 deletions(-) diff --git a/common/console.c b/common/console.c index 3b5524b996..785f71ce56 100644 --- a/common/console.c +++ b/common/console.c @@ -240,6 +240,11 @@ command_has_error: return EC_ERROR_UNKNOWN; } +#ifdef CONFIG_RESTRICTED_CONSOLE_COMMANDS + if (console_is_restricted() && cmd->flags & CMD_FLAG_RESTRICTED) + rv = EC_ERROR_ACCESS_DENIED; + else +#endif rv = cmd->handler(argc, argv); if (rv == EC_SUCCESS) return rv; @@ -720,12 +725,18 @@ static int command_help(int argc, char **argv) ccputs("Known commands:\n"); for (i = 0; i < rows; i++) { - ccputs(" "); + ccputs(" "); for (j = 0; j < cols; j++) { int index = j * rows + i; if (index >= ncmds) break; - ccprintf("%-15s", __cmds[index].name); +#ifdef CONFIG_RESTRICTED_CONSOLE_COMMANDS + if (console_is_restricted() && + __cmds[index].flags & CMD_FLAG_RESTRICTED) + ccprintf("-%-14s", __cmds[index].name); + else +#endif + ccprintf(" %-14s", __cmds[index].name); } ccputs("\n"); cflush(); @@ -738,9 +749,9 @@ static int command_help(int argc, char **argv) return EC_SUCCESS; } -DECLARE_CONSOLE_COMMAND(help, command_help, - "[ list | ]", - "Print command help"); +DECLARE_SAFE_CONSOLE_COMMAND(help, command_help, + "[ list | ]", + "Print command help"); #ifdef CONFIG_CONSOLE_HISTORY static int command_history(int argc, char **argv) diff --git a/include/console.h b/include/console.h index e82cd128cb..3f8935a525 100644 --- a/include/console.h +++ b/include/console.h @@ -123,22 +123,33 @@ void console_has_input(void); * @param flags Per-command flags, if needed. */ #ifndef HAS_TASK_CONSOLE -#define DECLARE_CONSOLE_COMMAND(NAME, ROUTINE, ARGDESC, HELP) \ +#define DECLARE_CONSOLE_COMMAND(NAME, ROUTINE, ARGDESC, HELP) \ + int (ROUTINE)(int argc, char **argv) __attribute__((unused)) +#define DECLARE_SAFE_CONSOLE_COMMAND(NAME, ROUTINE, ARGDESC, HELP) \ + int (ROUTINE)(int argc, char **argv) __attribute__((unused)) +#define DECLARE_CONSOLE_COMMAND_FLAGS(NAME, ROUTINE, ARGDESC, HELP, FLAGS) \ int (ROUTINE)(int argc, char **argv) __attribute__((unused)) -#elif defined(CONFIG_CONSOLE_CMDHELP) -#define DECLARE_CONSOLE_COMMAND(NAME, ROUTINE, ARGDESC, HELP) \ - static const char __con_cmd_label_##NAME[] = #NAME; \ - struct size_check##NAME { \ - int field[2 * (sizeof(__con_cmd_label_##NAME) < 16) - 1]; }; \ - const struct console_command __keep __con_cmd_##NAME \ - __attribute__((section(".rodata.cmds." #NAME))) = \ - { .name = __con_cmd_label_##NAME, \ - .handler = ROUTINE, \ - .argdesc = ARGDESC, \ - .help = HELP \ - } #else -#define DECLARE_CONSOLE_COMMAND(NAME, ROUTINE, ARGDESC, HELP) \ + +/* We always provde help args, but we may discard them to save space. */ +#if defined(CONFIG_CONSOLE_CMDHELP) +#define _HELP_ARGS(A, H) \ + .argdesc = A, \ + .help = H, +#else +#define _HELP_ARGS(A, H) +#endif + +/* We may or may not have a .flags field */ +#ifdef CONFIG_CONSOLE_COMMAND_FLAGS +#define _FLAG_ARGS(F) \ + .flags = F, +#else +#define _FLAG_ARGS(F) +#endif + +/* This macro takes all possible args and discards the ones we don't use */ +#define _DCL_CON_CMD_ALL(NAME, ROUTINE, ARGDESC, HELP, FLAGS) \ static const char __con_cmd_label_##NAME[] = #NAME; \ struct size_check##NAME { \ int field[2 * (sizeof(__con_cmd_label_##NAME) < 16) - 1]; }; \ @@ -146,7 +157,32 @@ void console_has_input(void); __attribute__((section(".rodata.cmds." #NAME))) = \ { .name = __con_cmd_label_##NAME, \ .handler = ROUTINE, \ + _HELP_ARGS(ARGDESC, HELP) \ + _FLAG_ARGS(FLAGS) \ } -#endif + +/* + * If the .flags field exists, we can use this to specify its value. If not, + * the value will be discarded so it doesn't matter. + */ +#define DECLARE_CONSOLE_COMMAND_FLAGS(NAME, ROUTINE, ARGDESC, HELP, FLAGS) \ + _DCL_CON_CMD_ALL(NAME, ROUTINE, ARGDESC, HELP, FLAGS) + +/* This works as before, for the same reason. */ +#define DECLARE_CONSOLE_COMMAND(NAME, ROUTINE, ARGDESC, HELP) \ + _DCL_CON_CMD_ALL(NAME, ROUTINE, ARGDESC, HELP, \ + CONFIG_CONSOLE_COMMAND_FLAGS_DEFAULT) + +/* + * This can be used to ensure that whatever default flag bits are set (if any), + * the command is never restricted. BE CAREFUL! You should only use this for + * commands that either do nothing or that do only safe things. + */ +#define DECLARE_SAFE_CONSOLE_COMMAND(NAME, ROUTINE, ARGDESC, HELP) \ + _DCL_CON_CMD_ALL(NAME, ROUTINE, ARGDESC, HELP, \ + (CONFIG_CONSOLE_COMMAND_FLAGS_DEFAULT & \ + ~CMD_FLAG_RESTRICTED)) + +#endif /* HAS_TASK_CONSOLE */ #endif /* __CROS_EC_CONSOLE_H */