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-next>] [day] [month] [year] [list]
Date: Wed, 15 May 2024 12:48:04 +0200
From: Borislav Petkov <bp@...nel.org>
To: X86 ML <x86@...nel.org>
Cc: LKML <linux-kernel@...r.kernel.org>,
	"Borislav Petkov (AMD)" <bp@...en8.de>
Subject: [PATCH] x86/alternative: Use the correct length when optimizing NOPs

From: "Borislav Petkov (AMD)" <bp@...en8.de>

Commit in Fixes moved the optimize_nops() call inside apply_relocation()
and made it a second optimization pass after the relocations have been
done.

Since optimize_nops() works only on NOPs, that is fine and it'll simply
jump over instructions which are not NOPs.

However, it made that call with repl_len as the buffer length to
optimize.

However, it can happen that there are alternatives calls like this one:

  alternative("mfence; lfence", "", ALT_NOT(X86_FEATURE_APIC_MSRS_FENCE));

where the replacement length is 0. And using repl_len is wrong because
apply_alternatives() expands the buffer size to the length of the source
insn that is being patched, by padding it with one-byte NOPs:

	for (; insn_buff_sz < a->instrlen; insn_buff_sz++)
		insn_buff[insn_buff_sz] = 0x90;

Long story short: pass the length of the original instruction(s) as the
length of the temporary buffer which to optimize.

Result:

  SMP alternatives: feat: 11*32+27, old: (lapic_next_deadline+0x9/0x50 (ffffffff81061829) len: 6), repl: (ffffffff89b1cc60, len: 0) flags: 0x1
  SMP alternatives: ffffffff81061829:   old_insn: 0f ae f0 0f ae e8
  SMP alternatives: ffffffff81061829: final_insn: 90 90 90 90 90 90

=>

  SMP alternatives: feat: 11*32+27, old: (lapic_next_deadline+0x9/0x50 (ffffffff81061839) len: 6), repl: (ffffffff89b1cc60, len: 0) flags: 0x1
  SMP alternatives: ffffffff81061839: [0:6) optimized NOPs: 66 0f 1f 44 00 00
  SMP alternatives: ffffffff81061839:   old_insn: 0f ae f0 0f ae e8
  SMP alternatives: ffffffff81061839: final_insn: 66 0f 1f 44 00 00

Fixes: da8f9cf7e721 ("x86/alternatives: Get rid of __optimize_nops()")
Signed-off-by: Borislav Petkov (AMD) <bp@...en8.de>
---
 arch/x86/kernel/alternative.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 7555c15b7183..89de61243272 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -372,7 +372,7 @@ static void __apply_relocation(u8 *buf, const u8 * const instr, size_t instrlen,
 void apply_relocation(u8 *buf, const u8 * const instr, size_t instrlen, u8 *repl, size_t repl_len)
 {
 	__apply_relocation(buf, instr, instrlen, repl, repl_len);
-	optimize_nops(instr, buf, repl_len);
+	optimize_nops(instr, buf, instrlen);
 }
 
 /* Low-level backend functions usable from alternative code replacements. */
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