public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/103955] New: std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int values
@ 2022-01-09 19:31 gcc at maxmitti dot tk
  2022-01-09 22:08 ` [Bug libstdc++/103955] std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int precision values pinskia at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: gcc at maxmitti dot tk @ 2022-01-09 19:31 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103955

            Bug ID: 103955
           Summary: std::to_chars(char*, char*, double, std::chars_format,
                    int precision) crashes for the two maximal int values
           Product: gcc
           Version: 11.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gcc at maxmitti dot tk
  Target Milestone: ---

Created attachment 52148
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52148&action=edit
preprocessed source

Calling std::to_chars(char*, char*, double, std::chars_format, int precision)
with a precision of 2147483647 or 2147483646 and a small buffer causes a
segmentation fault.
2147483645 and smaller return an error correctly.

The preprocessed source was created with GCC 11.1.0, but the crash also happens
with compiler-explorer’s 11.2 and trunk build and even with clang 13 when using
libstdc++, but not with libc++.

Example on compiler explorer: https://godbolt.org/z/c63qbWff4

gcc output follows:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib
--libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info
--with-bugurl=https://bugs.archlinux.org/
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --with-isl
--with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit
--enable-cet=auto --enable-checking=release --enable-clocale=gnu
--enable-default-pie --enable-default-ssp --enable-gnu-indirect-function
--enable-gnu-unique-object --enable-install-libiberty --enable-linker-build-id
--enable-lto --enable-multilib --enable-plugin --enable-shared
--enable-threads=posix --disable-libssp --disable-libstdcxx-pch
--disable-libunwind-exceptions --disable-werror
gdc_include_dir=/usr/include/dlang/gdc
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.1.0 (GCC) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++20' '-Wall' '-Wextra'
'-Wpedantic' '-o' 'bug' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/cc1plus -E -quiet -v -D_GNU_SOURCE
bug.cpp -mtune=generic -march=x86-64 -std=c++20 -Wall -Wextra -Wpedantic
-fpch-preprocess -o bug.ii
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../include/c++/11.1.0

/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../include/c++/11.1.0/x86_64-pc-linux-gnu

/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../include/c++/11.1.0/backward
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include-fixed
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++20' '-Wall' '-Wextra'
'-Wpedantic' '-o' 'bug' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/cc1plus -fpreprocessed bug.ii -quiet
-dumpbase bug.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -Wall -Wextra
-Wpedantic -std=c++20 -version -o bug.s
GNU C++20 (GCC) version 11.1.0 (x86_64-pc-linux-gnu)
        compiled by GNU C version 11.1.0, GMP version 6.2.1, MPFR version
4.1.0-p13, MPC version 1.2.1, isl version isl-0.24-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++20 (GCC) version 11.1.0 (x86_64-pc-linux-gnu)
        compiled by GNU C version 11.1.0, GMP version 6.2.1, MPFR version
4.1.0-p13, MPC version 1.2.1, isl version isl-0.24-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: e6d85a433da2a6385241e28f4582b1d3
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++20' '-Wall' '-Wextra'
'-Wpedantic' '-o' 'bug' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 as -v --64 -o bug.o bug.s
GNU assembler version 2.36.1 (x86_64-pc-linux-gnu) using BFD version (GNU
Binutils) 2.36.1
COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/:/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/:/usr/lib/gcc/x86_64-pc-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/:/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++20' '-Wall' '-Wextra'
'-Wpedantic' '-o' 'bug' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
'-dumpdir' 'bug.'
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/collect2 -plugin
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so
-plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/lto-wrapper
-plugin-opt=-fresolution=bug.res -plugin-opt=-pass-through=-lgcc_s
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id
--eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker
/lib64/ld-linux-x86-64.so.2 -pie -o bug
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/Scrt1.o
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/crti.o
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/crtbeginS.o
-L/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0
-L/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib -L/lib/../lib
-L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../.. bug.o
-lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/crtendS.o
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/crtn.o
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-std=c++20' '-Wall' '-Wextra'
'-Wpedantic' '-o' 'bug' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
'-dumpdir' 'bug.'

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/103955] std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int precision values
  2022-01-09 19:31 [Bug libstdc++/103955] New: std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int values gcc at maxmitti dot tk
@ 2022-01-09 22:08 ` pinskia at gcc dot gnu.org
  2022-01-09 22:27 ` pinskia at gcc dot gnu.org
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-01-09 22:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103955

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Unpreprocessed source (just in case):
#include <array>
#include <charconv>

int main()
{
    std::array<char, 36> result;

    // these two crash
    const auto [end, ec] = std::to_chars(result.data(), result.data() +
result.size(), 1.337, std::chars_format::fixed, 2147483647);
    std::to_chars(result.data(), result.data() + result.size(), 1.337,
std::chars_format::fixed, 2147483646);

    // does not crash
    std::to_chars(result.data(), result.data() + result.size(), 1.337,
std::chars_format::fixed, 2147483645);
    return ec == std::errc{};
}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/103955] std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int precision values
  2022-01-09 19:31 [Bug libstdc++/103955] New: std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int values gcc at maxmitti dot tk
  2022-01-09 22:08 ` [Bug libstdc++/103955] std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int precision values pinskia at gcc dot gnu.org
