mbox series

[v2,0/3] Fix strncpy() warnings for GCC8 new -Wstringop-truncation

Message ID 20181218110333.22558-1-philmd@redhat.com
Headers show
Series Fix strncpy() warnings for GCC8 new -Wstringop-truncation | expand

Message

Philippe Mathieu-Daudé Dec. 18, 2018, 11:03 a.m. UTC
GCC 8 new warning prevents builds to success since quite some time.
First report on the mailing list is in July 2018:
https://lists.gnu.org/archive/html/qemu-devel/2018-07/msg03723.html

Various intents has been sent to fix this:
- Incorrectly using g_strlcpy()
  https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg03705.html
  https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg03706.html
- Using assert() and strpadcpy()
  https://lists.gnu.org/archive/html/qemu-devel/2018-11/msg03938.html
- Use #pragma GCC diagnostic ignored "-Wstringop-truncation"
  https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html
- adding an inline wrapper with said pragma in there
  https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html
- -Wno-stringop-truncation is the makefile
  https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html

This series replace the strncpy() calls by strpadcpy() which seemed
to me the saniest option.

Regards,

Phil.

Marc-André Lureau (1):
  hw/acpi: Replace strncpy() by strpadcpy(pad='\0')

Philippe Mathieu-Daudé (2):
  block/sheepdog: Replace strncpy() by strpadcpy(pad='\0')
  migration: Replace strncpy() by strpadcpy(pad='\0')

 block/sheepdog.c         |  6 +++---
 hw/acpi/aml-build.c      |  6 ++++--
 hw/acpi/core.c           | 13 +++++++------
 migration/global_state.c |  4 ++--
 4 files changed, 16 insertions(+), 13 deletions(-)

Comments

Michael S. Tsirkin Dec. 18, 2018, 2:31 p.m. UTC | #1
On Tue, Dec 18, 2018 at 12:03:30PM +0100, Philippe Mathieu-Daudé wrote:
> GCC 8 new warning prevents builds to success since quite some time.
> First report on the mailing list is in July 2018:
> https://lists.gnu.org/archive/html/qemu-devel/2018-07/msg03723.html
> 
> Various intents has been sent to fix this:
> - Incorrectly using g_strlcpy()
>   https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg03705.html
>   https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg03706.html
> - Using assert() and strpadcpy()
>   https://lists.gnu.org/archive/html/qemu-devel/2018-11/msg03938.html
> - Use #pragma GCC diagnostic ignored "-Wstringop-truncation"
>   https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html
> - adding an inline wrapper with said pragma in there
>   https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html
> - -Wno-stringop-truncation is the makefile
>   https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html
> 
> This series replace the strncpy() calls by strpadcpy() which seemed
> to me the saniest option.
> 
> Regards,
> 
> Phil.

Do you happen to know why does it build fine with
Gcc 8.2.1?

Reading the GCC manual it seems that
there is a "nostring" attribute that means
"might not be 0 terminated".
I think we should switch to that which fixes the warning
but also warns if someone tries to misuse these
as C-strings.

Seems to be a better option, does it not?


