Declare __warn_memset_zero_len internally for newer gcc [bz #25399]

Message ID 20201103111534.818940-1-siddhesh@sourceware.org
State Superseded
Headers
Series Declare __warn_memset_zero_len internally for newer gcc [bz #25399] |

Commit Message

Siddhesh Poyarekar Nov. 3, 2020, 11:15 a.m. UTC
  The __warn_memset_zero_len symbol, used to issue a linker warning
about zero length memset calls, is included in warning-nop.o only when
glibc is built with an older gcc, which is incorrect.  When a program
calling memset with zero length is built with either gcc < 5.0 or with
clang (which advertises __GNUC__ as 4), it results in a link failure
due to not finding the symbol in libc_nonshared.a.

Fill in this gap by declaring __warn_memset_zero_len for newer gcc as
well so that it is always available in libc_nonshared.a for any
compiler to link against.
---
 debug/warning-nop.c            | 10 ++++++++++
 string/bits/string_fortified.h |  6 ++++--
 2 files changed, 14 insertions(+), 2 deletions(-)
  

Comments

Florian Weimer Nov. 3, 2020, 3:05 p.m. UTC | #1
* Siddhesh Poyarekar via Libc-alpha:

> The __warn_memset_zero_len symbol, used to issue a linker warning
> about zero length memset calls, is included in warning-nop.o only when
> glibc is built with an older gcc, which is incorrect.  When a program
> calling memset with zero length is built with either gcc < 5.0 or with
> clang (which advertises __GNUC__ as 4), it results in a link failure
> due to not finding the symbol in libc_nonshared.a.
>
> Fill in this gap by declaring __warn_memset_zero_len for newer gcc as
> well so that it is always available in libc_nonshared.a for any
> compiler to link against.

Does Clang have its own warning for this?

An alternative would be to drop the warning from the glibc headers
because current compilers do not need it.

Thanks,
Florian
  
Serge Guelton Nov. 3, 2020, 4:04 p.m. UTC | #2
On Tue, Nov 03, 2020 at 04:05:11PM +0100, Florian Weimer wrote:
> * Siddhesh Poyarekar via Libc-alpha:
> 
> > The __warn_memset_zero_len symbol, used to issue a linker warning
> > about zero length memset calls, is included in warning-nop.o only when
> > glibc is built with an older gcc, which is incorrect.  When a program
> > calling memset with zero length is built with either gcc < 5.0 or with
> > clang (which advertises __GNUC__ as 4), it results in a link failure
> > due to not finding the symbol in libc_nonshared.a.
> >
> > Fill in this gap by declaring __warn_memset_zero_len for newer gcc as
> > well so that it is always available in libc_nonshared.a for any
> > compiler to link against.
> 
> Does Clang have its own warning for this?

Clang has -Wmemset-transposed-args. The warning is emitted during smeantic
analysis, catching two patterns: 1. a size argument of 0 and 2. when the
constant argument is a sizeof


> An alternative would be to drop the warning from the glibc headers
> because current compilers do not need it.
> 
> Thanks,
> Florian
> -- 
> Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
> Commercial register: Amtsgericht Muenchen, HRB 153243,
> Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill
>
  
Florian Weimer Nov. 3, 2020, 4:05 p.m. UTC | #3
* Serge Guelton:

> On Tue, Nov 03, 2020 at 04:05:11PM +0100, Florian Weimer wrote:
>> * Siddhesh Poyarekar via Libc-alpha:
>> 
>> > The __warn_memset_zero_len symbol, used to issue a linker warning
>> > about zero length memset calls, is included in warning-nop.o only when
>> > glibc is built with an older gcc, which is incorrect.  When a program
>> > calling memset with zero length is built with either gcc < 5.0 or with
>> > clang (which advertises __GNUC__ as 4), it results in a link failure
>> > due to not finding the symbol in libc_nonshared.a.
>> >
>> > Fill in this gap by declaring __warn_memset_zero_len for newer gcc as
>> > well so that it is always available in libc_nonshared.a for any
>> > compiler to link against.
>> 
>> Does Clang have its own warning for this?
>
> Clang has -Wmemset-transposed-args. The warning is emitted during smeantic
> analysis, catching two patterns: 1. a size argument of 0 and 2. when the
> constant argument is a sizeof

Is it enabled by -Wall?

Thanks,
Florian
  
Serge Guelton Nov. 3, 2020, 4:46 p.m. UTC | #4
On Tue, Nov 03, 2020 at 05:05:54PM +0100, Florian Weimer wrote:
> * Serge Guelton:
> 
> > On Tue, Nov 03, 2020 at 04:05:11PM +0100, Florian Weimer wrote:
> >> * Siddhesh Poyarekar via Libc-alpha:
> >> 
> >> > The __warn_memset_zero_len symbol, used to issue a linker warning
> >> > about zero length memset calls, is included in warning-nop.o only when
> >> > glibc is built with an older gcc, which is incorrect.  When a program
> >> > calling memset with zero length is built with either gcc < 5.0 or with
> >> > clang (which advertises __GNUC__ as 4), it results in a link failure
> >> > due to not finding the symbol in libc_nonshared.a.
> >> >
> >> > Fill in this gap by declaring __warn_memset_zero_len for newer gcc as
> >> > well so that it is always available in libc_nonshared.a for any
> >> > compiler to link against.
> >> 
> >> Does Clang have its own warning for this?
> >
> > Clang has -Wmemset-transposed-args. The warning is emitted during smeantic
> > analysis, catching two patterns: 1. a size argument of 0 and 2. when the
> > constant argument is a sizeof
> 
> Is it enabled by -Wall?

Yes
  
Siddhesh Poyarekar Nov. 3, 2020, 4:50 p.m. UTC | #5
On 11/3/20 8:35 PM, Florian Weimer via Libc-alpha wrote:
> An alternative would be to drop the warning from the glibc headers
> because current compilers do not need it.

This would mean dropping this check for situations where one is building 
against a newer glibc with gcc < 5.0.  I don't know how common this use 
case is.

Siddhesh
  
Florian Weimer Nov. 3, 2020, 4:59 p.m. UTC | #6
* Serge Guelton:

> On Tue, Nov 03, 2020 at 05:05:54PM +0100, Florian Weimer wrote:
>> * Serge Guelton:
>> 
>> > On Tue, Nov 03, 2020 at 04:05:11PM +0100, Florian Weimer wrote:
>> >> * Siddhesh Poyarekar via Libc-alpha:
>> >> 
>> >> > The __warn_memset_zero_len symbol, used to issue a linker warning
>> >> > about zero length memset calls, is included in warning-nop.o only when
>> >> > glibc is built with an older gcc, which is incorrect.  When a program
>> >> > calling memset with zero length is built with either gcc < 5.0 or with
>> >> > clang (which advertises __GNUC__ as 4), it results in a link failure
>> >> > due to not finding the symbol in libc_nonshared.a.
>> >> >
>> >> > Fill in this gap by declaring __warn_memset_zero_len for newer gcc as
>> >> > well so that it is always available in libc_nonshared.a for any
>> >> > compiler to link against.
>> >> 
>> >> Does Clang have its own warning for this?
>> >
>> > Clang has -Wmemset-transposed-args. The warning is emitted during smeantic
>> > analysis, catching two patterns: 1. a size argument of 0 and 2. when the
>> > constant argument is a sizeof
>> 
>> Is it enabled by -Wall?
>
> Yes

Then I don't think we need the manual warning in the glibc headers.

Thanks,
Florian
  

Patch

diff --git a/debug/warning-nop.c b/debug/warning-nop.c
index 4ab7e182b7..8df7b0d098 100644
--- a/debug/warning-nop.c
+++ b/debug/warning-nop.c
@@ -68,3 +68,13 @@  nop (void)
 #define __builtin_object_size(bos, level) 0
 
 #include <string.h>
+
+/* The public string_fortify.h header (included via string.h above) declares
+   __warn_memset_zero_len only when it is built with GCC < 5.0 or a non-gcc
+   compiler where compiler support for zero length memset warning may not be
+   available.  Internally however we need to ensure that __warn_memset_zero_len
+   is always available when using older gcc or other compilers to link against
+   glibc.  */
+#if __GNUC_PREREQ (5,0)
+__warndecl (__warn_memset_zero_len, __WARN_MEMSET_ZERO_LEN_MSG);
+#endif
diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h
index 309d0f39b2..be88291f62 100644
--- a/string/bits/string_fortified.h
+++ b/string/bits/string_fortified.h
@@ -22,9 +22,11 @@ 
 # error "Never use <bits/string_fortified.h> directly; include <string.h> instead."
 #endif
 
+#define __WARN_MEMSET_ZERO_LEN_MSG \
+  "memset used with constant zero length parameter; this could be due to transposed parameters"
+
 #if !__GNUC_PREREQ (5,0)
-__warndecl (__warn_memset_zero_len,
-	    "memset used with constant zero length parameter; this could be due to transposed parameters");
+__warndecl (__warn_memset_zero_len, __WARN_MEMSET_ZERO_LEN_MSG);
 #endif
 
 __fortify_function void *