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:   Wed, 03 Feb 2021 13:02:25 +0100
From:   Peter Zijlstra <peterz@...radead.org>
To:     Josh Poimboeuf <jpoimboe@...hat.com>,
        Thomas Gleixner <tglx@...utronix.de>
Cc:     Miroslav Benes <mbenes@...e.cz>,
        Nick Desaulniers <ndesaulniers@...gle.com>,
        Julien Thierry <jthierry@...hat.com>,
        Kees Cook <keescook@...omium.org>, x86@...nel.org,
        linux-kernel@...r.kernel.org, peterz@...radead.org
Subject: [PATCH 3/5] objtool: Prepare for scratch regs

Introduce __save_reg() which allows using the
!arch_callee_saved_reg()s and make sure they're wiped after every
stack op so they don't linger, allow for a single op exception so they
can be used on the very next stack-op.

Signed-off-by: Peter Zijlstra (Intel) <peterz@...radead.org>
---
 tools/objtool/check.c |   27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1775,15 +1775,20 @@ static int update_cfi_state_regs(struct
 	return 0;
 }
 
-static void save_reg(struct cfi_state *cfi, unsigned char reg, int base, int offset)
+static void __save_reg(struct cfi_state *cfi, unsigned char reg, int base, int offset)
 {
-	if (arch_callee_saved_reg(reg) &&
-	    cfi->regs[reg].base == CFI_UNDEFINED) {
+	if (cfi->regs[reg].base == CFI_UNDEFINED) {
 		cfi->regs[reg].base = base;
 		cfi->regs[reg].offset = offset;
 	}
 }
 
+static void save_reg(struct cfi_state *cfi, unsigned char reg, int base, int offset)
+{
+	if (arch_callee_saved_reg(reg))
+		__save_reg(cfi, reg, base, offset);
+}
+
 static void restore_reg(struct cfi_state *cfi, unsigned char reg)
 {
 	cfi->regs[reg].base = initial_func_cfi.regs[reg].base;
@@ -1848,6 +1853,7 @@ static int update_cfi_state(struct instr
 {
 	struct cfi_reg *cfa = &cfi->cfa;
 	struct cfi_reg *regs = cfi->regs;
+	bool skip_wipe = false;
 
 	/* stack operations don't make sense with an undefined CFA */
 	if (cfa->base == CFI_UNDEFINED) {
@@ -2192,6 +2198,21 @@ static int update_cfi_state(struct instr
 		return -1;
 	}
 
+	/*
+	 * Only callee saved registers are preserved; the rest is scratch space
+	 * preserved at most one instruction.
+	 */
+	if (!skip_wipe) {
+		int i;
+
+		for (i = 0; i < CFI_NUM_REGS; i++) {
+			if (arch_callee_saved_reg(i))
+				continue;
+
+			restore_reg(cfi, i);
+		}
+	}
+
 	return 0;
 }
 


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