From: Ard Biesheuvel <ardb+git@google.com>
To: linux-arm-kernel@lists.infradead.org
Cc: catalin.marinas@arm.com, will@kernel.org, mark.rutland@arm.com,
Ard Biesheuvel <ardb@kernel.org>,
Sami Tolvanen <samitolvanen@google.com>,
Kees Cook <kees@kernel.org>,
Nathan Chancellor <nathan@kernel.org>
Subject: [PATCH 2/3] arm64/scs: Deal with 64-bit relative offsets in FDE frames
Date: Wed, 6 Nov 2024 19:55:16 +0100 [thread overview]
Message-ID: <20241106185513.3096442-7-ardb+git@google.com> (raw)
In-Reply-To: <20241106185513.3096442-5-ardb+git@google.com>
From: Ard Biesheuvel <ardb@kernel.org>
In some cases, the compiler may decide to emit DWARF FDE frames with
64-bit signed fields for the code offset and range fields. This may
happen when using the large code model, for instance, which permits
an executable to be spread out over more than 4 GiB of address space.
Whether this is the case can be inferred from the augmentation data in
the CIE frame, so decode this data before processing the FDE frames.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/kernel/pi/patch-scs.c | 34 ++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/pi/patch-scs.c b/arch/arm64/kernel/pi/patch-scs.c
index cec8f0a52bbc..55d0cd64ef71 100644
--- a/arch/arm64/kernel/pi/patch-scs.c
+++ b/arch/arm64/kernel/pi/patch-scs.c
@@ -50,6 +50,10 @@ bool dynamic_scs_is_enabled;
#define DW_CFA_GNU_negative_offset_extended 0x2f
#define DW_CFA_hi_user 0x3f
+#define DW_EH_PE_sdata4 0x0b
+#define DW_EH_PE_sdata8 0x0c
+#define DW_EH_PE_pcrel 0x10
+
enum {
PACIASP = 0xd503233f,
AUTIASP = 0xd50323bf,
@@ -125,6 +129,7 @@ struct eh_frame {
u8 data_alignment_factor;
u8 return_address_register;
u8 augmentation_data_size;
+ u8 fde_pointer_format;
};
struct { // FDE
@@ -132,11 +137,18 @@ struct eh_frame {
s32 range;
u8 opcodes[];
};
+
+ struct { // FDE
+ s64 initial_loc64;
+ s64 range64;
+ u8 opcodes64[];
+ };
};
};
static int scs_handle_fde_frame(const struct eh_frame *frame,
int code_alignment_factor,
+ bool use_sdata8,
bool dry_run)
{
int size = frame->size - offsetof(struct eh_frame, opcodes) + 4;
@@ -144,6 +156,12 @@ static int scs_handle_fde_frame(const struct eh_frame *frame,
const u8 *opcode = frame->opcodes;
int l;
+ if (use_sdata8) {
+ loc = (u64)&frame->initial_loc64 + frame->initial_loc64;
+ opcode = frame->opcodes64;
+ size -= 8;
+ }
+
// assume single byte uleb128_t for augmentation data size
if (*opcode & BIT(7))
return EDYNSCS_INVALID_FDE_AUGM_DATA_SIZE;
@@ -210,6 +228,7 @@ static int scs_handle_fde_frame(const struct eh_frame *frame,
int scs_patch(const u8 eh_frame[], int size)
{
int code_alignment_factor = 1;
+ bool fde_use_sdata8 = false;
const u8 *p = eh_frame;
while (size > 4) {
@@ -245,13 +264,24 @@ int scs_patch(const u8 eh_frame[], int size)
return EDYNSCS_INVALID_CIE_HEADER;
code_alignment_factor = frame->code_alignment_factor;
+
+ switch (frame->fde_pointer_format) {
+ case DW_EH_PE_pcrel | DW_EH_PE_sdata4:
+ fde_use_sdata8 = false;
+ break;
+ case DW_EH_PE_pcrel | DW_EH_PE_sdata8:
+ fde_use_sdata8 = true;
+ break;
+ default:
+ return EDYNSCS_INVALID_CIE_SDATA_SIZE;
+ }
} else {
ret = scs_handle_fde_frame(frame, code_alignment_factor,
- true);
+ fde_use_sdata8, true);
if (ret)
return ret;
scs_handle_fde_frame(frame, code_alignment_factor,
- false);
+ fde_use_sdata8, false);
}
p += sizeof(frame->size) + frame->size;
--
2.47.0.277.g8800431eea-goog
next prev parent reply other threads:[~2024-11-06 19:01 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-06 18:55 [PATCH 0/3] arm64: Dynamic shadow call stack fixes Ard Biesheuvel
2024-11-06 18:55 ` [PATCH 1/3] arm64/scs: Fix handling of DWARF augmentation data in CIE/FDE frames Ard Biesheuvel
2024-11-06 22:13 ` Sami Tolvanen
2024-11-08 14:14 ` Ard Biesheuvel
2024-11-06 18:55 ` Ard Biesheuvel [this message]
2024-11-06 18:55 ` [PATCH 3/3] arm64/scs: Drop unused prototype __pi_scs_patch_vmlinux() Ard Biesheuvel
2024-11-06 22:13 ` [PATCH 0/3] arm64: Dynamic shadow call stack fixes Sami Tolvanen
2024-11-08 16:50 ` Catalin Marinas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241106185513.3096442-7-ardb+git@google.com \
--to=ardb+git@google.com \
--cc=ardb@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=kees@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=mark.rutland@arm.com \
--cc=nathan@kernel.org \
--cc=samitolvanen@google.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).