From db49c933fe34a54947dbc7df381fa1700dc1e74f Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Fri, 20 Mar 2026 23:35:38 +0100 Subject: First commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- .gitignore | 18 ++++++++++++ LICENSE | 15 ++++++++++ Makefile | 28 ++++++++++++++++++ README | 2 ++ config.mk | 8 ++++++ sigsegv-recovery.c | 46 +++++++++++++++++++++++++++++ stackoverflow-recovery.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 192 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README create mode 100644 config.mk create mode 100644 sigsegv-recovery.c create mode 100644 stackoverflow-recovery.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..69ef5dd --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +*\#* +*~ +*.o +*.a +*.t +*.lo +*.to +*.su +*.so +*.so.* +*.dll +*.dylib +*.gch +*.gcov +*.gcno +*.gcda +/sigsegv-recovery +/stackoverflow-recovery diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1634eae --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ +ISC License + +© 2026 Mattias Andrée + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..eb2a03e --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +.POSIX: + +CONFIGFILE = config.mk +include $(CONFIGFILE) + +OBJ =\ + sigsegv-recovery.o\ + stackoverflow-recovery.o + +HDR = + +all: $(OBJ:.o=) +$(OBJ): $(HDR) + +.c.o: + $(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + +.o: + $(CC) -o $@ $< $(LDFLAGS) + +clean: + -rm -f -- *.o *.a *.lo *.su + -rm -f -- $(OBJ:.o=) + +.SUFFIXES: +.SUFFIXES: .o .c + +.PHONY: all clean diff --git a/README b/README new file mode 100644 index 0000000..c42d5be --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +This is a just a simple example demonstrating how to make a +program recover after a segmentation violation or stack overflow. diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..f4adf12 --- /dev/null +++ b/config.mk @@ -0,0 +1,8 @@ +PREFIX = /usr +MANPREFIX = $(PREFIX)/share/man + +CC = c99 + +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE +CFLAGS = +LDFLAGS = diff --git a/sigsegv-recovery.c b/sigsegv-recovery.c new file mode 100644 index 0000000..b69449b --- /dev/null +++ b/sigsegv-recovery.c @@ -0,0 +1,46 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include + + +int *volatile just_null = NULL; + +static jmp_buf jmpenv; + + +static void +sigsegv(int signo) +{ + (void) signo; + + siglongjmp(jmpenv, 1); +} + + +int +main(void) +{ + volatile int sum = 0; + volatile int i; + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = &sigsegv; + sigfillset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + + for (i = 1; i <= 10; i++) { + if (!sigsetjmp(jmpenv, 1)) { + printf("%i: before null dereference\n", i); + sum += *just_null; + } else { + printf("%i: after null dereference\n", i); + } + } + + fflush(stdout); + return sum; +} diff --git a/stackoverflow-recovery.c b/stackoverflow-recovery.c new file mode 100644 index 0000000..436c8c7 --- /dev/null +++ b/stackoverflow-recovery.c @@ -0,0 +1,75 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include +#include + + +unsigned volatile just_one = 1; + +static jmp_buf jmpenv; + + +static void +sigsegv(int signo) +{ + (void) signo; + + siglongjmp(jmpenv, 1); +} + + +static unsigned +overflow2(size_t depth) +{ + if (!depth) + return just_one; + depth -= 1u; + return overflow2(depth) + overflow2(depth); +} + + +static unsigned +overflow(void) +{ + return overflow2(SIZE_MAX); +} + + +int +main(void) +{ + volatile unsigned sum = 0; + volatile int i; + struct sigaction sa; + stack_t ss; + + ss.ss_sp = malloc((size_t)SIGSTKSZ); + if (!ss.ss_sp) + return 1; + ss.ss_size = (size_t)SIGSTKSZ; + ss.ss_flags = 0; + if (sigaltstack(&ss, NULL)) + return 2; + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_ONSTACK; + sa.sa_handler = &sigsegv; + sigfillset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + + for (i = 1; i <= 10; i++) { + if (!sigsetjmp(jmpenv, 1)) { + printf("%i: before overflow dereference\n", i); + sum += overflow(); + } else { + printf("%i: after overflow dereference\n", i); + } + } + + fflush(stdout); + return (int)sum; +} -- cgit v1.2.3-70-g09d2