Bug 88780 - [10/11/12/13 Regression] bogus -Wstringop-truncation for copying as many bytes from a string as its length
Summary: [10/11/12/13 Regression] bogus -Wstringop-truncation for copying as many byte...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 9.0
: P2 normal
Target Milestone: 10.5
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wstringop-truncation
  Show dependency treegraph
 
Reported: 2019-01-09 23:33 UTC by Martin Sebor
Modified: 2022-06-28 10:36 UTC (History)
8 users (show)

See Also:
Host:
Target:
Build:
Known to work: 7.3.0
Known to fail: 8.2.0, 9.0
Last reconfirmed: 2019-01-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2019-01-09 23:33:41 UTC
In the test case below the assignment suppression logic where we look for the next statement to see if it assigns a nul to the destination is never entered, resulting in a false positive.  I don't know/remember why it isn't used here, but using it doesn't seem that it would do the right thing here anyway: it would find the addition that computes pointer to use for the assignment:

  _3 = buf_8(D) + namelen_6;

The logic isn't robust enough to track pointer arithmetic when looking for the assignment.  To avoid the false positive the logic needs to be enhanced to track the destination across pointer arithmetic.

$ cat u.c && gcc -O2 -S -Wall u.c
typedef __SIZE_TYPE__ size_t;

void f (char *d, const char *s, size_t n)
{
  size_t len = __builtin_strlen (s);
  if (n < len + 1) return;

  __builtin_strncpy (d, s, len);
  d[len] = '\0';
}

u.c: In function ‘f’:
u.c:3:6: note: finish_function
    3 | void f (char *d, const char *s, size_t n)
      |      ^
u.c:8:3: warning: ‘__builtin_strncpy’ output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
    8 |   __builtin_strncpy (d, s, len);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
u.c:5:16: note: length computed here
    5 |   size_t len = __builtin_strlen (s);
      |                ^~~~~~~~~~~~~~~~~~~~


The test case was isolated from the following function:

/* Extract the common name of 'cert' into 'buf'. */
static int get_common_name(CERTCertificate *cert, char *buf, size_t bufsiz)
{
     /* FIXME --- truncating names with spaces */
     size_t namelen;
     char *name = CERT_GetCommonName(&cert->subject);

     if (!name) return -1;

     namelen = strlen(name);
     if (bufsiz < namelen+1) return -1;

     strncpy(buf, name, namelen);
     buf[namelen] = '\0';
     PORT_Free(name);

     return 0;
} 

and the following warning during a Fedora build with GCC 9:

In file included from /usr/include/string.h:494,
                 from /usr/include/nss3/secport.h:45,
                 from /usr/include/nss3/seccomon.h:27,
                 from /usr/include/nss3/nss.h:34,
                 from certwatch.c:77:
In function 'strncpy',
     inlined from 'get_common_name' at certwatch.c:249:5,
     inlined from 'check_cert' at certwatch.c:289:9,
     inlined from 'main' at certwatch.c:387:12:
/usr/include/bits/string_fortified.h:106:10: error: '__builtin___strncpy_chk' output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
   106 |   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
       |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
certwatch.c: In function 'main':
certwatch.c:246:15: note: length computed here
   246 |     namelen = strlen(name);
       |               ^~~~~~~~~~~~
