summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2024-06-04 13:09:32 -0400
committerJakob Kaivo <jkk@ung.org>2024-06-04 13:09:32 -0400
commitea6cb2d3bb1796aef2c195079fe91311a43f4b82 (patch)
tree05849e82b3791e6b8132a34d5fe04e98b2665ba7
parent9c1836f093bf18db12eef6d437ee856b4c888c95 (diff)
implement jmp_buf tracking and disallow setjmp macro suppression
-rw-r--r--mk/___setjmp.x86-64.s.d8
-rw-r--r--mk/__setjmp.d9
-rw-r--r--mk/__setjmp.x86-64.s.d8
-rw-r--r--mk/__setjmp_h.d9
-rw-r--r--mk/all.mk5
-rw-r--r--mk/deps.mk18
-rw-r--r--mk/setjmp.d2
-rw-r--r--src/setjmp/___setjmp.x86-64.s (renamed from src/setjmp/__setjmp.x86-64.s)0
-rw-r--r--src/setjmp/__setjmp.c41
-rw-r--r--src/setjmp/__setjmp_h.c3
-rw-r--r--src/setjmp/_setjmp.h58
-rw-r--r--src/setjmp/longjmp.c2
-rw-r--r--src/setjmp/setjmp.c35
13 files changed, 157 insertions, 41 deletions
diff --git a/mk/___setjmp.x86-64.s.d b/mk/___setjmp.x86-64.s.d
new file mode 100644
index 00000000..5e2f61c7
--- /dev/null
+++ b/mk/___setjmp.x86-64.s.d
@@ -0,0 +1,8 @@
+libc_C.0: libc.a(___setjmp.x86-64.s.o)
+libc.a(___setjmp.x86-64.s.o): $(OBJDIR)/___setjmp.x86-64.s.o
+ @$(AR) $(ARFLAGS) $@ $(OBJDIR)/$%
+
+$(OBJDIR)/___setjmp.x86-64.s.o: src/setjmp/___setjmp.x86-64.s
+$(OBJDIR)/___setjmp.x86-64.s.o:
+ @mkdir -p $(@D)
+ $(CC) -c -o $@ $(CFLAGS) src/setjmp/___setjmp.x86-64.s
diff --git a/mk/__setjmp.d b/mk/__setjmp.d
new file mode 100644
index 00000000..401d987e
--- /dev/null
+++ b/mk/__setjmp.d
@@ -0,0 +1,9 @@
+libc_C.1: libc.a(__setjmp.o)
+libc.a(__setjmp.o): $(OBJDIR)/__setjmp.o
+ @$(AR) $(ARFLAGS) $@ $(OBJDIR)/$%
+
+$(OBJDIR)/__setjmp.o: src/setjmp/__setjmp.c
+$(OBJDIR)/__setjmp.o: src/_safety.h
+$(OBJDIR)/__setjmp.o:
+ @mkdir -p $(@D)
+ $(CC) -c -o $@ $(CFLAGS) src/setjmp/__setjmp.c
diff --git a/mk/__setjmp.x86-64.s.d b/mk/__setjmp.x86-64.s.d
deleted file mode 100644
index 0b0e30ae..00000000
--- a/mk/__setjmp.x86-64.s.d
+++ /dev/null
@@ -1,8 +0,0 @@
-libc_C.0: libc.a(__setjmp.x86-64.s.o)
-libc.a(__setjmp.x86-64.s.o): $(OBJDIR)/__setjmp.x86-64.s.o
- @$(AR) $(ARFLAGS) $@ $(OBJDIR)/$%
-
-$(OBJDIR)/__setjmp.x86-64.s.o: src/setjmp/__setjmp.x86-64.s
-$(OBJDIR)/__setjmp.x86-64.s.o:
- @mkdir -p $(@D)
- $(CC) -c -o $@ $(CFLAGS) src/setjmp/__setjmp.x86-64.s
diff --git a/mk/__setjmp_h.d b/mk/__setjmp_h.d
new file mode 100644
index 00000000..6d696465
--- /dev/null
+++ b/mk/__setjmp_h.d
@@ -0,0 +1,9 @@
+libc_C.0: libc.a(__setjmp_h.o)
+libc.a(__setjmp_h.o): $(OBJDIR)/__setjmp_h.o
+ @$(AR) $(ARFLAGS) $@ $(OBJDIR)/$%
+
+$(OBJDIR)/__setjmp_h.o: src/setjmp/__setjmp_h.c
+$(OBJDIR)/__setjmp_h.o: src/setjmp/_setjmp.h
+$(OBJDIR)/__setjmp_h.o:
+ @mkdir -p $(@D)
+ $(CC) -c -o $@ $(CFLAGS) src/setjmp/__setjmp_h.c
diff --git a/mk/all.mk b/mk/all.mk
index 54381d43..8290eccd 100644
--- a/mk/all.mk
+++ b/mk/all.mk
@@ -216,6 +216,8 @@ include mk/nanosleep.d
include mk/mktime.d
include mk/asctime.d
include mk/__readonly.d
+include mk/__setjmp.d
+include mk/__setjmp_h.d
include mk/longjmp.d
include mk/setjmp.d
include mk/thrd_join.d
@@ -347,6 +349,7 @@ include mk/strcpy.d
include mk/strtok.d
include mk/memset.d
include mk/memmove.d
+include mk/strdup.d
include mk/strncpy.d
include mk/strcat_s.d
include mk/strnlen_s.d
@@ -476,4 +479,4 @@ include mk/calloc.d
include mk/div.d
include mk/__sys.x86-64.s.d
include mk/__longjmp.x86-64.s.d
-include mk/__setjmp.x86-64.s.d
+include mk/___setjmp.x86-64.s.d
diff --git a/mk/deps.mk b/mk/deps.mk
index 92704b76..9a08cf2c 100644
--- a/mk/deps.mk
+++ b/mk/deps.mk
@@ -874,6 +874,14 @@ all: mk/__readonly.d
mk/__readonly.d: src/__readonly.c
sh mk/deps.sh src/__readonly.c
+all: mk/__setjmp.d
+mk/__setjmp.d: src/setjmp/__setjmp.c
+ sh mk/deps.sh src/setjmp/__setjmp.c
+
+all: mk/__setjmp_h.d
+mk/__setjmp_h.d: src/setjmp/__setjmp_h.c
+ sh mk/deps.sh src/setjmp/__setjmp_h.c
+
all: mk/longjmp.d
mk/longjmp.d: src/setjmp/longjmp.c
sh mk/deps.sh src/setjmp/longjmp.c
@@ -1398,6 +1406,10 @@ all: mk/memmove.d
mk/memmove.d: src/string/memmove.c
sh mk/deps.sh src/string/memmove.c
+all: mk/strdup.d
+mk/strdup.d: src/string/strdup.c
+ sh mk/deps.sh src/string/strdup.c
+
all: mk/strncpy.d
mk/strncpy.d: src/string/strncpy.c
sh mk/deps.sh src/string/strncpy.c
@@ -1914,7 +1926,7 @@ all: mk/__longjmp.x86-64.s.d
mk/__longjmp.x86-64.s.d: src/setjmp/__longjmp.x86-64.s
sh mk/deps.sh src/setjmp/__longjmp.x86-64.s
-all: mk/__setjmp.x86-64.s.d
-mk/__setjmp.x86-64.s.d: src/setjmp/__setjmp.x86-64.s
- sh mk/deps.sh src/setjmp/__setjmp.x86-64.s
+all: mk/___setjmp.x86-64.s.d
+mk/___setjmp.x86-64.s.d: src/setjmp/___setjmp.x86-64.s
+ sh mk/deps.sh src/setjmp/___setjmp.x86-64.s
diff --git a/mk/setjmp.d b/mk/setjmp.d
index 006a4c31..b696edbc 100644
--- a/mk/setjmp.d
+++ b/mk/setjmp.d
@@ -1,4 +1,4 @@
-libc_C.1: libc.a(setjmp.o)
+libc_C.0: libc.a(setjmp.o)
libc.a(setjmp.o): $(OBJDIR)/setjmp.o
@$(AR) $(ARFLAGS) $@ $(OBJDIR)/$%
diff --git a/src/setjmp/__setjmp.x86-64.s b/src/setjmp/___setjmp.x86-64.s
index 00b139b1..00b139b1 100644
--- a/src/setjmp/__setjmp.x86-64.s
+++ b/src/setjmp/___setjmp.x86-64.s
diff --git a/src/setjmp/__setjmp.c b/src/setjmp/__setjmp.c
new file mode 100644
index 00000000..cbd6a144
--- /dev/null
+++ b/src/setjmp/__setjmp.c
@@ -0,0 +1,41 @@
+#include <setjmp.h>
+#include <string.h>
+#include "_setjmp.h"
+#include "_safety.h"
+
+/** save program state **/
+
+int __setjmp(jmp_buf env)
+{
+ int ret = 0;
+ extern int ___setjmp(jmp_buf);
+ SIGNAL_SAFE(0);
+ memset(env, 0, sizeof(jmp_buf));
+ ret = ___setjmp(env);
+ ADD_JMP_BUF(env);
+ return ret;
+}
+
+CHECK_1(int, 0, __setjmp, jmp_buf)
+
+/***
+saves the current state of the calling environment
+in the TYPEDEF(jmp_buf) ARGUMENT(env).
+***/
+
+/*
+RETURN(0, the environment has been saved by THIS())
+RETURN(NONZERO, the environment has been restored by FUNCTION(longjmp))
+
+CONSTRAINT: entire controlling expression of a selection or iteration statement
+CONSTRAINT: one operand of a relational or equality operator which is the entire controlling expression of a selction or iteration statement
+CONSTRAINT: the operand of a unary ! as the entire controlling expression of a selection or iteration statement
+CONSTRAINT: an entire expression statement
+
+UNSPECIFIED(Whether THIS() is a macro or identifier with external linkage)
+
+UNDEFINED(A macro definition of THIS() is suppressed in order to access an actual function)
+UNDEFINED(A program defines an external identifier named LITERAL(setjmp))
+
+STDC(1)
+*/
diff --git a/src/setjmp/__setjmp_h.c b/src/setjmp/__setjmp_h.c
new file mode 100644
index 00000000..b4d0dcd6
--- /dev/null
+++ b/src/setjmp/__setjmp_h.c
@@ -0,0 +1,3 @@
+#include "_setjmp.h"
+
+struct __setjmp_h __setjmp_h;
diff --git a/src/setjmp/_setjmp.h b/src/setjmp/_setjmp.h
new file mode 100644
index 00000000..1bf19fe6
--- /dev/null
+++ b/src/setjmp/_setjmp.h
@@ -0,0 +1,58 @@
+#ifndef ___SETJMP_H__
+#define ___SETJMP_H__
+
+#include <setjmp.h>
+#include "_safety.h"
+
+struct __valid_jmp_buf {
+};
+
+extern struct __setjmp_h {
+ struct valid_jmp_buf {
+ unsigned long int *buf;
+ unsigned long int sum;
+ } *valid;
+ size_t nvalid;
+} __setjmp_h;
+
+
+#ifndef NDEBUG
+static inline unsigned long int jmp_sum(jmp_buf env)
+{
+ long unsigned int ret = 0;
+ for (size_t i = 0; i < sizeof(jmp_buf) / sizeof(unsigned long int); i++) {
+ ret ^= env[i];
+ }
+ return ret;
+}
+
+#define ADD_JMP_BUF(__env) do { \
+ struct valid_jmp_buf __v = { \
+ (unsigned long int *)(__env), \
+ jmp_sum(__env), \
+ }; \
+ ADD_PREV(__v, __setjmp_h.valid, __setjmp_h.nvalid); \
+} while (0)
+
+#define ASSERT_JMP_BUF(__env) do { \
+ int __found = 0; \
+ for (size_t __i = 0; __i < __setjmp_h.nvalid; __i++) { \
+ if (__setjmp_h.valid[__i].buf == (unsigned long int *)(__env)) { \
+ if (jmp_sum(__env) != __setjmp_h.valid[__i].sum) { \
+ UNDEFINED("jmp_buf has been modified!"); \
+ } \
+ __found = 1; \
+ break; \
+ } \
+ } \
+ if (!__found) { \
+ UNDEFINED("In call to longjmp(): Provided jmp_buf was not returned by a previous call to setjmp()"); \
+ } \
+} while (0)
+
+#else
+#define ADD_JMP_BUF(__env) (void)(__env)
+#define ASSERT_JMP_BUF(__env) (void)(__env)
+#endif
+
+#endif
diff --git a/src/setjmp/longjmp.c b/src/setjmp/longjmp.c
index 117910fc..2208aec7 100644
--- a/src/setjmp/longjmp.c
+++ b/src/setjmp/longjmp.c
@@ -1,4 +1,5 @@
#include <setjmp.h>
+#include "_setjmp.h"
#include "_safety.h"
/** restore calling environment **/
@@ -7,6 +8,7 @@ _Noreturn void longjmp(jmp_buf env, int val)
{
extern _Noreturn void ___longjmp(jmp_buf);
SIGNAL_SAFE(0);
+ ASSERT_JMP_BUF(env);
/* use val if nonzero, otherwise 1 */
env[0] = val ? val : 1;
diff --git a/src/setjmp/setjmp.c b/src/setjmp/setjmp.c
index 091f0993..3c8a199c 100644
--- a/src/setjmp/setjmp.c
+++ b/src/setjmp/setjmp.c
@@ -1,37 +1,16 @@
#include <setjmp.h>
-#include <string.h>
#include "_safety.h"
-/** save program state **/
+#undef setjmp
-int setjmp(jmp_buf env)
+int setjmp(jmp_buf jb)
{
- extern int ___setjmp(jmp_buf);
- SIGNAL_SAFE(0);
- memset(env, 0, sizeof(jmp_buf));
- return ___setjmp(env);
+ (void)jb;
+ UNDEFINED("The setjmp() macro has been suppressed to access an actual function");
+ return 0;
}
-CHECK_1(int, 0, setjmp, jmp_buf)
-
-/***
-saves the current state of the calling environment
-in the TYPEDEF(jmp_buf) ARGUMENT(env).
-***/
-
/*
-RETURN(0, the environment has been saved by THIS())
-RETURN(NONZERO, the environment has been restored by FUNCTION(longjmp))
-
-CONSTRAINT: entire controlling expression of a selection or iteration statement
-CONSTRAINT: one operand of a relational or equality operator which is the entire controlling expression of a selction or iteration statement
-CONSTRAINT: the operand of a unary ! as the entire controlling expression of a selection or iteration statement
-CONSTRAINT: an entire expression statement
-
-UNSPECIFIED(Whether THIS() is a macro or identifier with external linkage)
-
-UNDEFINED(A macro definition of THIS() is suppressed in order to access an actual function)
-UNDEFINED(A program defines an external identifier named LITERAL(setjmp))
-
-STDC(1)
+SIGNAL_SAFE(0)
+STDC(0)
*/