Re: [pcre-dev] PCRE 8.42 Release Candidate

Top Page
Delete this message
Author: Petr Pisar
Date:  
To: pcre-dev
Subject: Re: [pcre-dev] PCRE 8.42 Release Candidate
On Tue, Feb 20, 2018 at 04:36:24PM +0000, ph10@??? wrote:
> I've just put a Release Candidate for 8.42 in the usual place:
>

I tested it successfully on GNU/Linux on these platforms:

aarch64
armv7hl
i686
ppc64be
ppc64le
s390x
x86_64

Please note gcc-8 with glibc-2.27 emmits this warning:

gcc -DHAVE_CONFIG_H -I.      -pthread -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -mcet -fcf-protection -c -o pcregrep-pcregrep.o `test -f 'pcregrep.c' || echo './'`pcregrep.c
pcregrep.c: In function 'main':
pcregrep.c:2767:31: warning: '__builtin___sprintf_chk' may write a terminating nul past the end of the destination [-Wformat-overflow=]
         sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1);
                               ^
In file included from /usr/include/stdio.h:862,
                 from pcregrep.c:52:
/usr/include/bits/stdio2.h:33:10: note: '__builtin___sprintf_chk' output between 1 and 2147483669 bytes into a destination of size 24
   return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       __bos (__s), __fmt, __va_arg_pack ());
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


This warning is not new for 8.42-RC1. It happens also for 8.41. GCC and glibc
recieved some fortification features and this is the result.

If I understand PCRE code correctly, the warning is a false alarm because it
parses constant strings (pcretrep options) and builds a new string from them.
And all the buffer sizes are large enough. The compiler seems to be unable to
infer "fulllen - baselen - 2" value correctly.

An attached patch makes the warning gone.

-- Petr
From ed53a8d6d531a5427ce9385b7c15d65f59ac8e0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@???>
Date: Fri, 23 Feb 2018 10:28:22 +0100
Subject: [PATCH] Silent a GCC 8 warning about formatting a pcregrep long
option
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch silents this warning:

pcregrep.c:2767:31: warning: '__builtin___sprintf_chk' may write a terminating nul past the end of the destination [-Wformat-overflow=]
         sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1);
                               ^
In file included from /usr/include/stdio.h:862,
                 from pcregrep.c:52:
/usr/include/bits/stdio2.h:33:10: note: '__builtin___sprintf_chk' output between 1 and 2147483669 bytes into a destination of size 24
   return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       __bos (__s), __fmt, __va_arg_pack ());
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Signed-off-by: Petr Písař <ppisar@???>
---
pcregrep.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/pcregrep.c b/pcregrep.c
index 69ba85a..a46e7e2 100644
--- a/pcregrep.c
+++ b/pcregrep.c
@@ -2764,7 +2764,15 @@ for (i = 1; i < argc; i++)
           (int)strlen(arg) : (int)(argequals - arg);


         sprintf(buff1, "%.*s", baselen, op->long_name);
-        sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1);
+        if (sizeof(buff2)/sizeof(*buff2) <=
+            snprintf(buff2, sizeof(buff2)/sizeof(*buff2),
+              "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1))
+          {
+          fprintf(stderr,
+            "pcregrep: Buffer overflow when parsing %s option\n",
+            op->long_name);
+          pcregrep_exit(2);
+          }


         if (strncmp(arg, buff1, arglen) == 0 ||
            strncmp(arg, buff2, arglen) == 0)
-- 
2.13.6