aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-10-19 15:25:12 +0200
committerMartin Liska <mliska@suse.cz>2022-10-19 15:25:12 +0200
commit4465e2a047c3b175bf6c4ca500547eb6b12df52f (patch)
tree3159c8256f9907538f186ce7c1087c83825b5519 /libgcc
parent6c22519f33270a689fc8730ceff9212b376ed40d (diff)
parent09fed44cabd50f3d8e050f91cc2db02364ce9176 (diff)
downloadgcc-4465e2a047c3b175bf6c4ca500547eb6b12df52f.zip
gcc-4465e2a047c3b175bf6c4ca500547eb6b12df52f.tar.gz
gcc-4465e2a047c3b175bf6c4ca500547eb6b12df52f.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog21
-rw-r--r--libgcc/Makefile.in2
-rw-r--r--libgcc/config/i386/shadow-stack-unwind.h51
-rw-r--r--libgcc/unwind-dw2.h11
-rw-r--r--libgcc/unwind-generic.h2
-rw-r--r--libgcc/unwind.inc4
6 files changed, 78 insertions, 13 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index f756eb5..ea4997d 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,24 @@
+2022-10-18 Jonathan Wakely <jwakely@redhat.com>
+
+ * Makefile.in: Quote variable.
+
+2022-10-17 H.J. Lu <hjl.tools@gmail.com>
+
+ * unwind-generic.h (_Unwind_Frames_Increment): Add the EXC
+ argument.
+ * unwind.inc (_Unwind_RaiseException_Phase2): Pass EXC to
+ _Unwind_Frames_Increment.
+ (_Unwind_ForcedUnwind_Phase2): Likewise.
+ * config/i386/shadow-stack-unwind.h (_Unwind_Frames_Increment):
+ Take the EXC argument. Return _URC_FATAL_PHASE2_ERROR if the
+ return address on normal stack doesn't match the return address
+ on shadow stack.
+
+2022-10-17 Florian Weimer <fweimer@redhat.com>
+
+ * unwind-dw2.h (struct frame_state_reg_info): Move cfa_how member
+ and reduce its size.
+
2022-10-14 Jakub Jelinek <jakub@redhat.com>
* config/i386/t-softfp (softfp_extensions): Add bfsf.
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 1fe708a..6e2a0470 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -310,7 +310,7 @@ CRTSTUFF_T_CFLAGS =
MULTIDIR := $(shell $(CC) $(CFLAGS) -print-multi-directory)
MULTIOSDIR := $(shell $(CC) $(CFLAGS) -print-multi-os-directory)
-MULTIOSSUBDIR := $(shell if test $(MULTIOSDIR) != .; then echo /$(MULTIOSDIR); fi)
+MULTIOSSUBDIR := $(shell if test "$(MULTIOSDIR)" != .; then echo /$(MULTIOSDIR); fi)
inst_libdir = $(libsubdir)$(MULTISUBDIR)
inst_slibdir = $(slibdir)$(MULTIOSSUBDIR)
diff --git a/libgcc/config/i386/shadow-stack-unwind.h b/libgcc/config/i386/shadow-stack-unwind.h
index 2b02682..89d4416 100644
--- a/libgcc/config/i386/shadow-stack-unwind.h
+++ b/libgcc/config/i386/shadow-stack-unwind.h
@@ -54,10 +54,39 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
aligned. If the original shadow stack is 8 byte aligned, we just
need to pop 2 slots, one restore token, from shadow stack. Otherwise,
we need to pop 3 slots, one restore token + 4 byte padding, from
- shadow stack. */
-#ifndef __x86_64__
+ shadow stack.
+
+ When popping a stack frame, we compare the return address on normal
+ stack against the return address on shadow stack. If they don't match,
+ return _URC_FATAL_PHASE2_ERROR for the corrupted return address on
+ normal stack. Don't check the return address for
+ 1. Non-catchable exception where exception_class == 0. Process will
+ be terminated.
+ 2. Zero return address which marks the outermost stack frame.
+ 3. Signal stack frame since kernel puts a restore token on shadow
+ stack.
+ */
#undef _Unwind_Frames_Increment
-#define _Unwind_Frames_Increment(context, frames) \
+#ifdef __x86_64__
+#define _Unwind_Frames_Increment(exc, context, frames) \
+ { \
+ frames++; \
+ if (exc->exception_class != 0 \
+ && _Unwind_GetIP (context) != 0 \
+ && !_Unwind_IsSignalFrame (context)) \
+ { \
+ _Unwind_Word ssp = _get_ssp (); \
+ if (ssp != 0) \
+ { \
+ ssp += 8 * frames; \
+ _Unwind_Word ra = *(_Unwind_Word *) ssp; \
+ if (ra != _Unwind_GetIP (context)) \
+ return _URC_FATAL_PHASE2_ERROR; \
+ } \
+ } \
+ }
+#else
+#define _Unwind_Frames_Increment(exc, context, frames) \
if (_Unwind_IsSignalFrame (context)) \
do \
{ \
@@ -83,5 +112,19 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
} \
while (0); \
else \
- frames++;
+ { \
+ frames++; \
+ if (exc->exception_class != 0 \
+ && _Unwind_GetIP (context) != 0) \
+ { \
+ _Unwind_Word ssp = _get_ssp (); \
+ if (ssp != 0) \
+ { \
+ ssp += 4 * frames; \
+ _Unwind_Word ra = *(_Unwind_Word *) ssp; \
+ if (ra != _Unwind_GetIP (context)) \
+ return _URC_FATAL_PHASE2_ERROR; \
+ } \
+ } \
+ }
#endif
diff --git a/libgcc/unwind-dw2.h b/libgcc/unwind-dw2.h
index af34e00..a0834b1 100644
--- a/libgcc/unwind-dw2.h
+++ b/libgcc/unwind-dw2.h
@@ -50,6 +50,12 @@ typedef struct
} reg[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
unsigned char how[__LIBGCC_DWARF_FRAME_REGISTERS__+1];
+ enum {
+ CFA_UNSET,
+ CFA_REG_OFFSET,
+ CFA_EXP
+ } cfa_how : 8;
+
/* Used to implement DW_CFA_remember_state. */
struct frame_state_reg_info *prev;
@@ -58,11 +64,6 @@ typedef struct
_Unwind_Sword cfa_offset;
_Unwind_Word cfa_reg;
const unsigned char *cfa_exp;
- enum {
- CFA_UNSET,
- CFA_REG_OFFSET,
- CFA_EXP
- } cfa_how;
} regs;
/* The PC described by the current frame state. */
diff --git a/libgcc/unwind-generic.h b/libgcc/unwind-generic.h
index a87c9b3..bf72128 100644
--- a/libgcc/unwind-generic.h
+++ b/libgcc/unwind-generic.h
@@ -292,6 +292,6 @@ EXCEPTION_DISPOSITION _GCC_specific_handler (PEXCEPTION_RECORD, void *,
#define _Unwind_Frames_Extra(frames)
/* Increment frame count. */
-#define _Unwind_Frames_Increment(context, frames) frames++
+#define _Unwind_Frames_Increment(exc, context, frames) frames++
#endif /* unwind.h */
diff --git a/libgcc/unwind.inc b/libgcc/unwind.inc
index 5efd8af..a7111a7 100644
--- a/libgcc/unwind.inc
+++ b/libgcc/unwind.inc
@@ -73,7 +73,7 @@ _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
gcc_assert (!match_handler);
uw_update_context (context, &fs);
- _Unwind_Frames_Increment (context, frames);
+ _Unwind_Frames_Increment (exc, context, frames);
}
*frames_p = frames;
@@ -191,7 +191,7 @@ _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
/* Update cur_context to describe the same frame as fs, and discard
the previous context if necessary. */
uw_advance_context (context, &fs);
- _Unwind_Frames_Increment (context, frames);
+ _Unwind_Frames_Increment (exc, context, frames);
}
*frames_p = frames;