> Marc-André Lureau (1):
>   hw/acpi: Replace strncpy() by strpadcpy(pad='\0')
> 
> Philippe Mathieu-Daudé (2):
>   block/sheepdog: Replace strncpy() by strpadcpy(pad='\0')
>   migration: Replace strncpy() by strpadcpy(pad='\0')
> 
>  block/sheepdog.c         |  6 +++---
>  hw/acpi/aml-build.c      |  6 ++++--
>  hw/acpi/core.c           | 13 +++++++------
>  migration/global_state.c |  4 ++--
>  4 files changed, 16 insertions(+), 13 deletions(-)
> 
> -- 
> 2.17.2
Daniel Berrange Dec. 18, 2018, 2:36 p.m. UTC | #2
On Tue, Dec 18, 2018 at 09:31:00AM -0500, Michael S. Tsirkin wrote:
> On Tue, Dec 18, 2018 at 12:03:30PM +0100, Philippe Mathieu-Daudé wrote:
> > GCC 8 new warning prevents builds to success since quite some time.
> > First report on the mailing list is in July 2018:
> > https://lists.gnu.org/archive/html/qemu-devel/2018-07/msg03723.html
> > 
> > Various intents has been sent to fix this:
> > - Incorrectly using g_strlcpy()
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg03705.html
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg03706.html
> > - Using assert() and strpadcpy()
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-11/msg03938.html
> > - Use #pragma GCC diagnostic ignored "-Wstringop-truncation"
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html
> > - adding an inline wrapper with said pragma in there
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html
> > - -Wno-stringop-truncation is the makefile
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html
> > 
> > This series replace the strncpy() calls by strpadcpy() which seemed
> > to me the saniest option.
> > 
> > Regards,
> > 
> > Phil.
> 
> Do you happen to know why does it build fine with
> Gcc 8.2.1?
> 
> Reading the GCC manual it seems that
> there is a "nostring" attribute that means

typo - its "nonstring"

> "might not be 0 terminated".
> I think we should switch to that which fixes the warning
> but also warns if someone tries to misuse these
> as C-strings.
> 
> Seems to be a better option, does it not?

Yes, it does look best as gcc manual explicitly suggests "nonstring"
as the way to stop this strncpy warning.


Regards,
Daniel
Michael S. Tsirkin Dec. 18, 2018, 2:39 p.m. UTC | #3
On Tue, Dec 18, 2018 at 09:31:00AM -0500, Michael S. Tsirkin wrote:
> On Tue, Dec 18, 2018 at 12:03:30PM +0100, Philippe Mathieu-Daudé wrote:
> > GCC 8 new warning prevents builds to success since quite some time.
> > First report on the mailing list is in July 2018:
> > https://lists.gnu.org/archive/html/qemu-devel/2018-07/msg03723.html
> > 
> > Various intents has been sent to fix this:
> > - Incorrectly using g_strlcpy()
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg03705.html
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-08/msg03706.html
> > - Using assert() and strpadcpy()
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-11/msg03938.html
> > - Use #pragma GCC diagnostic ignored "-Wstringop-truncation"
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html
> > - adding an inline wrapper with said pragma in there
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html
> > - -Wno-stringop-truncation is the makefile
> >   https://lists.gnu.org/archive/html/qemu-devel/2018-12/msg04261.html
> > 
> > This series replace the strncpy() calls by strpadcpy() which seemed
> > to me the saniest option.
> > 
> > Regards,
> > 
> > Phil.
> 
> Do you happen to know why does it build fine with
> Gcc 8.2.1?
> 
> Reading the GCC manual it seems that
> there is a "nostring" attribute

Sorry that should be "nonstring".


> that means
> "might not be 0 terminated".
> I think we should switch to that which fixes the warning
> but also warns if someone tries to misuse these
> as C-strings.
> 
> Seems to be a better option, does it not?
> 

Also maybe we can make strpadcpy check for the nonstring
attribute too somehow?
Or did gcc just hardcode the strncpy name?

> > Marc-André Lureau (1):
> >   hw/acpi: Replace strncpy() by strpadcpy(pad='\0')
> > 
> > Philippe Mathieu-Daudé (2):
> >   block/sheepdog: Replace strncpy() by strpadcpy(pad='\0')
> >   migration: Replace strncpy() by strpadcpy(pad='\0')
> > 
> >  block/sheepdog.c         |  6 +++---
> >  hw/acpi/aml-build.c      |  6 ++++--
> >  hw/acpi/core.c           | 13 +++++++------
> >  migration/global_state.c |  4 ++--
> >  4 files changed, 16 insertions(+), 13 deletions(-)
> > 
> > -- 
> > 2.17.2
Paolo Bonzini Dec. 18, 2018, 2:45 p.m. UTC | #4
On 18/12/18 15:31, Michael S. Tsirkin wrote:
> Do you happen to know why does it build fine with
> Gcc 8.2.1?
> 
> Reading the GCC manual it seems that
> there is a "nostring" attribute that means
> "might not be 0 terminated".
> I think we should switch to that which fixes the warning
> but also warns if someone tries to misuse these
> as C-strings.
> 
> Seems to be a better option, does it not?
> 
> 

