From unknown Sat Jun 21 02:54:48 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#7347 <7347@debbugs.gnu.org> To: bug#7347 <7347@debbugs.gnu.org> Subject: Status: [PATCH] stat: do not rely on undefined behavior in printf formats Reply-To: bug#7347 <7347@debbugs.gnu.org> Date: Sat, 21 Jun 2025 09:54:48 +0000 retitle 7347 [PATCH] stat: do not rely on undefined behavior in printf form= ats reassign 7347 coreutils submitter 7347 Paul Eggert severity 7347 normal tag 7347 patch thanks From debbugs-submit-bounces@debbugs.gnu.org Sat Nov 06 16:59:30 2010 Received: (at submit) by debbugs.gnu.org; 6 Nov 2010 20:59:30 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1PEprF-0003QZ-Lw for submit@debbugs.gnu.org; Sat, 06 Nov 2010 16:59:29 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1PEprD-0003QU-0l for submit@debbugs.gnu.org; Sat, 06 Nov 2010 16:59:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PEpvb-0001sx-VS for submit@debbugs.gnu.org; Sat, 06 Nov 2010 17:04:00 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_RP_MATCHES_RCVD autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([199.232.76.165]:54430) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PEpvb-0001st-Sj for submit@debbugs.gnu.org; Sat, 06 Nov 2010 17:03:59 -0400 Received: from [140.186.70.92] (port=40358 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PEpva-00069s-Vu for bug-coreutils@gnu.org; Sat, 06 Nov 2010 17:03:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PEpvZ-0001sc-Gk for bug-coreutils@gnu.org; Sat, 06 Nov 2010 17:03:58 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:40015) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PEpvZ-0001sR-1v for bug-coreutils@gnu.org; Sat, 06 Nov 2010 17:03:57 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 26E6539E80F5 for ; Sat, 6 Nov 2010 14:03:53 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id A5QfP1TiEfzL for ; Sat, 6 Nov 2010 14:03:52 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id B2E2E39E80E0 for ; Sat, 6 Nov 2010 14:03:52 -0700 (PDT) Message-ID: <4CD5C2B0.3090709@cs.ucla.edu> Date: Sat, 06 Nov 2010 14:03:44 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.12) Gecko/20101027 Thunderbird/3.1.6 MIME-Version: 1.0 To: bug-coreutils@gnu.org Subject: [PATCH] stat: do not rely on undefined behavior in printf formats Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Spam-Score: -4.6 (----) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.7 (----) I have not pushed this, as I understand you're trying to put out a release, but this fixes some portability bugs in 'stat', such that it was relying on undefined behavior, which presumably could cause 'stat' to dump core, or worse, on non-GNU platforms. The downside of this patch is that the "I" printf flag is now ignored. However, support for "I" wasn't working anyway (because of time stamp fractions), so this isn't much of a loss. We can add proper "I" support later, if there's demand for it. >From 844d06f2f74cc26e648c9951f9ab43ae11c1dfc9 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 6 Nov 2010 13:57:08 -0700 Subject: [PATCH] stat: do not rely on undefined behavior in printf formats * src/stat.c (digits, printf_flags): New static vars. (make_format): New function. (out_string, out_int, out_uint, out_uint_o, out_uint_x): (out_minus_zero): Use it to avoid undefined behavior when invoking printf. (print_it): Check for invalid conversion specifications such as %..X and %1-X, which would otherwise rely on undefined behavior when invoking printf. * tests/misc/stat-nanoseconds: Check that the "I" printf flag doesn't mess up in the C locale, as it formerly did on non-GNU hosts. --- src/stat.c | 47 ++++++++++++++++++++++++++++++++++++------ tests/misc/stat-nanoseconds | 1 + 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/stat.c b/src/stat.c index 99f115b..ae7ce02 100644 --- a/src/stat.c +++ b/src/stat.c @@ -150,6 +150,16 @@ statfs (char const *filename, struct fs_info *buf) #define hextobin(c) ((c) >= 'a' && (c) <= 'f' ? (c) - 'a' + 10 : \ (c) >= 'A' && (c) <= 'F' ? (c) - 'A' + 10 : (c) - '0') +static char const digits[] = "0123456789"; + +/* Flags that are portable for use in printf, for at least one + conversion specifier; make_format removes unportable flags as + needed for particular specifiers. The glibc 2.2 extension "I" is + listed here; it is removed by make_format because it has undefined + behavior elsewhere and because it is incompatible with + out_epoch_sec. */ +static char const printf_flags[] = "'-+ #0I"; + #define PROGRAM_NAME "stat" #define AUTHORS proper_name ("Michael Meskes") @@ -467,40 +477,59 @@ human_time (struct timespec t) return str; } +/* PFORMAT points to a '%' followed by a prefix of a format, all of + size PREFIX_LEN. The flags allowed for this format are + ALLOWED_FLAGS; remove other printf flags from the prefix, then + append SUFFIX. */ +static void +make_format (char *pformat, size_t prefix_len, char const *allowed_flags, + char const *suffix) +{ + char *dst = pformat + 1; + char const *src; + char const *srclim = pformat + prefix_len; + for (src = dst; src < srclim && strchr (printf_flags, *src); src++) + if (strchr (allowed_flags, *src)) + *dst++ = *src; + while (src < srclim) + *dst++ = *src++; + strcpy (dst, suffix); +} + static void out_string (char *pformat, size_t prefix_len, char const *arg) { - strcpy (pformat + prefix_len, "s"); + make_format (pformat, prefix_len, "-", "s"); printf (pformat, arg); } static int out_int (char *pformat, size_t prefix_len, intmax_t arg) { - strcpy (pformat + prefix_len, PRIdMAX); + make_format (pformat, prefix_len, "'-+ 0", PRIdMAX); return printf (pformat, arg); } static int out_uint (char *pformat, size_t prefix_len, uintmax_t arg) { - strcpy (pformat + prefix_len, PRIuMAX); + make_format (pformat, prefix_len, "'-0", PRIuMAX); return printf (pformat, arg); } static void out_uint_o (char *pformat, size_t prefix_len, uintmax_t arg) { - strcpy (pformat + prefix_len, PRIoMAX); + make_format (pformat, prefix_len, "-#0", PRIoMAX); printf (pformat, arg); } static void out_uint_x (char *pformat, size_t prefix_len, uintmax_t arg) { - strcpy (pformat + prefix_len, PRIxMAX); + make_format (pformat, prefix_len, "-#0", PRIxMAX); printf (pformat, arg); } static int out_minus_zero (char *pformat, size_t prefix_len) { - strcpy (pformat + prefix_len, ".0f"); + make_format (pformat, prefix_len, "'-+ 0", ".0f"); return printf (pformat, -0.25); } @@ -1028,8 +1057,12 @@ print_it (char const *format, char const *filename, { case '%': { - size_t len = strspn (b + 1, "#-+.I 0123456789"); + size_t len = strspn (b + 1, printf_flags); char const *fmt_char = b + len + 1; + fmt_char += strspn (fmt_char, digits); + if (*fmt_char == '.') + fmt_char += 1 + strspn (fmt_char + 1, digits); + len = fmt_char - (b + 1); unsigned int fmt_code = *fmt_char; memcpy (dest, b, len + 1); diff --git a/tests/misc/stat-nanoseconds b/tests/misc/stat-nanoseconds index 0f41eb0..cd21596 100755 --- a/tests/misc/stat-nanoseconds +++ b/tests/misc/stat-nanoseconds @@ -39,6 +39,7 @@ test "$(stat -c %13.6X k)" = ' 67413.023456' || fail=1 test "$(stat -c %013.6X k)" = 067413.023456 || fail=1 test "$(stat -c %-13.6X k)" = '67413.023456 ' || fail=1 test "$(stat -c %18.10X k)" = ' 67413.0234567890' || fail=1 +test "$(stat -c %I18.10X k)" = ' 67413.0234567890' || fail=1 test "$(stat -c %018.10X k)" = 0067413.0234567890 || fail=1 test "$(stat -c %-18.10X k)" = '67413.0234567890 ' || fail=1 -- 1.7.2 From debbugs-submit-bounces@debbugs.gnu.org Sat Nov 06 17:49:01 2010 Received: (at 7347) by debbugs.gnu.org; 6 Nov 2010 21:49:01 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1PEqdA-0003kS-I2 for submit@debbugs.gnu.org; Sat, 06 Nov 2010 17:49:00 -0400 Received: from mx.meyering.net ([82.230.74.64]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1PEqd8-0003kN-Az for 7347@debbugs.gnu.org; Sat, 06 Nov 2010 17:48:59 -0400 Received: by rho.meyering.net (Acme Bit-Twister, from userid 1000) id 512B2602E7; Sat, 6 Nov 2010 22:53:31 +0100 (CET) From: Jim Meyering To: Paul Eggert Subject: Re: bug#7347: [PATCH] stat: do not rely on undefined behavior in printf formats In-Reply-To: <4CD5C2B0.3090709@cs.ucla.edu> (Paul Eggert's message of "Sat, 06 Nov 2010 14:03:44 -0700") References: <4CD5C2B0.3090709@cs.ucla.edu> Date: Sat, 06 Nov 2010 22:53:31 +0100 Message-ID: <87wroqce5g.fsf@meyering.net> Lines: 30 MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -5.5 (-----) X-Debbugs-Envelope-To: 7347 Cc: 7347@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -5.5 (-----) Paul Eggert wrote: > I have not pushed this, as I understand you're trying to put out a > release, but this fixes some portability bugs in 'stat', such that it > was relying on undefined behavior, which presumably could cause > 'stat' to dump core, or worse, on non-GNU platforms. > > The downside of this patch is that the "I" printf flag is now ignored. > However, support for "I" wasn't working anyway (because of time stamp > fractions), so this isn't much of a loss. We can add proper "I" > support later, if there's demand for it. > > Subject: [PATCH] stat: do not rely on undefined behavior in printf formats > > * src/stat.c (digits, printf_flags): New static vars. > (make_format): New function. > (out_string, out_int, out_uint, out_uint_o, out_uint_x): > (out_minus_zero): Use it to avoid undefined behavior when invoking > printf. > (print_it): Check for invalid conversion specifications such as > %..X and %1-X, which would otherwise rely on undefined behavior > when invoking printf. > * tests/misc/stat-nanoseconds: Check that the "I" printf flag > doesn't mess up in the C locale, as it formerly did on non-GNU > hosts. Thanks for the patch! I looked through it, applied it and tested it. I see fixes (admittedly fringe, as you say, but still) and don't see anything that might cause trouble, so go ahead and push it. Nobody will miss the "I" flag. I think I've never even seen it used. From debbugs-submit-bounces@debbugs.gnu.org Sat Nov 06 21:09:42 2010 Received: (at 7347-done) by debbugs.gnu.org; 7 Nov 2010 01:09:42 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1PEtlO-0005mf-4r for submit@debbugs.gnu.org; Sat, 06 Nov 2010 21:09:42 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1PEtlL-0005ma-4a for 7347-done@debbugs.gnu.org; Sat, 06 Nov 2010 21:09:40 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 89EC539E80E1; Sat, 6 Nov 2010 18:14:12 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gWp+GL8Ys-I2; Sat, 6 Nov 2010 18:14:12 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 3599639E80E0; Sat, 6 Nov 2010 18:14:12 -0700 (PDT) Message-ID: <4CD5FD60.9020004@cs.ucla.edu> Date: Sat, 06 Nov 2010 18:14:08 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.12) Gecko/20101027 Thunderbird/3.1.6 MIME-Version: 1.0 To: Jim Meyering Subject: Re: bug#7347: [PATCH] stat: do not rely on undefined behavior in printf formats References: <4CD5C2B0.3090709@cs.ucla.edu> <87wroqce5g.fsf@meyering.net> In-Reply-To: <87wroqce5g.fsf@meyering.net> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.0 (---) X-Debbugs-Envelope-To: 7347-done Cc: 7347-done@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.0 (---) On 11/06/2010 02:53 PM, Jim Meyering wrote: > I see fixes (admittedly fringe, as you say, but still) > and don't see anything that might cause trouble, so go ahead and push it. Thanks for checking it; I just pushed it. From unknown Sat Jun 21 02:54:48 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Sun, 05 Dec 2010 12:24:04 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator