severity 1078556 grave tags 1078556 + upstream patch forwarded 1078556 https://lists.gnu.org/archive/html/bug-bash/2024-08/msg00087.html forcemerge 1078556 1078583 thanks
it's crazy to me that these were allowed to stay as normal (I'd say it's critical, since it "makes unrelated software on the system [...] break"; call it grave since actual usage of printf %f in system-provided programs is pretty rare), or that bash with this bug was allowed to migrate to testing. My analysis agrees with the mailing list: # valgrind bash -c 'printf %f 2' ==4136153== Memcheck, a memory error detector ==4136153== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==4136153== Using Valgrind-3.20.0 and LibVEX; rerun with -h for copyright info ==4136153== Command: bash -c printf\ %f\ 2 ==4136153== ==4136153== Conditional jump or move depends on uninitialised value(s) ==4136153== at 0x48E5435: __printf_fp_buffer_1.isra.0 (printf_fp.c:227) ==4136153== by 0x48E745B: __printf_fp_l_buffer (printf_fp.c:1122) ==4136153== by 0x48EDE4C: __printf_fp_spec (vfprintf-internal.c:266) ==4136153== by 0x48EDE4C: __printf_buffer (vfprintf-internal.c:999) ==4136153== by 0x48EECA0: __vfprintf_internal (vfprintf-internal.c:1544) ==4136153== by 0x49A16A6: __printf_chk (printf_chk.c:33) ==4136153== by 0x1C00A4: printf (stdio2.h:86) ==4136153== by 0x1C00A4: printf_builtin (printf.def:721) ==4136153== by 0x14E969: execute_builtin (execute_cmd.c:4971) ==4136153== by 0x154B24: execute_builtin_or_function (execute_cmd.c:5485) ==4136153== by 0x154B24: execute_simple_command (execute_cmd.c:4737) ==4136153== by 0x154B24: execute_command_internal (execute_cmd.c:866) ==4136153== by 0x1AEF58: parse_and_execute (evalstring.c:539) ==4136153== by 0x139FD9: run_one_command.isra.0 (shell.c:1473) ==4136153== by 0x138AA1: main (shell.c:763) ==4136153== ==4136153== Conditional jump or move depends on uninitialised value(s) ==4136153== at 0x48E538C: __printf_fp_buffer_1.isra.0 (printf_fp.c:238) ==4136153== by 0x48E745B: __printf_fp_l_buffer (printf_fp.c:1122) ==4136153== by 0x48EDE4C: __printf_fp_spec (vfprintf-internal.c:266) ==4136153== by 0x48EDE4C: __printf_buffer (vfprintf-internal.c:999) ==4136153== by 0x48EECA0: __vfprintf_internal (vfprintf-internal.c:1544) ==4136153== by 0x49A16A6: __printf_chk (printf_chk.c:33) ==4136153== by 0x1C00A4: printf (stdio2.h:86) ==4136153== by 0x1C00A4: printf_builtin (printf.def:721) ==4136153== by 0x14E969: execute_builtin (execute_cmd.c:4971) ==4136153== by 0x154B24: execute_builtin_or_function (execute_cmd.c:5485) ==4136153== by 0x154B24: execute_simple_command (execute_cmd.c:4737) ==4136153== by 0x154B24: execute_command_internal (execute_cmd.c:866) ==4136153== by 0x1AEF58: parse_and_execute (evalstring.c:539) ==4136153== by 0x139FD9: run_one_command.isra.0 (shell.c:1473) ==4136153== by 0x138AA1: main (shell.c:763) ==4136153== -nan==4136153== ==4136153== HEAP SUMMARY: ==4136153== in use at exit: 53,517 bytes in 422 blocks ==4136153== total heap usage: 459 allocs, 37 frees, 57,384 bytes allocated ==4136153== ==4136153== LEAK SUMMARY: ==4136153== definitely lost: 0 bytes in 0 blocks ==4136153== indirectly lost: 0 bytes in 0 blocks ==4136153== possibly lost: 0 bytes in 0 blocks ==4136153== still reachable: 53,517 bytes in 422 blocks ==4136153== suppressed: 0 bytes in 0 blocks ==4136153== Rerun with --leak-check=full to see details of leaked memory ==4136153== ==4136153== Use --track-origins=yes to see where uninitialised values come from ==4136153== For lists of detected and suppressed errors, rerun with: -s ==4136153== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) and this clearly shows that bash is actually using a normal-length double (strtod()): strchr("#'-+ 0", 'f') = nil strchr("hjlLtz", 'f') = nil __errno_location() = 0x7fdd273a86c8 strtod("2", "") = 2.000000 strlen("%f") = 2 malloc(1024) = 0x55ce477f5ee0 memcpy(0x55ce477f5ee0, "%", 1) = 0x55ce477f5ee0 clearerr(0x7fdd275825c0, 76, 0, 1) = 0xfbad2284 __printf_chk(1, 0x55ce477f5ee0, 0, 1) = 2094 and if it's giving that to %Lf then that's obviously wrong and the other half of the long double is uninitialised. This bug is only made visible because the configuration script is /also/ broken, since bookworm bash uses strtold(). This was identified by upstream and a patch is given in https://lists.gnu.org/archive/html/bug-bash/2024-08/msg00090.html I've verified that on sid with 5.2.21-2.1 prior to this patch, strtold() is not detected (and this triggers the bug, per valgrind): checking whether strtold is declared... yes checking for broken strtold... yes but with this patch strtold() is detected checking whether strtold is declared... yes checking for broken strtold... no and the bug is not triggered # valgrind ./debian/bash/usr/bin/bash -c 'printf %f 2' ==148139== Memcheck, a memory error detector ==148139== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==148139== Using Valgrind-3.20.0 and LibVEX; rerun with -h for copyright info ==148139== Command: ./debian/bash/usr/bin/bash -c printf\ %f\ 2 ==148139== 2.000000==148139== ==148139== HEAP SUMMARY: ==148139== in use at exit: 53,735 bytes in 425 blocks ==148139== total heap usage: 460 allocs, 35 frees, 57,631 bytes allocated ==148139== ==148139== LEAK SUMMARY: ==148139== definitely lost: 0 bytes in 0 blocks ==148139== indirectly lost: 0 bytes in 0 blocks ==148139== possibly lost: 0 bytes in 0 blocks ==148139== still reachable: 53,735 bytes in 425 blocks ==148139== suppressed: 0 bytes in 0 blocks ==148139== Rerun with --leak-check=full to see details of leaked memory ==148139== ==148139== For lists of detected and suppressed errors, rerun with: -s ==148139== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) I'm attaching upstream's configure-strtold-check (reformatted to unified debian/patches/-compatible format, tested against 5.2.21-2.1). Best,
--- bash-5.2.21.orig/configure +++ bash-5.2.21/configure @@ -15676,7 +15676,7 @@ else $as_nop int main (void) { -long double r; char *foo, bar; r = strtold(foo, &bar); +long double r; char *foo, *bar; r = strtold(foo, &bar); ; return 0; --- bash-5.2.21.orig/configure.ac +++ bash-5.2.21/configure.ac @@ -885,7 +885,7 @@ AC_CHECK_DECLS([strtold], [ [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[#include <stdlib.h>]], - [[long double r; char *foo, bar; r = strtold(foo, &bar);]] + [[long double r; char *foo, *bar; r = strtold(foo, &bar);]] )], [bash_cv_strtold_broken=no],[bash_cv_strtold_broken=yes]) ]
signature.asc
Description: PGP signature