From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server-vie001.gnuweeb.org X-Spam-Level: * X-Spam-Status: No, score=1.6 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,NO_DNS_FOR_FROM,SPF_PASS autolearn=no autolearn_force=no version=3.4.6 Authentication-Results: server-vie001.gnuweeb.org; dkim=pass (1024-bit key; unprotected) header.d=1wt.eu header.i=@1wt.eu header.a=rsa-sha256 header.s=mail header.b=RcqlGY0a; dkim-atps=neutral Received: by server-vie001.gnuweeb.org (Postfix, from userid 1000) id C35962E17D32; Sun, 26 Jul 2026 16:01:18 +0000 (UTC) Authentication-Results: server-vie001.gnuweeb.org; dmarc=pass (p=none dis=none) header.from=1wt.eu Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=51.159.59.229; helo=mta1.formilux.org; envelope-from=bounce@1wt.eu; receiver= Received: from mta1.formilux.org (mta1.formilux.org [51.159.59.229]) by server-vie001.gnuweeb.org (Postfix) with ESMTPS id 489A52E17D21; Sun, 26 Jul 2026 16:01:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1wt.eu; s=mail; t=1785081672; bh=FjX+HZlxW+WsZ2V2ep3yP0QJydoexSzmKp0lKAEIC/4=; h=From:Message-ID:From; b=RcqlGY0aok5ZCGzOZcodOlpFs8c3UU6srA9sF7UB/uQmZycm8Ruxr/62oiF70kV9I 7KmhruYAofFx93JyYTAqD6+ah+8gAocaB3WRmDfzG/d4hy7SNOTLaWQjjvqYV/GYSI YPfrYq6zmb9+D1KNrLkvjFbsaACgVVWsZN11ni1M= Received: from 1wt.eu (ded1.1wt.eu [163.172.96.212]) by mta1.formilux.org (Postfix) with ESMTP id 730DBC0A72; Sun, 26 Jul 2026 18:01:12 +0200 (CEST) Date: Sun, 26 Jul 2026 18:01:11 +0200 From: Willy Tarreau To: David Laight Cc: Ammar Faizi , Thomas =?iso-8859-1?Q?Wei=DFschuh?= , Linux Kernel Mailing List , Linux Kselftest Mailing List , LLVM Mailing List , Yichun Zhang , Alviro Iskandar Setiawan , Shuah Khan , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , gwml@gnuweeb.org Subject: Re: [PATCH 2/4] tools/nolibc: stdlib: avoid signed overflow in abs() and friends Message-ID: References: <20260726101306.3772237-1-ammarfaizi2@openresty.com> <20260726101306.3772237-3-ammarfaizi2@openresty.com> <20260726151334.4c1ec6f1@pumpkin> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260726151334.4c1ec6f1@pumpkin> List-Id: On Sun, Jul 26, 2026 at 03:13:34PM +0100, David Laight wrote: > On Sun, 26 Jul 2026 17:13:03 +0700 > Ammar Faizi wrote: > > > Negating the smallest negative value of a signed type overflows, which > > is undefined behavior. The selftests are built with: > > > > -fsanitize=undefined -fsanitize-trap=all > > > > so a caller passing INT_MIN does not merely get an unspecified answer, > > it dies (on both x86-64 and i386): > > > > A simple test program: > > > > printf("x = %d\n", abs(INT_MIN)); > > > > $ ./ab > > Illegal instruction (core dumped) > > > > (gdb) bt > > #0 0x0000000000401009 in main () > > (gdb) x/6i main > > 0x401000
: mov $0x80000000,%eax > > 0x401005 : neg %eax > > 0x401007 : jno 0x40100b > > => 0x401009 : ud2 > > 0x40100b : push %rax > > 0x40100c : mov $0x80000000,%esi > > > > Negate in the corresponding unsigned type instead. The value still > > cannot be represented in the result type, so the minimum is returned > > unchanged. > > > > Cc: Yichun Zhang > > Cc: Alviro Iskandar Setiawan > > Fixes: bf5e8a78bede ("tools/nolibc: add abs() and friends") > > Signed-off-by: Ammar Faizi > > --- > > tools/include/nolibc/stdlib.h | 12 +++++++++--- > > 1 file changed, 9 insertions(+), 3 deletions(-) > > > > diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h > > index 1816c2368b68..8d86044f759f 100644 > > --- a/tools/include/nolibc/stdlib.h > > +++ b/tools/include/nolibc/stdlib.h > > @@ -32,22 +32,28 @@ static __attribute__((unused)) char itoa_buffer[21]; > > * As much as possible, please keep functions alphabetically sorted. > > */ > > > > +/* > > + * The absolute value of the smallest negative value is not representable in > > + * the result type. Negate in the unsigned type so that the overflow is > > + * defined and return it unchanged, like the other libcs do. > > + */ > > + > > static __inline__ > > int abs(int j) > > { > > - return j >= 0 ? j : -j; > > + return j >= 0 ? j : (int)-(unsigned int)j; > > An alternative expression is -(j + 1) - 1 > gcc (and I think clang) optimise it to just -j. This one would give -j -2, but ~(j - 1) would work, just like (~j + 1). However here the benefit of the casts in Ammar's version is that it's obvious that it's only playing with same size casts with no extra operation. Willy