summaryrefslogtreecommitdiff
path: root/com32/elflink/ldlinux/ldlinux.c
diff options
context:
space:
mode:
authorSylvain Gault <sylvain.gault@gmail.com>2015-10-12 05:03:26 +0200
committerSylvain Gault <sylvain.gault@gmail.com>2015-10-13 05:44:33 +0200
commit7bb4e1335435397243c9b63a64a5c61c82691357 (patch)
tree9520abd28cf3b4107efac11fd573f6b1019979db /com32/elflink/ldlinux/ldlinux.c
parent91463467e4633d7c29dfb98b4079c3c330fcde95 (diff)
downloadsyslinux-7bb4e1335435397243c9b63a64a5c61c82691357.tar.gz
ldlinux: fix stack overflow when running COM32 modules
When a COM32 module exits, the functions never return and a new call to ldlinux_enter_command is made. This could fill the stack and overflow on some data present in memory. This patch use setjmp/longjmp to return to the main function and restart from there when a COM32 module exits. Signed-off-by: Sylvain Gault <sylvain.gault@gmail.com>
Diffstat (limited to 'com32/elflink/ldlinux/ldlinux.c')
-rw-r--r--com32/elflink/ldlinux/ldlinux.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
index 9b01dd3a..0172117b 100644
--- a/com32/elflink/ldlinux/ldlinux.c
+++ b/com32/elflink/ldlinux/ldlinux.c
@@ -31,6 +31,8 @@ static const struct file_ext file_extensions[] = {
{ NULL, 0 },
};
+jmp_buf __return_to_command_prompt;
+
/*
* Return a pointer to one byte after the last character of the
* command.
@@ -302,6 +304,7 @@ __export int main(int argc __unused, char **argv)
const void *adv;
const char *cmdline;
size_t count = 0;
+ int retval;
ldlinux_console_init();
@@ -333,16 +336,25 @@ __export int main(int argc __unused, char **argv)
if (!syslinux_setadv(ADV_BOOTONCE, 0, NULL))
syslinux_adv_write();
- load_kernel(cmdline); /* Shouldn't return */
- ldlinux_enter_command();
- }
-
- if (!forceprompt && !shift_is_held())
- ldlinux_auto_boot();
+ /*
+ * The corresponding longjmp is located in the execute function
+ * after a COM32 module has returned.
+ */
+ retval = setjmp(__return_to_command_prompt);
+ if (retval == 0)
+ load_kernel(cmdline); /* Shouldn't return */
+ } else {
+ retval = setjmp(__return_to_command_prompt);
+ if (retval == 0) {
+ if (!forceprompt && !shift_is_held())
+ ldlinux_auto_boot();
- if (defaultlevel > 1)
- ldlinux_auto_boot();
+ if (defaultlevel > 1)
+ ldlinux_auto_boot();
+ }
+ }
+ retval = setjmp(__return_to_command_prompt);
ldlinux_enter_command();
return 0;
}