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

            Bug ID: 106709
           Summary: GCC incorrectly warns about stringop-overread
           Product: gcc
           Version: 12.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ljrk at ljrk dot org
  Target Milestone: ---

Created attachment 53489
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53489&action=edit
Minimal Working/Reproducing Example

GCC incorrectly warns with default flags and optimization level -O2 about a
number of buffer overruns, in this example from `libmdigest` as part of the
schilytools in a call to `SHA1Update` at
https://codeberg.org/schilytools/schilytools/src/branch/master/libmdigest/sha1.c#L251:


                ==> COMPILING "OBJ/x86_64-linux-gcc/sha1.o"
        In function 'SHA1Update',
            inlined from 'SHA1Pad' at sha1.c:251:2:
        sha1.c:228:25: warning: 'SHA1Transform' reading 64 bytes from a region
of size 1 [-Wstringop-overread]
          228 |                         SHA1Transform(context->state, (UInt8_t
*)&data[i]);
              |                        
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        sha1.c:228:25: note: referencing argument 2 of type 'const uint8_t[64]'
{aka 'const unsigned char[64]'}




In this example we have the following code snippet in `SHA1Pad`:


                SHA1Update(context, /* data: */ (UInt8_t *)"\200", /* len: */
1);



with the inlined update function being: 


                j = (size_t)((context->count[0] >> 3) & 63);
                /* ... */
                if ((j + len) > 63) {
                        /* ... */ i = 64-j /*...*/;
                        SHA1Transform(context->state, context->buffer);
                        for (; i + 63 < len; i += 64)
                                SHA1Transform(context->state, (UInt8_t
*)&data[i]);
                        j = 0;
                } else /* ... */



Depending on the value of `count[0]`, both `j` may be up to 63 (if `count[0]`
is 0x3f00 or more).  Only in this case, with `len = 1` from `SHA1Update`, we
would enter this code block and correctly copy `i = 64-63 = 1` bytes from the 1
byte data buffer.  The loop would start with `i+63 = 1+63 < len = 1` and thus
not call `SHA1Transform` in any case.

Setting `j = 63` directly silences the warning, so it seems like GCC can't keep
track of `j <= 63`.

I've attached a minimized mwe.c as well:

        $ gcc -c -O2 -o mwe.o mwe.c
        In function ‘mwe2’,
            inlined from ‘mwe’ at mwe.c:17:2:
        mwe.c:11:25: warning: ‘mwe3’ reading 64 bytes from a region of size 1
[-Wstringop-overread]
           11 |                         mwe3((unsigned char*)&data[i]);
              |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        mwe.c:11:25: note: referencing argument 1 of type ‘const unsigned
char[64]’
        mwe.c: In function ‘mwe’:
        mwe.c:3:13: note: in a call to function ‘mwe3’
            3 | extern void mwe3(const unsigned char buffer[64]);
              |             ^~~~
        $ gcc -v
        Using built-in specs.
        COLLECT_GCC=gcc
        COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/lto-wrapper
        Target: x86_64-pc-linux-gnu
        Configured with: /build/gcc/src/gcc/configure
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --enable-bootstrap
--prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/
--with-build-config=bootstrap-lto --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-libstdcxx-backtrace --enable-link-serialization=1
--enable-linker-build-id --enable-lto --enable-multilib --enable-plugin
--enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch
--disable-werror
        Thread model: posix
        Supported LTO compression algorithms: zlib zstd
        gcc version 12.2.0 (GCC) 


It seems like this bug is related to
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105424 but I'm not sure.  If so,
feel free to close it.

Thanks for maintaining this great piece of software!

Reply via email to