aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorGene Cumm <gene.cumm@gmail.com>2016-01-19 06:37:41 -0500
committerGene Cumm <gene.cumm@gmail.com>2016-01-19 06:41:59 -0500
commit7cd1ed60e37f36db859a2ca3d6ee261f98dafdac (patch)
treefaa89c0124e259f8d63bb1da2755b9da42b14e6e /core
parent496bb8c2a19ccf9e8c6c67b925c492c924c9378a (diff)
parent19d0d592ee115e8772b7dc6d5594748a49b63b0c (diff)
downloadsyslinux-7cd1ed60e37f36db859a2ca3d6ee261f98dafdac.tar.gz
syslinux-7cd1ed60e37f36db859a2ca3d6ee261f98dafdac.tar.xz
syslinux-7cd1ed60e37f36db859a2ca3d6ee261f98dafdac.zip
Merge 'git://github.com/Celelibi/syslinux.git/fix/bios/tail-call-stack-overflows'
FIXME: this circumvents some of the issue but is not the cleanest and may reoccur.
Diffstat (limited to 'core')
-rw-r--r--core/elflink/load_env32.c58
1 files changed, 57 insertions, 1 deletions
diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
index 492cc095..db19c7aa 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)
{