From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3391 invoked by alias); 11 Dec 2019 07:52:29 -0000 Mailing-List: contact gdb-testers-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-testers-owner@sourceware.org Received: (qmail 3378 invoked by uid 89); 11 Dec 2019 07:52:29 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.1 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: kwanyin.sergiodj.net Received: from kwanyin.sergiodj.net (HELO kwanyin.sergiodj.net) (158.69.185.54) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 11 Dec 2019 07:52:27 +0000 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [binutils-gdb] ubsan: cris: signed integer overflow From: gdb-buildbot@sergiodj.net To: gdb-testers@sourceware.org Message-Id: Date: Wed, 11 Dec 2019 07:52:00 -0000 X-SW-Source: 2019-q4/txt/msg04346.txt.bz2 *** TEST RESULTS FOR COMMIT c202f69e5130fed314afa079ce30abaad4d34991 *** commit c202f69e5130fed314afa079ce30abaad4d34991 Author: Alan Modra AuthorDate: Tue Dec 10 23:22:10 2019 +1030 Commit: Alan Modra CommitDate: Wed Dec 11 11:38:24 2019 +1030 ubsan: cris: signed integer overflow This was the following in print_with_operands case 4: number = buffer[2] + buffer[3] * 256 + buffer[4] * 65536 + buffer[5] * 0x1000000; and buffer[5] * 0x1000000 can indeed overflow. So to fix this we need to use unsigned arithmetic where overflow semantics are specified. But number is a long, and the expression is int which will be sign extended to long. If we make the expression unsigned it will be zero extended. So make number an int32_t and rearrange a little for some of the places that need fixing. * cris-dis.c (print_with_operands): Avoid signed integer overflow when collecting bytes of a 32-bit integer. diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 57212f843b..6b76f158c9 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,8 @@ +2019-12-11 Alan Modra + + * cris-dis.c (print_with_operands): Avoid signed integer + overflow when collecting bytes of a 32-bit integer. + 2019-12-11 Alan Modra * cr16-dis.c (EXTRACT, SBM): Rewrite. diff --git a/opcodes/cris-dis.c b/opcodes/cris-dis.c index 793549d26d..c501ba002c 100644 --- a/opcodes/cris-dis.c +++ b/opcodes/cris-dis.c @@ -850,9 +850,8 @@ print_with_operands (const struct cris_opcode *opcodep, case 'n': { /* Like N but pc-relative to the start of the insn. */ - unsigned long number - = (buffer[2] + buffer[3] * 256 + buffer[4] * 65536 - + buffer[5] * 0x1000000 + addr); + int32_t number = (buffer[2] + buffer[3] * 256 + buffer[4] * 65536 + + buffer[5] * 0x1000000u); /* Finish off and output previous formatted bytes. */ *tp = 0; @@ -860,14 +859,14 @@ print_with_operands (const struct cris_opcode *opcodep, (*info->fprintf_func) (info->stream, "%s", temp); tp = temp; - (*info->print_address_func) ((bfd_vma) number, info); + (*info->print_address_func) (addr + number, info); } break; case 'u': { /* Like n but the offset is bits <3:0> in the instruction. */ - unsigned long number = (buffer[0] & 0xf) * 2 + addr; + unsigned int number = (buffer[0] & 0xf) * 2; /* Finish off and output previous formatted bytes. */ *tp = 0; @@ -875,7 +874,7 @@ print_with_operands (const struct cris_opcode *opcodep, (*info->fprintf_func) (info->stream, "%s", temp); tp = temp; - (*info->print_address_func) ((bfd_vma) number, info); + (*info->print_address_func) (addr + number, info); } break; @@ -889,7 +888,7 @@ print_with_operands (const struct cris_opcode *opcodep, { /* We're looking at [pc+], i.e. we need to output an immediate number, where the size can depend on different things. */ - long number; + int32_t number; int signedp = ((*cs == 'z' && (insn & 0x20)) || opcodep->match == BDAP_QUICK_OPCODE); @@ -940,9 +939,8 @@ print_with_operands (const struct cris_opcode *opcodep, break; case 4: - number - = buffer[2] + buffer[3] * 256 + buffer[4] * 65536 - + buffer[5] * 0x1000000; + number = (buffer[2] + buffer[3] * 256 + buffer[4] * 65536 + + buffer[5] * 0x1000000u); break; default: @@ -1042,10 +1040,10 @@ print_with_operands (const struct cris_opcode *opcodep, { /* It's [pc+]. This cannot possibly be anything but an address. */ - unsigned long number - = prefix_buffer[2] + prefix_buffer[3] * 256 - + prefix_buffer[4] * 65536 - + prefix_buffer[5] * 0x1000000; + int32_t number = (prefix_buffer[2] + + prefix_buffer[3] * 256 + + prefix_buffer[4] * 65536 + + prefix_buffer[5] * 0x1000000u); info->target = (bfd_vma) number; @@ -1131,7 +1129,7 @@ print_with_operands (const struct cris_opcode *opcodep, if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15) { - long number; + int32_t number; unsigned int nbytes; /* It's a value. Get its size. */ @@ -1157,10 +1155,9 @@ print_with_operands (const struct cris_opcode *opcodep, break; case 4: - number - = prefix_buffer[2] + prefix_buffer[3] * 256 - + prefix_buffer[4] * 65536 - + prefix_buffer[5] * 0x1000000; + number = (prefix_buffer[2] + prefix_buffer[3] * 256 + + prefix_buffer[4] * 65536 + + prefix_buffer[5] * 0x1000000u); break; default: