• Borislav Petkov's avatar
    x86/alternatives: Fix ALTERNATIVE_2 padding generation properly · dbe4058a
    Borislav Petkov authored
    Quentin caught a corner case with the generation of instruction
    padding in the ALTERNATIVE_2 macro: if len(orig_insn) <
    len(alt1) < len(alt2), then not enough padding gets added and
    that is not good(tm) as we could overwrite the beginning of the
    next instruction.
    
    Luckily, at the time of this writing, we don't have
    ALTERNATIVE_2() invocations which have that problem and even if
    we did, a simple fix would be to prepend the instructions with
    enough prefixes so that that corner case doesn't happen.
    
    However, best it would be if we fixed it properly. See below for
    a simple, abstracted example of what we're doing.
    
    So what we ended up doing is, we compute the
    
    	max(len(alt1), len(alt2)) - len(orig_insn)
    
    and feed that value to the .skip gas directive. The max() cannot
    have conditionals due to gas limitations, thus the fancy integer
    math.
    
    With this patch, all ALTERNATIVE_2 sites get padded correctly;
    generating obscure test cases pass too:
    
      #define alt_max_short(a, b)    ((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))
    
      #define gen_skip(orig, alt1, alt2, marker)	\
      	.skip -((alt_max_short(alt1, alt2) - (orig)) > 0) * \
      		(alt_max_short(alt1, alt2) - (orig)),marker
    
      	.pushsection .text, "ax"
      .globl main
      main:
      	gen_skip(1, 2, 4, 0x09)
      	gen_skip(4, 1, 2, 0x10)
      	...
      	.popsection
    
    Thanks to Quentin for catching it and double-checking the fix!
    Reported-by: default avatarQuentin Casasnovas <quentin.casasnovas@oracle.com>
    Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
    Cc: Andy Lutomirski <luto@amacapital.net>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Brian Gerst <brgerst@gmail.com>
    Cc: Denys Vlasenko <dvlasenk@redhat.com>
    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Link: http://lkml.kernel.org/r/20150404133443.GE21152@pd.tnicSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    dbe4058a
alternative.h 9.44 KB