Using strpadcpy is clever and self-documenting, though.  We have it
already, so why not use it.

Paolo
Michael S. Tsirkin Dec. 18, 2018, 2:54 p.m. UTC | #5
On Tue, Dec 18, 2018 at 03:45:08PM +0100, Paolo Bonzini wrote:
> On 18/12/18 15:31, Michael S. Tsirkin wrote:
> > Do you happen to know why does it build fine with
> > Gcc 8.2.1?
> > 
> > Reading the GCC manual it seems that
> > there is a "nostring" attribute that means
> > "might not be 0 terminated".
> > I think we should switch to that which fixes the warning
> > but also warns if someone tries to misuse these
> > as C-strings.
> > 
> > Seems to be a better option, does it not?
> > 
> > 
> 
> Using strpadcpy is clever and self-documenting, though.  We have it
> already, so why not use it.
> 
> Paolo

The advantage of nonstring is that it will catch attempts to
use these fields with functions that expect a 0 terminated string.

strpadcpy will instead just silence the warning.
Paolo Bonzini Dec. 18, 2018, 4:38 p.m. UTC | #6
On 18/12/18 15:54, Michael S. Tsirkin wrote:
> On Tue, Dec 18, 2018 at 03:45:08PM +0100, Paolo Bonzini wrote:
>> On 18/12/18 15:31, Michael S. Tsirkin wrote:
>>> Do you happen to know why does it build fine with
>>> Gcc 8.2.1?
>>>
>>> Reading the GCC manual it seems that
>>> there is a "nostring" attribute that means
>>> "might not be 0 terminated".
>>> I think we should switch to that which fixes the warning
>>> but also warns if someone tries to misuse these
>>> as C-strings.
>>>
>>> Seems to be a better option, does it not?
>>>
>>>
>>
>> Using strpadcpy is clever and self-documenting, though.  We have it
>> already, so why not use it.
>>
>> Paolo
> 
> The advantage of nonstring is that it will catch attempts to
> use these fields with functions that expect a 0 terminated string.
> 
> strpadcpy will instead just silence the warning.

Ah, I see.  We could also do both, that's a matter of taste.

Paolo
Philippe Mathieu-Daudé Dec. 18, 2018, 4:55 p.m. UTC | #7
On 12/18/18 3:54 PM, Michael S. Tsirkin wrote:
> On Tue, Dec 18, 2018 at 03:45:08PM +0100, Paolo Bonzini wrote:
>> On 18/12/18 15:31, Michael S. Tsirkin wrote:
>>> Do you happen to know why does it build fine with
>>> Gcc 8.2.1?
>>>
>>> Reading the GCC manual it seems that
>>> there is a "nostring" attribute that means
>>> "might not be 0 terminated".
>>> I think we should switch to that which fixes the warning
>>> but also warns if someone tries to misuse these
>>> as C-strings.
>>>
>>> Seems to be a better option, does it not?
>>>
>>>
>>
>> Using strpadcpy is clever and self-documenting, though.  We have it
>> already, so why not use it.
>>
>> Paolo
> 
> The advantage of nonstring is that it will catch attempts to
> use these fields with functions that expect a 0 terminated string.
> 
> strpadcpy will instead just silence the warning.

migration/global_state.c:109:15: error: 'strlen' argument 1 declared
attribute 'nonstring' [-Werror=stringop-overflow=]
     s->size = strlen((char *)s->runstate) + 1;
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~

