From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by sourceware.org (Postfix) with ESMTPS id 27405383D82D for ; Mon, 23 May 2022 11:05:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 27405383D82D Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 538AB218E5 for ; Mon, 23 May 2022 11:05:19 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 3ECC5139F5 for ; Mon, 23 May 2022 11:05:19 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 6FAxDm9qi2JxFQAAMHmgww (envelope-from ) for ; Mon, 23 May 2022 11:05:19 +0000 From: Tom de Vries To: gdb-patches@sourceware.org Subject: [PATCH 7/8] [gdb/m2] Fix UB and literal truncation Date: Mon, 23 May 2022 13:05:17 +0200 Message-Id: <20220523110518.2447-7-tdevries@suse.de> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220523110518.2447-1-tdevries@suse.de> References: <20220523110518.2447-1-tdevries@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 May 2022 11:05:22 -0000 Rewrite parse_number to use ULONGEST instead of LONGEST, to fix UB errors as mentioned in PR29163. Furthermore, make sure we error out on overflow instead of truncating in all cases. Tested on x86_64-linux, with a build with --enable-targets=all. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29163 --- gdb/m2-exp.y | 47 ++++++++++++------------- gdb/testsuite/gdb.base/parse_number.exp | 3 +- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y index 85bac11b8fb..d3e917bb8d7 100644 --- a/gdb/m2-exp.y +++ b/gdb/m2-exp.y @@ -582,12 +582,11 @@ static int parse_number (int olen) { const char *p = pstate->lexptr; - LONGEST n = 0; - LONGEST prevn = 0; + ULONGEST n = 0; + ULONGEST prevn = 0; int c,i,ischar=0; int base = input_radix; int len = olen; - int unsigned_p = number_sign == 1 ? 1 : 0; if(p[len-1] == 'H') { @@ -639,16 +638,11 @@ parse_number (int olen) n+=i; if(i >= base) return ERROR; - if(!unsigned_p && number_sign == 1 && (prevn >= n)) - unsigned_p=1; /* Try something unsigned */ - /* Don't do the range check if n==i and i==0, since that special - case will give an overflow error. */ - if(RANGE_CHECK && n!=i && i) - { - if((unsigned_p && (unsigned)prevn >= (unsigned)n) || - ((!unsigned_p && number_sign==-1) && -prevn <= -n)) - range_error (_("Overflow on numeric constant.")); - } + if (n == 0 && prevn == 0) + ; + else if (RANGE_CHECK && prevn >= n) + range_error (_("Overflow on numeric constant.")); + prevn=n; } @@ -661,17 +655,22 @@ parse_number (int olen) yylval.ulval = n; return CHAR; } - else if ( unsigned_p && number_sign == 1) - { - yylval.ulval = n; - return UINT; - } - else if((unsigned_p && (n<0))) { - range_error (_("Overflow on numeric constant -- number too large.")); - /* But, this can return if range_check == range_warn. */ - } - yylval.lval = n; - return INT; + + int int_bits = gdbarch_int_bit (pstate->gdbarch ()); + bool have_signed = number_sign == -1; + bool have_unsigned = number_sign == 1; + if (have_signed && fits_in_type (number_sign, n, int_bits, true)) + { + yylval.lval = n; + return INT; + } + else if (have_unsigned && fits_in_type (number_sign, n, int_bits, false)) + { + yylval.ulval = n; + return UINT; + } + else + error (_("Overflow on numeric constant.")); } diff --git a/gdb/testsuite/gdb.base/parse_number.exp b/gdb/testsuite/gdb.base/parse_number.exp index 4189ccaf92c..6e0091278a9 100644 --- a/gdb/testsuite/gdb.base/parse_number.exp +++ b/gdb/testsuite/gdb.base/parse_number.exp @@ -161,8 +161,7 @@ proc parse_number { lang n } { return [list "CARDINAL" $n] } else { # Overflow. - # Some truncated value or re_overflow, should be re_overflow. - return [list ($re_overflow|CARDINAL|INTEGER) ($re_overflow|$any)] + return [list $re_overflow $re_overflow] } } elseif { $lang == "fortran" } { if { [fits_in_type $n $int_bits s] } { -- 2.35.3