From: Julien Thierry <jthierry@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: jpoimboe@redhat.com, peterz@infradead.org, mbenes@suse.cz,
raphael.gault@arm.com, benh@kernel.crashing.org,
Julien Thierry <jthierry@redhat.com>
Subject: [PATCH v2 1/3] objtool: check: Fully validate the stack frame
Date: Mon, 28 Sep 2020 10:36:29 +0100 [thread overview]
Message-ID: <20200928093631.210610-2-jthierry@redhat.com> (raw)
In-Reply-To: <20200928093631.210610-1-jthierry@redhat.com>
A valid stack frame should contain both the return address and the
previous frame pointer value.
On x86, the return value is placed on the stack by the calling
instructions. On other architectures, the callee need to explicitly
save the return address on the stack.
Add the necessary checks to verify a function properly sets up all the
elements of the stack frame.
Signed-off-by: Julien Thierry <jthierry@redhat.com>
---
tools/objtool/arch/x86/include/cfi_regs.h | 3 +++
tools/objtool/cfi.h | 2 ++
tools/objtool/check.c | 21 +++++++++++++++++----
3 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/tools/objtool/arch/x86/include/cfi_regs.h b/tools/objtool/arch/x86/include/cfi_regs.h
index 79bc517efba8..4e443b49d0d3 100644
--- a/tools/objtool/arch/x86/include/cfi_regs.h
+++ b/tools/objtool/arch/x86/include/cfi_regs.h
@@ -22,4 +22,7 @@
#define CFI_RA 16
#define CFI_NUM_REGS 17
+#define STACKFRAME_BP_OFFSET -16
+#define STACKFRAME_RA_OFFSET -8
+
#endif /* _OBJTOOL_CFI_REGS_H */
diff --git a/tools/objtool/cfi.h b/tools/objtool/cfi.h
index c7c59c6a44ee..2691b6ce4fcd 100644
--- a/tools/objtool/cfi.h
+++ b/tools/objtool/cfi.h
@@ -35,4 +35,6 @@ struct cfi_state {
bool end;
};
+#define STACKFRAME_SIZE 16
+
#endif /* _OBJTOOL_CFI_H */
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 2df9f769412e..50b3a4504db1 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1668,12 +1668,24 @@ static bool has_modified_stack_frame(struct instruction *insn, struct insn_state
return false;
}
+static bool check_reg_frame_pos(const struct cfi_reg *reg, int stackframe_start,
+ int expected_offset)
+{
+ return reg->base == CFI_CFA &&
+ reg->offset == stackframe_start + expected_offset;
+}
+
static bool has_valid_stack_frame(struct insn_state *state)
{
struct cfi_state *cfi = &state->cfi;
- if (cfi->cfa.base == CFI_BP && cfi->regs[CFI_BP].base == CFI_CFA &&
- cfi->regs[CFI_BP].offset == -16)
+ if (cfi->cfa.base == CFI_BP && cfi->cfa.offset >= STACKFRAME_SIZE &&
+ check_reg_frame_pos(&cfi->regs[CFI_BP],
+ -cfi->cfa.offset + STACKFRAME_SIZE,
+ STACKFRAME_BP_OFFSET) &&
+ check_reg_frame_pos(&cfi->regs[CFI_RA],
+ -cfi->cfa.offset + STACKFRAME_SIZE,
+ STACKFRAME_RA_OFFSET))
return true;
if (cfi->drap && cfi->regs[CFI_BP].base == CFI_BP)
@@ -1802,8 +1814,9 @@ static int update_cfi_state(struct instruction *insn, struct cfi_state *cfi,
case OP_SRC_REG:
if (op->src.reg == CFI_SP && op->dest.reg == CFI_BP &&
cfa->base == CFI_SP &&
- regs[CFI_BP].base == CFI_CFA &&
- regs[CFI_BP].offset == -cfa->offset) {
+ check_reg_frame_pos(®s[CFI_BP],
+ -cfa->offset + STACKFRAME_SIZE,
+ STACKFRAME_BP_OFFSET)) {
/* mov %rsp, %rbp */
cfa->base = op->dest.reg;
--
2.25.4
next prev parent reply other threads:[~2020-09-28 9:36 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-28 9:36 [PATCH v2 0/3] objtool: Extend CFA updating/checking Julien Thierry
2020-09-28 9:36 ` Julien Thierry [this message]
2020-09-29 19:18 ` [PATCH v2 1/3] objtool: check: Fully validate the stack frame Josh Poimboeuf
2020-10-12 10:21 ` Julien Thierry
2020-10-12 15:35 ` Josh Poimboeuf
2020-10-13 12:12 ` Julien Thierry
2020-09-28 9:36 ` [PATCH v2 2/3] objtool: check: Support addition to set CFA base Julien Thierry
2020-09-28 9:36 ` [PATCH v2 3/3] objtool: check: Make SP memory operation match PUSH/POP semantics Julien Thierry
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=20200928093631.210610-2-jthierry@redhat.com \
--to=jthierry@redhat.com \
--cc=benh@kernel.crashing.org \
--cc=jpoimboe@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mbenes@suse.cz \
--cc=peterz@infradead.org \
--cc=raphael.gault@arm.com \
/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
all inboxes | Powered by JetHome®