[libc] Fix longstanding signal handling bug with improperly set DS register #2191
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
After looking at how ia16-elf-gcc and OWC compilers generate some code reloading DS for fast execution when using far pointers, it occurred to me that a ELKS program might be interrupted by the hardware timer or keyboard when the process's DS != SS.
If, on return to execution from an interrupt a signal has been raised for the process and a C signal handler routine registered through
signal
, the kernel sets up the stack to return to the signal handler, rather than the interrupted normal C code. When this happens, the C library signal handling callback code saves all the registers and calls the C interrupt handler - but does not reset DS to a valid value for C signal handler which has been compiled expecting the DS == SS, and as a result the system may read/write data incorrectly and a system hang or crash results. This finding explains how on rare occasions ELKS may crash after ^C a process, even though the kernel has no known crash issues.This PR tests and fixes the above usually rare event. The following test code has been written which demonstrates the problem - the program busy loops calling a function which loads the DS register for far pointer memory access, but also having registered an interrupt handler for SIGINT (^C typed). Without this fix, the system will crash on ^C or two. With the fix, DS is set to SS and the registered interrupt handler executes normally, then resets DS to its original value before returning to the interrupted process.
The revised C library signal callback routines are updated for ia16-elf-gcc and OpenWatcom C compilers. When we implement signal handling in C86, this fix will also be implemented for that compiler.