[v2] Fix stringop-overflow warning in bug-regex19.c.

Message ID 20210517141936.4122773-1-stli@linux.ibm.com
State New
Headers show
Series
  • [v2] Fix stringop-overflow warning in bug-regex19.c.
Related show

Commit Message

Noah Goldstein via Libc-alpha May 17, 2021, 2:19 p.m.
Starting with commit
26492c0a14966c32c43cd6ca1d0dca5e62c6cfef
"Annotate additional APIs with GCC attribute access.",
gcc emits this warning on s390x:
In function ‘do_one_test’,
    inlined from ‘do_mb_tests’ at bug-regex19.c:385:11:
bug-regex19.c:271:9: error: ‘re_search’ specified size 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Werror=stringop-overflow=]
  271 |   res = re_search (&regbuf, test->string, strlen (test->string),
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  272 |      test->start, strlen (test->string) - test->start, NULL);
      |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../include/regex.h:2,
                 from bug-regex19.c:22:
bug-regex19.c: In function ‘do_mb_tests’:
../posix/regex.h:554:17: note: in a call to function ‘re_search’ declared with attribute ‘read_only (2, 3)’
  554 | extern regoff_t re_search (struct re_pattern_buffer *__buffer,
      |                 ^~~~~~~~~
...

The function do_one_test is inlined into do_mb_tests on s390x (at least with
gcc 10).  If do_one_test is marked with __attribute__ ((noinline)), there are
no warnings on s390x. If do_one_test is marked with
__attribute__ ((always_inline)), there are the same warnings on x86_64.

test->string points to a variable length array on stack of do_mb_tests
and the content is generated based on the passed test struct.

According to Martin Sebor, this is a false positive caused by the same bug as
the one in nss/makedb.c.  It's fixed in GCC 11 and will also be available in
the next GCC 10.4 release.
---
 posix/bug-regex19.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

-- 
2.30.2

Comments

Noah Goldstein via Libc-alpha May 18, 2021, 8:09 a.m. | #1
On 17/05/2021 16:19, Stefan Liebler wrote:
> Starting with commit

> 26492c0a14966c32c43cd6ca1d0dca5e62c6cfef

> "Annotate additional APIs with GCC attribute access.",

> gcc emits this warning on s390x:

> In function ‘do_one_test’,

>     inlined from ‘do_mb_tests’ at bug-regex19.c:385:11:

> bug-regex19.c:271:9: error: ‘re_search’ specified size 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Werror=stringop-overflow=]

>   271 |   res = re_search (&regbuf, test->string, strlen (test->string),

>       |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

>   272 |      test->start, strlen (test->string) - test->start, NULL);

>       |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

> In file included from ../include/regex.h:2,

>                  from bug-regex19.c:22:

> bug-regex19.c: In function ‘do_mb_tests’:

> ../posix/regex.h:554:17: note: in a call to function ‘re_search’ declared with attribute ‘read_only (2, 3)’

>   554 | extern regoff_t re_search (struct re_pattern_buffer *__buffer,

>       |                 ^~~~~~~~~

> ...

> 

> The function do_one_test is inlined into do_mb_tests on s390x (at least with

> gcc 10).  If do_one_test is marked with __attribute__ ((noinline)), there are

> no warnings on s390x. If do_one_test is marked with

> __attribute__ ((always_inline)), there are the same warnings on x86_64.

> 

> test->string points to a variable length array on stack of do_mb_tests

> and the content is generated based on the passed test struct.

> 

> According to Martin Sebor, this is a false positive caused by the same bug as

> the one in nss/makedb.c.  It's fixed in GCC 11 and will also be available in

> the next GCC 10.4 release.

> ---

>  posix/bug-regex19.c | 19 +++++++++++++++++++

>  1 file changed, 19 insertions(+)

> 

> diff --git a/posix/bug-regex19.c b/posix/bug-regex19.c

> index 9bbffb17e3..b3fee0a730 100644

> --- a/posix/bug-regex19.c

> +++ b/posix/bug-regex19.c

> @@ -24,6 +24,7 @@

>  #include <stdlib.h>

>  #include <string.h>

>  #include <locale.h>

> +#include <libc-diag.h>

>  

>  #define BRE RE_SYNTAX_POSIX_BASIC

>  #define ERE RE_SYNTAX_POSIX_EXTENDED

> @@ -268,8 +269,17 @@ do_one_test (const struct test_s *test, const char *fail)

>        return 1;

>      }