GCC won... It is true this strlen() is buggy, indeed s->runstate might
be not NUL-terminated.
Michael S. Tsirkin Dec. 18, 2018, 5:03 p.m. UTC | #8
On Tue, Dec 18, 2018 at 05:38:17PM +0100, Paolo Bonzini wrote:
> On 18/12/18 15:54, Michael S. Tsirkin wrote:
> > On Tue, Dec 18, 2018 at 03:45:08PM +0100, Paolo Bonzini wrote:
> >> On 18/12/18 15:31, Michael S. Tsirkin wrote:
> >>> Do you happen to know why does it build fine with
> >>> Gcc 8.2.1?
> >>>
> >>> Reading the GCC manual it seems that
> >>> there is a "nostring" attribute that means
> >>> "might not be 0 terminated".
> >>> I think we should switch to that which fixes the warning
> >>> but also warns if someone tries to misuse these
> >>> as C-strings.
> >>>
> >>> Seems to be a better option, does it not?
> >>>
> >>>
> >>
> >> Using strpadcpy is clever and self-documenting, though.  We have it
> >> already, so why not use it.
> >>
> >> Paolo
> > 
> > The advantage of nonstring is that it will catch attempts to
> > use these fields with functions that expect a 0 terminated string.
> > 
> > strpadcpy will instead just silence the warning.
> 
> Ah, I see.  We could also do both, that's a matter of taste.
> 
> Paolo

Do you happen to know how to make gcc check the buffer size
for strpadcpy? Is the name strncpy just hard-coded?
Michael S. Tsirkin Dec. 18, 2018, 5:04 p.m. UTC | #9
On Tue, Dec 18, 2018 at 05:55:27PM +0100, Philippe Mathieu-Daudé wrote:
> On 12/18/18 3:54 PM, Michael S. Tsirkin wrote:
> > On Tue, Dec 18, 2018 at 03:45:08PM +0100, Paolo Bonzini wrote:
> >> On 18/12/18 15:31, Michael S. Tsirkin wrote:
> >>> Do you happen to know why does it build fine with
> >>> Gcc 8.2.1?
> >>>
> >>> Reading the GCC manual it seems that
> >>> there is a "nostring" attribute that means
> >>> "might not be 0 terminated".
> >>> I think we should switch to that which fixes the warning
> >>> but also warns if someone tries to misuse these
> >>> as C-strings.
> >>>
> >>> Seems to be a better option, does it not?
> >>>
> >>>
> >>
> >> Using strpadcpy is clever and self-documenting, though.  We have it
> >> already, so why not use it.
> >>
> >> Paolo
> > 
> > The advantage of nonstring is that it will catch attempts to
> > use these fields with functions that expect a 0 terminated string.
> > 
> > strpadcpy will instead just silence the warning.
> 
> migration/global_state.c:109:15: error: 'strlen' argument 1 declared
> attribute 'nonstring' [-Werror=stringop-overflow=]
>      s->size = strlen((char *)s->runstate) + 1;
>                ^~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> GCC won... It is true this strlen() is buggy, indeed s->runstate might
> be not NUL-terminated.


Ooh nice. I smell some CVE fixes coming from this effort.
Paolo Bonzini Dec. 18, 2018, 5:12 p.m. UTC | #10
On 18/12/18 17:55, Philippe Mathieu-Daudé wrote:
>> strpadcpy will instead just silence the warning.
> migration/global_state.c:109:15: error: 'strlen' argument 1 declared
> attribute 'nonstring' [-Werror=stringop-overflow=]
>      s->size = strlen((char *)s->runstate) + 1;
>                ^~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> GCC won... It is true this strlen() is buggy, indeed s->runstate might
> be not NUL-terminated.

No, runstate is declared as an array of 100 bytes, which are more than
enough.  It's ugly code but not buggy.

