From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S967462AbdEXODP (ORCPT ); Wed, 24 May 2017 10:03:15 -0400 Received: from mx2.suse.de ([195.135.220.15]:36831 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S967460AbdEXODD (ORCPT ); Wed, 24 May 2017 10:03:03 -0400 Date: Wed, 24 May 2017 16:02:55 +0200 From: Borislav Petkov To: Mateusz Jurczyk Cc: Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Andy Lutomirski , x86@kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v2] x86: Prevent uninitialized stack byte read in apply_alternatives() Message-ID: <20170524140254.GE7275@nazgul.tnic> References: <20170524130418.GB7275@nazgul.tnic> <20170524135500.27223-1-mjurczyk@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20170524135500.27223-1-mjurczyk@google.com> User-Agent: Mutt/1.6.0 (2016-04-01) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, May 24, 2017 at 03:55:00PM +0200, Mateusz Jurczyk wrote: > In the current form of the code, if a->replacementlen is 0, the reference > to *insnbuf for comparison touches potentially garbage memory. While it > doesn't affect the execution flow due to the subsequent a->replacementlen > comparison, it is (rightly) detected as use of uninitialized memory by a > runtime instrumentation currently under my development, and could be > detected as such by other tools in the future, too (e.g. KMSAN). > > Fix the "false-positive" by reordering the conditions to first check the > replacement instruction length before referencing specific opcode bytes. > > Signed-off-by: Mateusz Jurczyk > --- > Changes in v2: > - Add an explaining comment, as per Borislav Petkov's request. > > arch/x86/kernel/alternative.c | 9 +++++++-- > 1 file changed, 7 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c > index c5b8f760473c..32e14d137416 100644 > --- a/arch/x86/kernel/alternative.c > +++ b/arch/x86/kernel/alternative.c > @@ -409,8 +409,13 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start, > memcpy(insnbuf, replacement, a->replacementlen); > insnbuf_sz = a->replacementlen; > > - /* 0xe8 is a relative jump; fix the offset. */ > - if (*insnbuf == 0xe8 && a->replacementlen == 5) { > + /* > + * 0xe8 is a relative jump; fix the offset. > + * > + * Instruction length is checked before the opcode to avoid > + * accessing uninitialized bytes for zero-length replacements. > + */ > + if (a->replacementlen == 5 && *insnbuf == 0xe8) { > *(s32 *)(insnbuf + 1) += replacement - instr; > DPRINTK("Fix CALL offset: 0x%x, CALL 0x%lx", > *(s32 *)(insnbuf + 1), > -- Reviewed-by: Borislav Petkov -- Regards/Gruss, Boris. SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg) --