>  

> +#if __GNUC_PREREQ (10, 0) && !__GNUC_PREREQ (11, 0)

> +  DIAG_PUSH_NEEDS_COMMENT;

> +  /* Avoid GCC 10 false positive warning: specified size exceeds maximum

> +     object size.  */

> +  DIAG_IGNORE_NEEDS_COMMENT (10, "-Wstringop-overflow");

> +#endif

>    res = re_search (&regbuf, test->string, strlen (test->string),

>  		   test->start, strlen (test->string) - test->start, NULL);

> +#if __GNUC_PREREQ (10, 0) && !__GNUC_PREREQ (11, 0)

> +  DIAG_POP_NEEDS_COMMENT;

> +#endif

>    if (res != test->res)

>      {

>        printf ("%sre_search \"%s\" \"%s\" failed: %d (expected %d)\n",

> @@ -280,8 +290,17 @@ do_one_test (const struct test_s *test, const char *fail)

>  

>    if (test->res > 0 && test->start == 0)

>      {

> +#if __GNUC_PREREQ (10, 0) && !__GNUC_PREREQ (11, 0)

> +  DIAG_PUSH_NEEDS_COMMENT;

> +  /* Avoid GCC 10 false positive warning: specified size exceeds maximum

> +     object size.  */

> +  DIAG_IGNORE_NEEDS_COMMENT (10, "-Wstringop-overflow");

> +#endif

>        res = re_search (&regbuf, test->string, strlen (test->string),

>  		       test->res, strlen (test->string) - test->res, NULL);

> +#if __GNUC_PREREQ (10, 0) && !__GNUC_PREREQ (11, 0)

> +  DIAG_POP_NEEDS_COMMENT;

> +#endif

>        if (res != test->res)

>  	{

>  	  printf ("%sre_search from expected \"%s\" \"%s\" failed: %d (expected %d)\n",

> 

Committed after response from Martin:
https://sourceware.org/pipermail/libc-alpha/2021-May/126416.html

Thanks,
Stefan

Patch

diff --git a/posix/bug-regex19.c b/posix/bug-regex19.c
index 9bbffb17e3..b3fee0a730 100644
--- a/posix/bug-regex19.c
+++ b/posix/bug-regex19.c
@@ -24,6 +24,7 @@ 
 #include <stdlib.h>
 #include <string.h>
 #include <locale.h>
+#include <libc-diag.h>
 
 #define BRE RE_SYNTAX_POSIX_BASIC
 #define ERE RE_SYNTAX_POSIX_EXTENDED
@@ -268,8 +269,17 @@  do_one_test (const struct test_s *test, const char *fail)
       return 1;
     }
 
+#if __GNUC_PREREQ (10, 0) && !__GNUC_PREREQ (11, 0)
+  DIAG_PUSH_NEEDS_COMMENT;
+  /* Avoid GCC 10 false positive warning: specified size exceeds maximum
+     object size.  */
+  DIAG_IGNORE_NEEDS_COMMENT (10, "-Wstringop-overflow");
+#endif
   res = re_search (&regbuf, test->string, strlen (test->string),
 		   test->start, strlen (test->string) - test->start, NULL);
+#if __GNUC_PREREQ (10, 0) && !__GNUC_PREREQ (11, 0)
+  DIAG_POP_NEEDS_COMMENT;
+#endif
   if (res != test->res)
     {
       printf ("%sre_search \"%s\" \"%s\" failed: %d (expected %d)\n",
@@ -280,8 +290,17 @@  do_one_test (const struct test_s *test, const char *fail)
 
   if (test->res > 0 && test->start == 0)
     {
+#if __GNUC_PREREQ (10, 0) && !__GNUC_PREREQ (11, 0)
+  DIAG_PUSH_NEEDS_COMMENT;
+  /* Avoid GCC 10 false positive warning: specified size exceeds maximum
+     object size.  */
+  DIAG_IGNORE_NEEDS_COMMENT (10, "-Wstringop-overflow");
+#endif
       res = re_search (&regbuf, test->string, strlen (test->string),
 		       test->res, strlen (test->string) - test->res, NULL);
+#if __GNUC_PREREQ (10, 0) && !__GNUC_PREREQ (11, 0)
+  DIAG_POP_NEEDS_COMMENT;
+#endif
       if (res != test->res)
 	{
 	  printf ("%sre_search from expected \"%s\" \"%s\" failed: %d (expected %d)\n",