@ 2022-01-09 22:27 ` pinskia at gcc dot gnu.org
  2022-01-10 13:41 ` ppalka at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-01-09 22:27 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103955

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2022-01-09
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Confirmed.
With  -fsanitize=address I get:



=================================================================
==1==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd6d9523d7
at pc 0x7f37917b829e bp 0x7ffd6d9522c0 sp 0x7ffd6d951a70
WRITE of size 2147483594 at 0x7ffd6d9523d7 thread T0
    #0 0x7f37917b829d in __interceptor_memset
(/opt/compiler-explorer/gcc-11.2.0/lib64/libasan.so.6+0x3c29d)
    #1 0x7f37916cafa6 
(/opt/compiler-explorer/gcc-11.2.0/lib64/libstdc++.so.6+0x162fa6)
    #2 0x7f37916cb48c in std::to_chars(char*, char*, double, std::chars_format,
int) (/opt/compiler-explorer/gcc-11.2.0/lib64/libstdc++.so.6+0x16348c)
    #3 0x4010fa in main /app/example.cpp:9
    #4 0x7f37908c20b2 in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
    #5 0x4011ed in _start (/app/output.s+0x4011ed)

Address 0x7ffd6d9523d7 is located in stack of thread T0 at offset 103 in frame
    #0 0x40107f in main /app/example.cpp:5

  This frame has 1 object(s):
    [48, 84) 'result' (line 6) <== Memory access at offset 103 overflows this
variable
HINT: this may be a false positive if your program uses some custom stack
unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow
(/opt/compiler-explorer/gcc-11.2.0/lib64/libasan.so.6+0x3c29d) in
__interceptor_memset
Shadow bytes around the buggy address:
  0x10002db22420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002db22430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002db22440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002db22450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002db22460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
=>0x10002db22470: f1 f1 f1 f1 00 00 00 00 04 f3[f3]f3 f3 f3 00 00
  0x10002db22480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002db22490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002db224a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002db224b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002db224c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==1==ABORTING

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/103955] std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int precision values
  2022-01-09 19:31 [Bug libstdc++/103955] New: std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int values gcc at maxmitti dot tk
  2022-01-09 22:08 ` [Bug libstdc++/103955] std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int precision values pinskia at gcc dot gnu.org
  2022-01-09 22:27 ` pinskia at gcc dot gnu.org
@ 2022-01-10 13:41 ` ppalka at gcc dot gnu.org
  2022-01-12 14:10 ` cvs-commit at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: ppalka at gcc dot gnu.org @ 2022-01-10 13:41 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103955

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |ppalka at gcc dot gnu.org
   Target Milestone|---                         |11.3

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/103955] std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int precision values
  2022-01-09 19:31 [Bug libstdc++/103955] New: std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int values gcc at maxmitti dot tk
                   ` (2 preceding siblings ...)
  2022-01-10 13:41 ` ppalka at gcc dot gnu.org
