From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mta1.formilux.org (mta1.formilux.org [51.159.59.229]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D2B7A35674C for ; Sun, 26 Jul 2026 16:01:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=51.159.59.229 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785081683; cv=none; b=KKWSIOKIJZq6akASckkRHtZG88ngpYKuLFJx9TblGk0Im8d2msYx7iPCfCK5hTTWaiDvE96eYsoRhj43/b/oHRyaGflncBffS9eYBKHBRavwbXQYz8djB+HNI1XN89vgG/ONSzNhCDsv7M4Ert6Pw21asg3F7bwxTa0Hsxk2Mdg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785081683; c=relaxed/simple; bh=qc8TI7coDHDMk6rrvcGxqI4PK/ClhXefLf/6sg/ahJw=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=nvneAuwQCAnYCCGJxE3WREwsM3XrvYF5Fb4QeZy/iOVl6++sLoM4/d4/yBXwmJ4OtcORticQS4N8t3hEDMp4r7hUYeF8B+FogjuVuqRSssXna68ME/qwA5zPMIJB62KuI1eP2u3XOsY6lEXGNH4hfloG8dkWYaybJo5ajXat8Ic= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=1wt.eu; spf=pass smtp.mailfrom=1wt.eu; dkim=pass (1024-bit key) header.d=1wt.eu header.i=@1wt.eu header.b=RcqlGY0a; arc=none smtp.client-ip=51.159.59.229 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=1wt.eu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=1wt.eu Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=1wt.eu header.i=@1wt.eu header.b="RcqlGY0a" 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> Precedence: bulk X-Mailing-List: llvm@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260726151334.4c1ec6f1@pumpkin> 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