[syslinux:master] core: Fix stack overflow when reloading config
syslinux-bot for Sylvain Gault
sylvain.gault at gmail.com
Tue Jan 19 03:57:04 PST 2016
Commit-ID: 19d0d592ee115e8772b7dc6d5594748a49b63b0c
Gitweb: http://www.syslinux.org/commit/19d0d592ee115e8772b7dc6d5594748a49b63b0c
Author: Sylvain Gault <sylvain.gault at gmail.com>
AuthorDate: Tue, 13 Oct 2015 05:26:30 +0200
Committer: Sylvain Gault <sylvain.gault at gmail.com>
CommitDate: Tue, 13 Oct 2015 05:44:33 +0200
core: Fix stack overflow when reloading config
The behavior when running a "CONFIG" command line is to reload
ldlinux.c32 with the new file as argument. This call never return.
In order to avoid stacking up the calls to start_ldlinux, this patch
introduce a setjmp/longjmp to return to the first call to start_ldlinux,
thus freeing all the stack space.
Signed-off-by: Sylvain Gault <sylvain.gault at gmail.com>
---
core/elflink/load_env32.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
index 492cc09..db19c7a 100644
--- a/core/elflink/load_env32.c
+++ b/core/elflink/load_env32.c
@@ -55,7 +55,7 @@ void init_module_subsystem(struct elf_module *module)
list_add(&module->list, &modules_head);
}
-__export int start_ldlinux(int argc, char **argv)
+static int _start_ldlinux(int argc, char **argv)
{
int rv;
@@ -96,6 +96,62 @@ again:
return rv;
}
+__export int start_ldlinux(int argc, char **argv)
+{
+ /* These variables are static to survive the longjmp. */
+ static int has_jmpbuf = 0;
+ static jmp_buf restart;
+ static int savedargc;
+ static char *heapargs;
+ static size_t argsmem = 0;
+ char **stackargv;
+ char *stackargs;
+ char *p, *q;
+ int i;
+
+
+ /* 1. Save the arguments on the heap */
+ for (i = 0; i < argc; i++)
+ argsmem += strlen(argv[i]) + 1;
+
+ savedargc = argc;
+ heapargs = malloc(argsmem);
+
+ p = heapargs;
+ for (i = 0; i < savedargc; i++) {
+ q = argv[i];
+ while (*q)
+ *p++ = *q++;
+
+ *p++ = '\0';
+ }
+
+ /* 2. Undo the stack if we're restarting ldlinux */
+ if (has_jmpbuf)
+ longjmp(restart, 1);
+
+ setjmp(restart);
+ has_jmpbuf = 1;
+
+ /* 3. Convert the heap memory to stack memory to avoid memory leaks */
+ stackargs = alloca(argsmem);
+ stackargv = alloca(savedargc * (sizeof(char *) + 1));
+
+ memcpy(stackargs, heapargs, argsmem);
+
+ p = stackargs;
+ for (i = 0; i < savedargc; i++) {
+ stackargv[i] = p;
+ p += strlen(p) + 1;
+ }
+
+ stackargv[savedargc] = NULL;
+
+ free(heapargs);
+
+ return _start_ldlinux(savedargc, stackargv);
+}
+
/* note to self: do _*NOT*_ use static key word on this function */
void load_env32(com32sys_t * regs __unused)
{
More information about the Syslinux-commits
mailing list