diff options
author | John Crispin <john@openwrt.org> | 2014-11-19 14:09:19 +0000 |
---|---|---|
committer | John Crispin <john@openwrt.org> | 2014-11-19 14:09:19 +0000 |
commit | 83381c5c8fabe913f3a6966a7acacd44c429f6e8 (patch) | |
tree | 7834ba3e2c998abf05973e833269396549449a97 /target/linux | |
parent | da5001475c093f296248fe6842d9188d4f64fd4e (diff) | |
download | upstream-83381c5c8fabe913f3a6966a7acacd44c429f6e8.tar.gz upstream-83381c5c8fabe913f3a6966a7acacd44c429f6e8.tar.bz2 upstream-83381c5c8fabe913f3a6966a7acacd44c429f6e8.zip |
ixp4xx: Don't overwrite memory in wg302v1_fixup()
wg302v1_fixup() looks for the ATAG_CMDLINE atag, it doesn't find it and
so it takes the last atag in the list and overwrites non allocated
memory.
The side effects are corrupted vital data and a kernel that doesn't
boot. More details here https://dev.openwrt.org/ticket/18356
The fix appends the fixup to the command line and updates the atag only
when it finds it.
Signed-off-by: Gianluca Anzolin <gianluca@sottospazio.it>
SVN-Revision: 43320
Diffstat (limited to 'target/linux')
-rw-r--r-- | target/linux/ixp4xx/patches-3.10/162-wg302v1_mem_fixup.patch | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/target/linux/ixp4xx/patches-3.10/162-wg302v1_mem_fixup.patch b/target/linux/ixp4xx/patches-3.10/162-wg302v1_mem_fixup.patch index 3d40802dca..75212bc2e7 100644 --- a/target/linux/ixp4xx/patches-3.10/162-wg302v1_mem_fixup.patch +++ b/target/linux/ixp4xx/patches-3.10/162-wg302v1_mem_fixup.patch @@ -4,13 +4,14 @@ &wg302v1_eth[0], }; -+static char wg302v1_mem_fixup[] __initdata = "mem=32M "; ++static char wg302v1_mem_fixup[] __initdata = " mem=32M"; + +static void __init wg302v1_fixup(struct tag *tags, char **cmdline, + struct meminfo *mi) +{ + struct tag *t = tags; + char *p = *cmdline; ++ size_t fixlen, cmdlen; + + /* Find the end of the tags table, taking note of any cmdline tag. */ + for (; t->hdr.size; t = tag_next(t)) { @@ -19,18 +20,17 @@ + } + } + -+ /* Overwrite the end of the table with a new cmdline tag. */ -+ t->hdr.tag = ATAG_CMDLINE; -+ t->hdr.size = (sizeof (struct tag_header) + -+ strlen(wg302v1_mem_fixup) + strlen(p) + 1 + 4) >> 2; -+ strlcpy(t->u.cmdline.cmdline, wg302v1_mem_fixup, COMMAND_LINE_SIZE); -+ strlcpy(t->u.cmdline.cmdline + strlen(wg302v1_mem_fixup), p, -+ COMMAND_LINE_SIZE - strlen(wg302v1_mem_fixup)); ++ fixlen = strlen(wg302v1_mem_fixup); ++ cmdlen = strlen(p); ++ if (fixlen + cmdlen >= COMMAND_LINE_SIZE) ++ return; + -+ /* Terminate the table. */ -+ t = tag_next(t); -+ t->hdr.tag = ATAG_NONE; -+ t->hdr.size = 0; ++ /* append the fixup to the cmdline */ ++ memmove(p + cmdlen, wg302v1_mem_fixup, fixlen + 1); ++ ++ /* Adjust the size of the atag if there was one */ ++ if (t->hdr.size) ++ t->hdr.size += fixlen; +} + static void __init wg302v1_init(void) |