]> xenbits.xensource.com Git - people/pauldu/qemu.git/commitdiff
disas/m68k: Avoid unintended sign extension in get_field()
authorPeter Maydell <peter.maydell@linaro.org>
Fri, 3 Mar 2017 15:50:30 +0000 (15:50 +0000)
committerPeter Maydell <peter.maydell@linaro.org>
Tue, 7 Mar 2017 14:33:51 +0000 (14:33 +0000)
In get_field(), we take an 'unsigned char' value and shift it left,
which implicitly promotes it to 'signed int', before ORing it into an
'unsigned long' type.  If 'unsigned long' is 64 bits then this will
result in a sign extension and the top 32 bits of the result will be
1s.  Add explicit casts to unsigned long before shifting to prevent
this.

(Spotted by Coverity, CID 715697.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-id: 1488556233-31246-4-git-send-email-peter.maydell@linaro.org

disas/m68k.c

index 073abb9efd7e76a90bdaca4a19a1a512cce510e8..61b689ef3ec1cea9e2c9071fafde2490b62b0a2e 100644 (file)
@@ -4685,10 +4685,11 @@ get_field (const unsigned char *data, enum floatformat_byteorders order,
        /* This is the last byte; zero out the bits which are not part of
           this field.  */
        result |=
-         (*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1))
+         (unsigned long)(*(data + cur_byte)
+                         & ((1 << (len - cur_bitshift)) - 1))
            << cur_bitshift;
       else
-       result |= *(data + cur_byte) << cur_bitshift;
+       result |= (unsigned long)*(data + cur_byte) << cur_bitshift;
       cur_bitshift += FLOATFORMAT_CHAR_BIT;
       if (order == floatformat_little)
        ++cur_byte;