• Russell King's avatar
    ARM: fix csum_tcpudp_magic() miscompilation · d46cda12
    Russell King authored
    There is a miscompilation of csum_tcpudp_magic() due to the way we pass
    the asm() operands in.  Fortunately, this doesn't affect the IP code,
    but can affect anyone who passes ntohs(udp->len) as the length argument,
    or protocols with more than 8 bits.
    
    The problem stems from passing 16-bit operands into an asm() - GCC makes
    no guarantees about what may be in the high 16-bits of such a register
    passed into assembly which is in the "HI" machine mode.
    
    Address this by changing the way we handle the 16-bit arguments - since
    accumulating the protocol and length can never overflow, we can delegate
    this to the compiler to perform, and then accumulate it into the
    checksum inside the asm(), taking account of the endian-ness via an
    appropriate 32-bit rotation.
    
    While we are here, also realise that there's a chance to optimise this
    a little: several callers from IP code pass a constant zero as the
    initial sum.  This is wasteful - if we detect this condition, we can
    optimise away one instruction.
    Tested-by: default avatarMaxime Bizon <mbizon@freebox.fr>
    Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
    d46cda12
checksum.h 3.73 KB