x86/alternatives: Prevent uninitialized stack byte read in apply_alternatives()
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 <mjurczyk@google.com> Reviewed-by: Borislav Petkov <bp@suse.de> Cc: Andy Lutomirski <luto@kernel.org> Link: http://lkml.kernel.org/r/20170524135500.27223-1-mjurczyk@google.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
cbed27cdf0
commit
fc152d22d6
@ -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),
|
||||
|
Loading…
x
Reference in New Issue
Block a user