diff options
author | John Crispin <blogic@openwrt.org> | 2014-11-19 14:09:19 +0000 |
---|---|---|
committer | John Crispin <blogic@openwrt.org> | 2014-11-19 14:09:19 +0000 |
commit | 794e4699e49c84cfeefcf18b2e7b843bf10ad19c (patch) | |
tree | 07c7f37726d69956f96c023db4e0bb55f2ffec18 /target/linux/ixp4xx | |
parent | c3d6194c74744adabfa83a02dc98319662a3e898 (diff) | |
download | master-187ad058-794e4699e49c84cfeefcf18b2e7b843bf10ad19c.tar.gz master-187ad058-794e4699e49c84cfeefcf18b2e7b843bf10ad19c.tar.bz2 master-187ad058-794e4699e49c84cfeefcf18b2e7b843bf10ad19c.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>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@43320 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/ixp4xx')
-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) |