mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Julien Thierry <jthierry@redhat.com>
To: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: linux-kernel@vger.kernel.org, peterz@infradead.org,
	mbenes@suse.cz, raphael.gault@arm.com, benh@kernel.crashing.org
Subject: Re: [PATCH 1/3] objtool: check: Fully validate the stack frame
Date: Mon, 21 Sep 2020 11:31:23 +0100	[thread overview]
Message-ID: <9a40f898-8f6a-2ba0-1954-0d06be5e2ef8@redhat.com> (raw)
In-Reply-To: <20200918205641.6nvnsib2paqa6xyn@treble>



On 9/18/20 9:56 PM, Josh Poimboeuf wrote:
> On Tue, Sep 15, 2020 at 09:12:02AM +0100, Julien Thierry wrote:
>> 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 value on the stack.
> 
> s/return value/return address/g
> 
>>
>> Add the necessary checks to verify a function properly sets up the all
> 
> s/the all/all the/
> 
>> the elements of the stack frame.
>>
>> Signed-off-by: Julien Thierry <jthierry@redhat.com>
>> ---
>>   tools/objtool/arch/x86/include/cfi_regs.h |  4 ++++
>>   tools/objtool/check.c                     | 17 +++++++++++++----
>>   2 files changed, 17 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..19b75b8b8439 100644
>> --- a/tools/objtool/arch/x86/include/cfi_regs.h
>> +++ b/tools/objtool/arch/x86/include/cfi_regs.h
>> @@ -22,4 +22,8 @@
>>   #define CFI_RA			16
>>   #define CFI_NUM_REGS		17
>>   
>> +#define CFA_SIZE	16
> 
> If I remember correctly, CFA (stolen from DWARF) is "Caller Frame
> Address".  It's the stack address of the caller, before the call.
> 

Ok, so maybe I'm mixing Call Frame and Stack Frame (frame pointer + 
return address).

> I get the feeling CFA_SIZE is the wrong name, because CFA is an address,
> and its size isn't 16 bytes.  But I'm not quite sure what this is
> supposed to represent.  Is it supposed to be the size of the frame
> pointer + return address?  Isn't that always going to be 16 bytes for
> both arches?
> 

For arm64 and x86_64 it is. Maybe it is a bit early to consider it might 
differ for other arches (e.g. 32bit arches?).

>> +#define CFA_BP_OFFSET	-16
>> +#define CFA_RA_OFFSET	-8
>> +
>>   #endif /* _OBJTOOL_CFI_REGS_H */
>> diff --git a/tools/objtool/check.c b/tools/objtool/check.c
>> index 500f63b3dcff..7db6761d28c2 100644
>> --- a/tools/objtool/check.c
>> +++ b/tools/objtool/check.c
>> @@ -1669,12 +1669,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 cfa_start,
>> +				int expected_offset)
>> +{
>> +	return reg->base == CFI_CFA &&
>> +	       reg->offset == cfa_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 >= CFA_SIZE &&
> 
> Why '>=' rather than '=='?
> 

Because on arm64 the stack frame is not necessarily the first thing put 
on the stack by the callee. The callee is free to create the stack frame 
where it wants (on its part of the stack of course) as long as it 
appropriately sets the frame pointer before making a call.

You could have something like:

+------------+
|            |
|            |
+------------+----> f1() called
|            |
| some callee|
| saved regs |
|            |
+------------+
|     RA     |
+------------+
|     BP/FP  |
+------------+----> Set new BP/FP value


>> +	    check_reg_frame_pos(&cfi->regs[CFI_BP], -cfi->cfa.offset + CFA_SIZE, CFA_BP_OFFSET) &&
>> +	    check_reg_frame_pos(&cfi->regs[CFI_RA], -cfi->cfa.offset + CFA_SIZE, CFA_RA_OFFSET))
> 
> Isn't '-cfi->cfa.offset + CFA_SIZE' always going to be zero?
> 

For x86 yes, for arm64 it cfa.offset can be > 16.

-- 
Julien Thierry


  reply	other threads:[~2020-09-21 10:31 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-15  8:12 [PATCH 0/3] objtool: Extend CFA updating/checking Julien Thierry
2020-09-15  8:12 ` [PATCH 1/3] objtool: check: Fully validate the stack frame Julien Thierry
2020-09-18 20:56   ` Josh Poimboeuf
2020-09-21 10:31     ` Julien Thierry [this message]
2020-09-21 15:03       ` Josh Poimboeuf
2020-09-15  8:12 ` [PATCH 2/3] objtool: check: Support addition to set CFA base Julien Thierry
2020-09-18 21:09   ` Josh Poimboeuf
2020-09-15  8:12 ` [PATCH 3/3] objtool: check: Make SP memory operation match PUSH/POP semantics Julien Thierry
2020-09-18 21:43   ` Josh Poimboeuf
2020-09-21 10:31     ` Julien Thierry
2020-09-21 15:12       ` Josh Poimboeuf

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=9a40f898-8f6a-2ba0-1954-0d06be5e2ef8@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®