lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 18 Sep 2020 15:56:41 -0500
From:   Josh Poimboeuf <jpoimboe@...hat.com>
To:     Julien Thierry <jthierry@...hat.com>
Cc:     linux-kernel@...r.kernel.org, peterz@...radead.org, mbenes@...e.cz,
        raphael.gault@....com, benh@...nel.crashing.org
Subject: Re: [PATCH 1/3] objtool: check: Fully validate the stack frame

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@...hat.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.

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?

> +#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 '=='?

> +	    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?

-- 
Josh

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