Paolo
Michael S. Tsirkin Dec. 18, 2018, 5:17 p.m. UTC | #11
On Tue, Dec 18, 2018 at 06:12:05PM +0100, Paolo Bonzini wrote:
> On 18/12/18 17:55, Philippe Mathieu-Daudé wrote:
> >> strpadcpy will instead just silence the warning.
> > migration/global_state.c:109:15: error: 'strlen' argument 1 declared
> > attribute 'nonstring' [-Werror=stringop-overflow=]
> >      s->size = strlen((char *)s->runstate) + 1;
> >                ^~~~~~~~~~~~~~~~~~~~~~~~~~~
> > 
> > GCC won... It is true this strlen() is buggy, indeed s->runstate might
> > be not NUL-terminated.
> 
> No, runstate is declared as an array of 100 bytes, which are more than
> enough.  It's ugly code but not buggy.
> 
> Paolo

Yes ... but it is loaded using
        VMSTATE_BUFFER(runstate, GlobalState),
and parsed using qapi_enum_parse which does not get
the buffer length.

So unless we are lucky there's a buffer overrun
on a remote/file input here.

Seems buggy to me - what am I missing?
Daniel P. Berrangé Dec. 18, 2018, 5:38 p.m. UTC | #12
On Tue, Dec 18, 2018 at 12:03:34PM -0500, Michael S. Tsirkin wrote:
> On Tue, Dec 18, 2018 at 05:38:17PM +0100, Paolo Bonzini wrote:
> > On 18/12/18 15:54, Michael S. Tsirkin wrote:
> > > On Tue, Dec 18, 2018 at 03:45:08PM +0100, Paolo Bonzini wrote:
> > >> On 18/12/18 15:31, Michael S. Tsirkin wrote:
> > >>> Do you happen to know why does it build fine with
> > >>> Gcc 8.2.1?
> > >>>
> > >>> Reading the GCC manual it seems that
> > >>> there is a "nostring" attribute that means
> > >>> "might not be 0 terminated".
> > >>> I think we should switch to that which fixes the warning
> > >>> but also warns if someone tries to misuse these
> > >>> as C-strings.
> > >>>
> > >>> Seems to be a better option, does it not?
> > >>>
> > >>>
> > >>
> > >> Using strpadcpy is clever and self-documenting, though.  We have it
> > >> already, so why not use it.
> > >>
> > >> Paolo
> > > 
> > > The advantage of nonstring is that it will catch attempts to
> > > use these fields with functions that expect a 0 terminated string.
> > > 
> > > strpadcpy will instead just silence the warning.
> > 
> > Ah, I see.  We could also do both, that's a matter of taste.
> > 
> > Paolo
> 
> Do you happen to know how to make gcc check the buffer size
> for strpadcpy? Is the name strncpy just hard-coded?

GCC provides  strncpy as a builtin function and its warning only
checks its builtin.

Regards,
Daniel
Paolo Bonzini Dec. 18, 2018, 5:38 p.m. UTC | #13
On 18/12/18 18:17, Michael S. Tsirkin wrote:
> On Tue, Dec 18, 2018 at 06:12:05PM +0100, Paolo Bonzini wrote:
>> On 18/12/18 17:55, Philippe Mathieu-Daudé wrote:
>>>> strpadcpy will instead just silence the warning.
>>> migration/global_state.c:109:15: error: 'strlen' argument 1 declared
>>> attribute 'nonstring' [-Werror=stringop-overflow=]
>>>      s->size = strlen((char *)s->runstate) + 1;
>>>                ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>
>>> GCC won... It is true this strlen() is buggy, indeed s->runstate might
>>> be not NUL-terminated.
>>
>> No, runstate is declared as an array of 100 bytes, which are more than
>> enough.  It's ugly code but not buggy.
>>
>> Paolo
> 
> Yes ... but it is loaded using
>         VMSTATE_BUFFER(runstate, GlobalState),
> and parsed using qapi_enum_parse which does not get
> the buffer length.
> 
> So unless we are lucky there's a buffer overrun
> on a remote/file input here.
> 
> Seems buggy to me - what am I missing?

Yup.   I think we're lucky twice though.  First, the state field stops
the runaway qapi_enum_parse.  Second, in any case worst case it's a segv
on migration.  This is a bug but not a CVE.

Paolo