@ 2022-01-12 14:10 ` cvs-commit at gcc dot gnu.org
  2022-04-12 19:18 ` cvs-commit at gcc dot gnu.org
  2022-04-12 19:18 ` ppalka at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-01-12 14:10 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103955

--- Comment #3 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>:

https://gcc.gnu.org/g:c0e355c77972d96fcec2ff7da047ad03e10e51d9

commit r12-6522-gc0e355c77972d96fcec2ff7da047ad03e10e51d9
Author: Patrick Palka <ppalka@redhat.com>
Date:   Wed Jan 12 09:10:24 2022 -0500

    libstdc++: Avoid overflow in bounds checks [PR103955]

    We currently crash when the floating-point to_chars overloads are passed
    a precision value near INT_MAX, ultimately due to overflow in the bounds
    checks that verify the output range is large enough.

    The simplest portable fix seems to be to replace bounds checks of the form
    A >= B + C (where B + C may overflow) with the otherwise equivalent check
    A >= B && A - B >= C, which is the approach this patch takes.

    Before we could do this in __floating_to_chars_hex, there we first need
    to track the unbounded "excess" precision (i.e. the number of trailing
    fractional digits in the output that are guaranteed to be '0') separately
    from the bounded "effective" precision (i.e. the number of significant
    fractional digits in the output), like we do in __f_t_c_precision.

            PR libstdc++/103955

    libstdc++-v3/ChangeLog:

            * src/c++17/floating_to_chars.cc (__floating_to_chars_hex):
            Track the excess precision separately from the effective
            precision.  Avoid overflow in bounds check by splitting it into
            two checks.
            (__floating_to_chars_precision): Avoid overflow in bounds checks
            similarly.
            * testsuite/20_util/to_chars/103955.cc: New test.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/103955] std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int precision values
  2022-01-09 19:31 [Bug libstdc++/103955] New: std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int values gcc at maxmitti dot tk
                   ` (3 preceding siblings ...)
  2022-01-12 14:10 ` cvs-commit at gcc dot gnu.org
@ 2022-04-12 19:18 ` cvs-commit at gcc dot gnu.org
  2022-04-12 19:18 ` ppalka at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-04-12 19:18 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103955

--- Comment #4 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-11 branch has been updated by Patrick Palka
<ppalka@gcc.gnu.org>:

https://gcc.gnu.org/g:0b6d4ee830b01ee70cc5dc32722d73ac3ea4e0db

commit r11-9822-g0b6d4ee830b01ee70cc5dc32722d73ac3ea4e0db
Author: Patrick Palka <ppalka@redhat.com>
Date:   Wed Jan 12 09:10:24 2022 -0500

    libstdc++: Avoid overflow in bounds checks [PR103955]

    We currently crash when the floating-point to_chars overloads are passed
    a precision value near INT_MAX, ultimately due to overflow in the bounds
    checks that verify the output range is large enough.

    The simplest portable fix seems to be to replace bounds checks of the form
    A >= B + C (where B + C may overflow) with the otherwise equivalent check
    A >= B && A - B >= C, which is the approach this patch takes.

    Before we could do this in __floating_to_chars_hex, there we first need
    to track the unbounded "excess" precision (i.e. the number of trailing
    fractional digits in the output that are guaranteed to be '0') separately
    from the bounded "effective" precision (i.e. the number of significant
    fractional digits in the output), like we do in __f_t_c_precision.

            PR libstdc++/103955

    libstdc++-v3/ChangeLog:

            * src/c++17/floating_to_chars.cc (__floating_to_chars_hex):
            Track the excess precision separately from the effective
            precision.  Avoid overflow in bounds check by splitting it into
            two checks.
            (__floating_to_chars_precision): Avoid overflow in bounds checks
            similarly.
            * testsuite/20_util/to_chars/103955.cc: New test.

    (cherry picked from commit c0e355c77972d96fcec2ff7da047ad03e10e51d9)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug libstdc++/103955] std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int precision values
  2022-01-09 19:31 [Bug libstdc++/103955] New: std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int values gcc at maxmitti dot tk
                   ` (4 preceding siblings ...)
  2022-04-12 19:18 ` cvs-commit at gcc dot gnu.org
@ 2022-04-12 19:18 ` ppalka at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: ppalka at gcc dot gnu.org @ 2022-04-12 19:18 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103955

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |FIXED

--- Comment #5 from Patrick Palka <ppalka at gcc dot gnu.org> ---
Fixed for 11.3/12.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-04-12 19:18 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-09 19:31 [Bug libstdc++/103955] New: std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int values gcc at maxmitti dot tk
2022-01-09 22:08 ` [Bug libstdc++/103955] std::to_chars(char*, char*, double, std::chars_format, int precision) crashes for the two maximal int precision values pinskia at gcc dot gnu.org
2022-01-09 22:27 ` pinskia at gcc dot gnu.org
2022-01-10 13:41 ` ppalka at gcc dot gnu.org
2022-01-12 14:10 ` cvs-commit at gcc dot gnu.org
2022-04-12 19:18 ` cvs-commit at gcc dot gnu.org
2022-04-12 19:18 ` ppalka at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).