Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp2882506pxk; Mon, 28 Sep 2020 02:38:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy+KGNq1IJ71+LqaMPonmTrHQlMgzzgn9lUhmcMCJpBP/vZsFYiYCAR1JnW9LQRNQWekJIl X-Received: by 2002:a17:906:9a1:: with SMTP id q1mr776070eje.30.1601285935415; Mon, 28 Sep 2020 02:38:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1601285935; cv=none; d=google.com; s=arc-20160816; b=pZ4JW4/TlHqD+vogQqS/PwkZxyQr+S3rvjtwIlLnJz/5qgiZbosWqqvkaJuL9jwKRa H7yL9dNRgBMMdWKLeL5RPtGXIJTYcZo/XYKmkH8Q8ueg6fzAVLP6afgOH0kVS0DFPQ9q 82YY7f9i4GV6B5qYZyvd+re1x7T0ukJ7jJK8F9mfNBgqON4Q4BqcuAG2ZV70LgdK6iBM vyrmhZdz0LbWG2796TGp8h+1nU29ZAb1Py30huSdP+fpB/wg3/twzbpAauNDP92j18mx sQtqGrAluBEyJHBhHbPYqGWN73Tyv+T37lcANmPgBoYIY77JUD6teoAyYJjtCTen2Lek rawQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=J6b7rvUA+1w7iqW8kEtLXFQVs31ukjeHiFKqzkhFxhE=; b=FUCV6PdRaDgemYwpGAAPiY8fze9bQEiRpWXb5VoFqUc3PK2pufRN2AB+BEUx1i70eW gY3mP7ROOYe6ChD2A857BVE2ySFI3/D3Q7m2FyPHqMdUtt/LPgzwLemGey2uv5lj4Mrx XxRF0kIXKtxpQ/FyEy86FE1pyqexsFdaqxqOj7MhVspvu0Ma+6btmzlZ9LtlVbnJ7X2s 5sAjkOwAjwcadjVlXJE0Ysbk1VITaBvp/GqS7rQ2aYxxRm/+PWo7T9P2YELQIDV14uf7 j5yeS/3kSiBZUQ6dVKje3NFF843GYdnEW8C8wvxFK8G0ooTc3sCobKSOgPVCycjViyz6 WXgg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="JIace/mu"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u10si274488ejy.154.2020.09.28.02.38.32; Mon, 28 Sep 2020 02:38:55 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="JIace/mu"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726613AbgI1Jgt (ORCPT + 99 others); Mon, 28 Sep 2020 05:36:49 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:31191 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726380AbgI1Jgr (ORCPT ); Mon, 28 Sep 2020 05:36:47 -0400 Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1601285805; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=J6b7rvUA+1w7iqW8kEtLXFQVs31ukjeHiFKqzkhFxhE=; b=JIace/mud8tRG/NUptCtv+NfgutbM09wgYdJl3IH5wB2fJoD8xiZu+edFDZ49F4usoEN68 vHfaK+TT6/ynWK63sZHwLbB+psVpDymXITf5220YElAivDiTnYGpyziJIY1z7v9MCEX+6J FVD+fqTkCLnJdETmrDE5TdqlrFF6uE4= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-121-MixSBHRnPheygZPmIjZqvg-1; Mon, 28 Sep 2020 05:36:41 -0400 X-MC-Unique: MixSBHRnPheygZPmIjZqvg-1 Received: by mail-wr1-f71.google.com with SMTP id s8so167329wrb.15 for ; Mon, 28 Sep 2020 02:36:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=J6b7rvUA+1w7iqW8kEtLXFQVs31ukjeHiFKqzkhFxhE=; b=PB0JWwU77xga26GWLIzrdJArWTU8QI5+iIaxSeFI01rElYJ1HmwzLmbbQCpNBzs34z 1ki2ZoqGzCu8MjhtD/dP0N2ef372MeA0L6WGJNhHxRGd2uTHR6xQ2D65TObnpXKsPMVu +t3YMXSa9Kd1FeBE5Tryk5JfKxvmbduFHB6/cyQ5DBnkBJJYbbWQVTOr9h5ZTR6irwag GAZssDGUnGoQe0sKQFUTu0xlVDKcNNLj/6vgItQV2o24aFJ95W0NzIb3RTSHEXIAXC9S /lk5a49BeD6AHAaoL703vKRMUVEkiQYTbS94LfWMKSdKBiwtzavVYCBGl7bdA3J/8SXw CFyA== X-Gm-Message-State: AOAM530jSZyZHE85Sggdal1c38Qd3cf8s5guTV7147nY9T0cTuuD/3+K 1hgZQluhSn2HgPMK47mhQ71ido9qr4M7lkDzxspmaNjooQboxQinFy8/A8Efiomg02Y4PZKRRbH h0VPheJcM9fxxkfKIOtAjGrGJ X-Received: by 2002:a5d:574c:: with SMTP id q12mr651044wrw.253.1601285800317; Mon, 28 Sep 2020 02:36:40 -0700 (PDT) X-Received: by 2002:a5d:574c:: with SMTP id q12mr651029wrw.253.1601285800173; Mon, 28 Sep 2020 02:36:40 -0700 (PDT) Received: from redfedo.redhat.com ([2a01:cb14:499:3d00:cd47:f651:9d80:157a]) by smtp.gmail.com with ESMTPSA id y207sm495967wmc.17.2020.09.28.02.36.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Sep 2020 02:36:39 -0700 (PDT) From: Julien Thierry 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 Subject: [PATCH v2 1/3] objtool: check: Fully validate the stack frame Date: Mon, 28 Sep 2020 10:36:29 +0100 Message-Id: <20200928093631.210610-2-jthierry@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20200928093631.210610-1-jthierry@redhat.com> References: <20200928093631.210610-1-jthierry@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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