summaryrefslogtreecommitdiff
path: root/common/cmd_bootm.c
diff options
context:
space:
mode:
authorDoug Anderson <dianders@chromium.org>2011-10-05 13:31:14 -0700
committerDoug Anderson <dianders@chromium.org>2011-10-07 08:47:15 -0700
commit73829d2ccaafe12dca5e324cc348b037a079b73b (patch)
treea5f96e20a3bd709d55b07a51dcf06aaee76a68b9 /common/cmd_bootm.c
parentbd3303c4525fc91667fde0b2f64795d3b0d2d35f (diff)
CHROMIUM: bootm: Avoid 256-byte overflow in fixup_silent_linux()
This makes fixup_silent_linux() use malloc() to allocate its working space, meaning that our maximum kernel command line should only be limited by malloc(). Previously it was silently overflowing the stack. BUG=chromium-os:21313 TEST=Manual: 1. Built with: USE="-cros-debug" emerge-${BOARD} \ chromeos-u-boot \ chromeos-bootimage 2. Flashed with: cros_write_firmware --board=${BOARD} /build/${BOARD}/firmware/image.bin 3. Saw that I could boot. TEST=Manually copied unittest code (included in next checkin) to a C file and then ran it. All tests pass. Note that there is no automated way to run unittests like this in u-boot yet. Change-Id: I0b5fd0d4a3cd09b7545d676a201a11b4a9b7dada Signed-off-by: Doug Anderson <dianders@chromium.org> Reviewed-on: http://gerrit.chromium.org/gerrit/8815 Reviewed-by: Che-Liang Chiou <clchiou@chromium.org>
Diffstat (limited to 'common/cmd_bootm.c')
-rw-r--r--common/cmd_bootm.c64
1 files changed, 54 insertions, 10 deletions
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 9cad7e0fb1..ba0b4a5759 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -1209,9 +1209,38 @@ U_BOOT_CMD(
/* helper routines */
/*******************************************************************/
#ifdef CONFIG_SILENT_CONSOLE
+
+/**
+ * Wrap malloc to print a warning (if in DEBUG mode) upon failure.
+ *
+ * Note that even though a warning will be printed, NULL can still be returned
+ * by this function.
+ *
+ * This is expected to be called through the macro chkmalloc(), which handles
+ * filling in the file and line parameters.
+ *
+ * @param size Number of bytes to allocate
+ * @param file File name; filled in by chkmalloc() wrapper.
+ * @param line Line number; filled in by chkmalloc() wrapper.
+ * @return memory allocated, or NULL.
+ */
+static void *do_chkmalloc(size_t size, const char *file, unsigned int line)
+{
+ void *p = malloc(size);
+ if (!p)
+ debug("WARNING: malloc of %lu bytes failed (%s:%u)\n",
+ (unsigned long)size, file, line);
+ return p;
+}
+#define chkmalloc(size) do_chkmalloc(size, __FILE__, __LINE__)
+
+
+#define CONSOLE_ARG "console="
+#define CONSOLE_ARG_LEN (sizeof(CONSOLE_ARG) - 1)
+
static void fixup_silent_linux(void)
{
- char buf[256], *start, *end;
+ char *buf;
char *cmdline = getenv("bootargs");
/* Only fix cmdline when requested */
@@ -1219,25 +1248,40 @@ static void fixup_silent_linux(void)
return;
debug("before silent fix-up: %s\n", cmdline);
- if (cmdline) {
- start = strstr(cmdline, "console=");
+ if (cmdline && (cmdline[0] != '\0')) {
+ char *start = strstr(cmdline, "console=");
if (start) {
- end = strchr(start, ' ');
- strncpy(buf, cmdline, (start - cmdline + 8));
+ char *end = strchr(start, ' ');
+ int num_start_bytes = start - cmdline + CONSOLE_ARG_LEN;
+
+ /* We know cmdline bytes will be more than enough. */
+ buf = chkmalloc(strlen(cmdline) + 1);
+ if (!buf)
+ return;
+
+ strncpy(buf, cmdline, num_start_bytes);
if (end)
- strcpy(buf + (start - cmdline + 8), end);
+ strcpy(buf + num_start_bytes, end);
else
- buf[start - cmdline + 8] = '\0';
+ buf[num_start_bytes] = '\0';
} else {
- strcpy(buf, cmdline);
- strcat(buf, " console=");
+ buf = chkmalloc(strlen(cmdline) + 1 +
+ CONSOLE_ARG_LEN + 1);
+ if (!buf)
+ return;
+ sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);
}
} else {
- strcpy(buf, "console=");
+ buf = strdup("console=");
+ if (!buf) {
+ debug("WARNING: strdup failed in fixup_silent_linux\n");
+ return;
+ }
}
setenv("bootargs", buf);
debug("after silent fix-up: %s\n", buf);
+ free(buf);
}
#endif /* CONFIG_SILENT_CONSOLE */