cc1: all warnings being treated as errors
Comment 1 Martin Sebor 2019-01-17 01:56:43 UTC
The Wstringop-truncation warning is new in GCC 8 and is not issued by GCC 7 so I'm marking this a regression.
Comment 2 Jakub Jelinek 2019-02-22 15:21:18 UTC
GCC 8.3 has been released.
Comment 3 Jakub Jelinek 2020-03-04 09:49:47 UTC
GCC 8.4.0 has been released, adjusting target milestone.
Comment 4 Pei JIA 2020-04-30 13:12:32 UTC
gcc 9.3 in Ubuntu 20.04, this bug comes back????
Comment 5 Arjan van Vught 2020-05-26 13:24:29 UTC
(In reply to Pei JIA from comment #4)
> gcc 9.3 in Ubuntu 20.04, this bug comes back????

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04 LTS
Release:        20.04
Codename:       focal

gcc --version
gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

This code:
	strncpy(m_SourceName, pSourceName, E131_SOURCE_NAME_LENGTH - 1);
	m_SourceName[E131_SOURCE_NAME_LENGTH - 1] = '\0';

gives:

g++ -DNDEBUG -D_TIME_STAMP_YEAR_=2020 -D_TIME_STAMP_MONTH_=5 -D_TIME_STAMP_DAY_=26  -I./include -I../lib-hal/include -I../lib-debug/include -I../lib-lightset/include -I../lib-properties/include -I../lib-hal/include -I../lib-network/include -O2 -Wall -Werror -Wextra -Wpedantic -Wunused -Wsign-conversion  -fno-rtti -fno-exceptions -fno-unwind-tables -Wnon-virtual-dtor -Wuseless-cast -Wold-style-cast -std=c++11 -c src/e131bridge.cpp -o build_linux/src/e131bridge.o
In file included from /usr/include/string.h:495,
                 from src/e131bridge.cpp:29:
In function ‘char* strncpy(char*, const char*, size_t)’,
    inlined from ‘void E131Bridge::SetSourceName(const char*)’ at src/e131bridge.cpp:159:9,
    inlined from ‘E131Bridge::E131Bridge()’ at src/e131bridge.cpp:88:15,
    inlined from ‘E131Bridge::E131Bridge()’ at src/e131bridge.cpp:51:1:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:34: error: ‘char* __builtin_strncpy(char*, const char*, long unsigned int)’ output may be truncated copying 63 bytes from a string of length 63 [-Werror=stringop-truncation]
  106 |   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
      |          ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Workaround:

#if (__GNUC__ > 8)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wstringop-truncation"
#endif
	strncpy(m_SourceName, pSourceName, E131_SOURCE_NAME_LENGTH - 1);
	m_SourceName[E131_SOURCE_NAME_LENGTH - 1] = '\0';
#if (__GNUC__ > 8)
# pragma GCC diagnostic pop
#endif
Comment 6 Marietto 2020-08-18 15:57:52 UTC
Hello.

I'm a xen user. I'm trying to Build Qemu & Xen for XenGT on Ubuntu 20.04 following this tutorial :

https://github.com/intel/gvt-linux/wiki/GVTg_Setup_Guide#332-build-qemu--xen-for-xengt

because I want to share the integrated GPU with a xen VM.

The main hardware components of my PC are the following :

CPU I9-9900k

Intel Corporation UHD Graphics 630 (Desktop 9 Series) (rev 02)

IVIDIA Corporation TU102 [GeForce RTX 2080 Ti] (rev a1)

The compilation gave no errors until this point :

root@ziomario-z390aoruspro:/etc/xen/igvtg-xen# make install-tools

......

make libs
make[5]: ingresso nella directory «/etc/xen/igvtg-xen/tools/libxc»
rm -f _paths.h.tmp; echo "#define sbindir "/usr/sbin"" >>_paths.h.tmp; echo "#define bindir "/usr/bin"" >>_paths.h.tmp; echo "#define LIBEXEC "/usr/lib/xen"" >>_paths.h.tmp; echo "#define LIBEXEC_BIN "/usr/lib/xen/bin"" >>_paths.h.tmp; echo "#define libdir "/usr/lib"" >>_paths.h.tmp; echo "#define SHAREDIR "/usr/share"" >>_paths.h.tmp; echo "#define XENFIRMWAREDIR "/usr/lib/xen/boot"" >>_paths.h.tmp; echo "#define XEN_CONFIG_DIR "/etc/xen"" >>_paths.h.tmp; echo "#define XEN_SCRIPT_DIR "/etc/xen/scripts"" >>_paths.h.tmp; echo "#define XEN_LOCK_DIR "/var/lock"" >>_paths.h.tmp; echo "#define XEN_RUN_DIR "/var/run/xen"" >>_paths.h.tmp; echo "#define XEN_PAGING_DIR "/var/lib/xen/xenpaging"" >>_paths.h.tmp; echo "#define XEN_DUMP_DIR "/var/lib/xen/dump"" >>_paths.h.tmp; echo "#define XEN_LOG_DIR "/var/log/xen"" >>_paths.h.tmp; echo "#define XEN_LIB_DIR "/var/lib/xen"" >>_paths.h.tmp; echo "#define XEN_RUN_STORED "/var/run/xenstored"" >>_paths.h.tmp; if ! cmp -s _paths.h.tmp paths.h; then mv -f paths.h.tmp paths.h; else rm -f paths.h.tmp; fi
gcc -m64 -DBUILD_ID -fno-strict-aliasing -std=gnu99 -Wall -Wstrict-prototypes -Wdeclaration-after-statement -Wno-unused-but-set-variable -Wno-unused-local-typedefs -O2 -fomit-frame-pointer -D__XEN_INTERFACE_VERSION=XEN_LATEST_INTERFACE_VERSION -MMD -MF .xc_pm.o.d -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_GNU_SOURCE -I../../xen/common/libelf -Werror -Wmissing-prototypes -I. -I./include -I/etc/xen/igvtg-xen/tools/libxc/../../tools/include -D__XEN_TOOLS -pthread -I/etc/xen/igvtg-xen/tools/libxc/../../tools/libs/toollog/include -I/etc/xen/igvtg-xen/tools/libxc/../../tools/include -I/etc/xen/igvtg-xen/tools/libxc/../../tools/libs/evtchn/include -I/etc/xen/igvtg-xen/tools/libxc/../../tools/include -I/etc/xen/igvtg-xen/tools/libxc/../../tools/libs/devicemodel/include -I/etc/xen/igvtg-xen/tools/libxc/../../tools/include -include /etc/xen/igvtg-xen/tools/libxc/../../tools/config.h -I/etc/xen/igvtg-xen/tools/libxc/../../tools/libs/call/include -I/etc/xen/igvtg-xen/tools/libxc/../../tools/include -I/etc/xen/igvtg-xen/tools/libxc/../../tools/libs/foreignmemory/include -I/etc/xen/igvtg-xen/tools/libxc/../../tools/include -I/etc/xen/igvtg-xen/tools/libxc/../../tools/libs/gnttab/include -I/etc/xen/igvtg-xen/tools/libxc/../../tools/include -c -o xc_pm.o xc_pm.c
In file included from /usr/include/string.h:495,
from xc_private.h:24,
from xc_pm.c:22:
In function ‘strncpy’,
inlined from ‘xc_set_cpufreq_gov’ at xc_pm.c:308:5:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:10: error: ‘__builtin_strncpy’ specified bound 16 equals destination size [-Werror=stringop-truncation]
106 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[5]: *** [/etc/xen/igvtg-xen/tools/libxc/../../tools/Rules.mk:222: xc_pm.o] Errore 1
make[5]: uscita dalla directory «/etc/xen/igvtg-xen/tools/libxc»
make[4]: *** [Makefile:184: build] Errore 2
make[4]: uscita dalla directory «/etc/xen/igvtg-xen/tools/libxc»
make[3]: *** [/etc/xen/igvtg-xen/tools/../tools/Rules.mk:246: subdir-install-libxc] Errore 2
make[3]: uscita dalla directory «/etc/xen/igvtg-xen/tools»
make[2]: *** [/etc/xen/igvtg-xen/tools/../tools/Rules.mk:241: subdirs-install] Errore 2
make[2]: uscita dalla directory «/etc/xen/igvtg-xen/tools»
make[1]: *** [Makefile:74: install] Errore 2
make[1]: uscita dalla directory «/etc/xen/igvtg-xen/tools»
make: *** [Makefile:127: install-tools] Errore 2

how can I fix it ?
Comment 7 Martin Sebor 2020-08-18 17:26:00 UTC
(In reply to Marietto from comment #6)
...
> In function ‘strncpy’,
> inlined from ‘xc_set_cpufreq_gov’ at xc_pm.c:308:5:
> /usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:10: error:
> ‘__builtin_strncpy’ specified bound 16 equals destination size
> [-Werror=stringop-truncation]
> 106 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This instance of the warning is most likely unrelated to the one reported in comment #0 (to tell for sure we'd need a test case to reproduce it).  It indicates that strncpy is being called with the third argument set to the size of the destination array, which leaves the destination unterminated unless the source string is shorter.  The following articles describe the problem and the suggested solutions in detail:

https://developers.redhat.com/blog/2018/05/24/detecting-string-truncation-with-gcc-8/
https://us-cert.cisa.gov/bsi/articles/knowledge/coding-practices/strncpy-and-strncat
Comment 8 Marietto 2020-08-24 19:52:18 UTC
https://bugs.launchpad.net/ubuntu/+source/gcc-9/+bug/1892475

Il giorno mar 18 ago 2020 alle ore 19:26 msebor at gcc dot gnu.org <
gcc-bugzilla@gcc.gnu.org> ha scritto:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88780
>
> --- Comment #7 from Martin Sebor <msebor at gcc dot gnu.org> ---
> (In reply to Marietto from comment #6)
> ...
> > In function ‘strncpy’,
> > inlined from ‘xc_set_cpufreq_gov’ at xc_pm.c:308:5:
> > /usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:10: error:
> > ‘__builtin_strncpy’ specified bound 16 equals destination size
> > [-Werror=stringop-truncation]
> > 106 | return __builtin___strncpy_chk (__dest, __src, __len, __bos
> (__dest));
> > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> This instance of the warning is most likely unrelated to the one reported
> in
> comment #0 (to tell for sure we'd need a test case to reproduce it).  It
> indicates that strncpy is being called with the third argument set to the
> size
> of the destination array, which leaves the destination unterminated unless
> the
> source string is shorter.  The following articles describe the problem and
> the
> suggested solutions in detail:
>
>
> https://developers.redhat.com/blog/2018/05/24/detecting-string-truncation-with-gcc-8/
>
> https://us-cert.cisa.gov/bsi/articles/knowledge/coding-practices/strncpy-and-strncat
>
> --
> You are receiving this mail because:
> You are on the CC list for the bug.
Comment 9 Jakub Jelinek 2021-05-14 09:51:07 UTC
GCC 8 branch is being closed.
Comment 10 Richard Biener 2021-06-01 08:12:45 UTC
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
Comment 11 Martin Sebor 2022-03-17 20:02:55 UTC
I'm no longer working on this.
Comment 12 Richard Biener 2022-05-27 09:40:01 UTC
GCC 9 branch is being closed
Comment 13 Jakub Jelinek 2022-06-28 10:36:25 UTC
GCC 10.4 is being released, retargeting bugs to GCC 10.5.