Skip to content

Commit

Permalink
objtool: Fully validate the stack frame
Browse files Browse the repository at this point in the history
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 needs 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>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
  • Loading branch information
Julien Thierry authored and Josh Poimboeuf committed Jan 14, 2021
1 parent 7c53f6b commit fb084fd
Showing 1 changed file with 11 additions and 4 deletions.
15 changes: 11 additions & 4 deletions tools/objtool/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -1733,12 +1733,20 @@ 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 expected_offset)
{
return reg->base == CFI_CFA &&
reg->offset == 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 &&
check_reg_frame_pos(&cfi->regs[CFI_BP], -cfi->cfa.offset) &&
check_reg_frame_pos(&cfi->regs[CFI_RA], -cfi->cfa.offset + 8))
return true;

if (cfi->drap && cfi->regs[CFI_BP].base == CFI_BP)
Expand Down Expand Up @@ -1867,8 +1875,7 @@ 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(&regs[CFI_BP], -cfa->offset)) {

/* mov %rsp, %rbp */
cfa->base = op->dest.reg;
Expand Down

0 comments on commit fb084fd

Please sign in to comment.