Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Daniel P. Berrange
On Wed, Jan 20, 2010 at 08:19:26AM +0200, Kirill A. Shutemov wrote:
 On Wed, Jan 20, 2010 at 1:56 AM, Juan Quintela quint...@redhat.com wrote:
  From: Kirill A. Shutemov kir...@shutemov.name
 
  CC    block/vvfat.o
  cc1: warnings being treated as errors
  block/vvfat.c: In function 'commit_one_file':
  block/vvfat.c:2259: error: ignoring return value of 'ftruncate', declared 
  with attribute warn_unused_result
  make: *** [block/vvfat.o] Error 1
   CC    block/vvfat.o
  In file included from /usr/include/stdio.h:912,
                  from ./qemu-common.h:19,
                  from block/vvfat.c:27:
  In function 'snprintf',
     inlined from 'init_directories' at block/vvfat.c:871,
     inlined from 'vvfat_open' at block/vvfat.c:1068:
  /usr/include/bits/stdio2.h:65: error: call to __builtin___snprintf_chk will 
  always overflow destination buffer
  make: *** [block/vvfat.o] Error 1
 
  Signed-off-by: Kirill A. Shutemov kir...@shutemov.name
  Signed-off-by: Juan Quintela quint...@redhat.com
  ---
   block/vvfat.c |    9 +++--
   1 files changed, 7 insertions(+), 2 deletions(-)
 
  diff --git a/block/vvfat.c b/block/vvfat.c
  index 063f731..df957e5 100644
  --- a/block/vvfat.c
  +++ b/block/vvfat.c
  @@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s,
      {
         direntry_t* entry=array_get_next((s-directory));
         entry-attributes=0x28; /* archive | volume label */
  -       snprintf((char*)entry-name,11,QEMU VVFAT);
  +       memcpy(entry-name,QEMU VVF,8);
  +       memcpy(entry-extension,AT ,3);
      }
 
 Better to use
 
 memcpy(entry-name, QEMU VVFAT, 11);
 
 memcpy() doesn't check bounds.

It doesn't *currently* check bounds. If we want to explicitly
fill 2 fields at once, then we should redeclare this to have a 
union with one part comprising the entire buffer, thus avoiding
the need for delibrate buffer overruns.

Regards,
Daniel
-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Kirill A. Shutemov
On Wed, Jan 20, 2010 at 12:33 PM, Daniel P. Berrange
berra...@redhat.com wrote:
 On Wed, Jan 20, 2010 at 08:19:26AM +0200, Kirill A. Shutemov wrote:
 On Wed, Jan 20, 2010 at 1:56 AM, Juan Quintela quint...@redhat.com wrote:
  From: Kirill A. Shutemov kir...@shutemov.name
 
  CC    block/vvfat.o
  cc1: warnings being treated as errors
  block/vvfat.c: In function 'commit_one_file':
  block/vvfat.c:2259: error: ignoring return value of 'ftruncate', declared 
  with attribute warn_unused_result
  make: *** [block/vvfat.o] Error 1
   CC    block/vvfat.o
  In file included from /usr/include/stdio.h:912,
                  from ./qemu-common.h:19,
                  from block/vvfat.c:27:
  In function 'snprintf',
     inlined from 'init_directories' at block/vvfat.c:871,
     inlined from 'vvfat_open' at block/vvfat.c:1068:
  /usr/include/bits/stdio2.h:65: error: call to __builtin___snprintf_chk 
  will always overflow destination buffer
  make: *** [block/vvfat.o] Error 1
 
  Signed-off-by: Kirill A. Shutemov kir...@shutemov.name
  Signed-off-by: Juan Quintela quint...@redhat.com
  ---
   block/vvfat.c |    9 +++--
   1 files changed, 7 insertions(+), 2 deletions(-)
 
  diff --git a/block/vvfat.c b/block/vvfat.c
  index 063f731..df957e5 100644
  --- a/block/vvfat.c
  +++ b/block/vvfat.c
  @@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s,
      {
         direntry_t* entry=array_get_next((s-directory));
         entry-attributes=0x28; /* archive | volume label */
  -       snprintf((char*)entry-name,11,QEMU VVFAT);
  +       memcpy(entry-name,QEMU VVF,8);
  +       memcpy(entry-extension,AT ,3);
      }

 Better to use

 memcpy(entry-name, QEMU VVFAT, 11);

 memcpy() doesn't check bounds.

 It doesn't *currently* check bounds.

No. memcpy() will never check bounds. It's totaly different from strcpy,
http://gcc.gnu.org/ml/gcc-patches/2009-06/msg00419.html

 If we want to explicitly
 fill 2 fields at once, then we should redeclare this to have a
 union with one part comprising the entire buffer, thus avoiding
 the need for delibrate buffer overruns.

 Regards,
 Daniel
 --
 |: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
 |: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
 |: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
 |: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|





Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Kevin Wolf
Am 20.01.2010 12:09, schrieb Kirill A. Shutemov:
 On Wed, Jan 20, 2010 at 12:33 PM, Daniel P. Berrange
 berra...@redhat.com wrote:
 On Wed, Jan 20, 2010 at 08:19:26AM +0200, Kirill A. Shutemov wrote:
 On Wed, Jan 20, 2010 at 1:56 AM, Juan Quintela quint...@redhat.com wrote:
 From: Kirill A. Shutemov kir...@shutemov.name

 CCblock/vvfat.o
 cc1: warnings being treated as errors
 block/vvfat.c: In function 'commit_one_file':
 block/vvfat.c:2259: error: ignoring return value of 'ftruncate', declared 
 with attribute warn_unused_result
 make: *** [block/vvfat.o] Error 1
  CCblock/vvfat.o
 In file included from /usr/include/stdio.h:912,
 from ./qemu-common.h:19,
 from block/vvfat.c:27:
 In function 'snprintf',
inlined from 'init_directories' at block/vvfat.c:871,
inlined from 'vvfat_open' at block/vvfat.c:1068:
 /usr/include/bits/stdio2.h:65: error: call to __builtin___snprintf_chk 
 will always overflow destination buffer
 make: *** [block/vvfat.o] Error 1

 Signed-off-by: Kirill A. Shutemov kir...@shutemov.name
 Signed-off-by: Juan Quintela quint...@redhat.com
 ---
  block/vvfat.c |9 +++--
  1 files changed, 7 insertions(+), 2 deletions(-)

 diff --git a/block/vvfat.c b/block/vvfat.c
 index 063f731..df957e5 100644
 --- a/block/vvfat.c
 +++ b/block/vvfat.c
 @@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s,
 {
direntry_t* entry=array_get_next((s-directory));
entry-attributes=0x28; /* archive | volume label */
 -   snprintf((char*)entry-name,11,QEMU VVFAT);
 +   memcpy(entry-name,QEMU VVF,8);
 +   memcpy(entry-extension,AT ,3);
 }

 Better to use

 memcpy(entry-name, QEMU VVFAT, 11);

 memcpy() doesn't check bounds.

 It doesn't *currently* check bounds.
 
 No. memcpy() will never check bounds. It's totaly different from strcpy,
 http://gcc.gnu.org/ml/gcc-patches/2009-06/msg00419.html

Regardless if deliberately overflowing the buffer works or doesn't
making it explicit is better. Someone might reorder the struct or add
new fields in between (okay, unlikely in this case, but still) and
you'll overflow into fields you never wanted to touch.

Kevin




Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Markus Armbruster
Kevin Wolf kw...@redhat.com writes:

 Am 20.01.2010 12:09, schrieb Kirill A. Shutemov:
 On Wed, Jan 20, 2010 at 12:33 PM, Daniel P. Berrange
 berra...@redhat.com wrote:
 On Wed, Jan 20, 2010 at 08:19:26AM +0200, Kirill A. Shutemov wrote:
 On Wed, Jan 20, 2010 at 1:56 AM, Juan Quintela quint...@redhat.com wrote:
[...]
 diff --git a/block/vvfat.c b/block/vvfat.c
 index 063f731..df957e5 100644
 --- a/block/vvfat.c
 +++ b/block/vvfat.c
 @@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s,
 {
direntry_t* entry=array_get_next((s-directory));
entry-attributes=0x28; /* archive | volume label */
 -   snprintf((char*)entry-name,11,QEMU VVFAT);
 +   memcpy(entry-name,QEMU VVF,8);
 +   memcpy(entry-extension,AT ,3);
 }

 Better to use

 memcpy(entry-name, QEMU VVFAT, 11);

 memcpy() doesn't check bounds.

No, this is evil, and may well be flagged by static analysis tools.

 It doesn't *currently* check bounds.
 
 No. memcpy() will never check bounds. It's totaly different from strcpy,
 http://gcc.gnu.org/ml/gcc-patches/2009-06/msg00419.html

 Regardless if deliberately overflowing the buffer works or doesn't
 making it explicit is better. Someone might reorder the struct or add
 new fields in between (okay, unlikely in this case, but still) and
 you'll overflow into fields you never wanted to touch.

Moreover, compilers are free to put padding between members name and
extension.




Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Kirill A. Shutemov
On Wed, Jan 20, 2010 at 2:15 PM, Markus Armbruster arm...@redhat.com wrote:
 Kevin Wolf kw...@redhat.com writes:

 Am 20.01.2010 12:09, schrieb Kirill A. Shutemov:
 On Wed, Jan 20, 2010 at 12:33 PM, Daniel P. Berrange
 berra...@redhat.com wrote:
 On Wed, Jan 20, 2010 at 08:19:26AM +0200, Kirill A. Shutemov wrote:
 On Wed, Jan 20, 2010 at 1:56 AM, Juan Quintela quint...@redhat.com 
 wrote:
 [...]
 diff --git a/block/vvfat.c b/block/vvfat.c
 index 063f731..df957e5 100644
 --- a/block/vvfat.c
 +++ b/block/vvfat.c
 @@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s,
     {
        direntry_t* entry=array_get_next((s-directory));
        entry-attributes=0x28; /* archive | volume label */
 -       snprintf((char*)entry-name,11,QEMU VVFAT);
 +       memcpy(entry-name,QEMU VVF,8);
 +       memcpy(entry-extension,AT ,3);
     }

 Better to use

 memcpy(entry-name, QEMU VVFAT, 11);

 memcpy() doesn't check bounds.

 No, this is evil, and may well be flagged by static analysis tools.

If so, the tool is stupid.

 It doesn't *currently* check bounds.

 No. memcpy() will never check bounds. It's totaly different from strcpy,
 http://gcc.gnu.org/ml/gcc-patches/2009-06/msg00419.html

 Regardless if deliberately overflowing the buffer works or doesn't
 making it explicit is better. Someone might reorder the struct or add
 new fields in between (okay, unlikely in this case, but still) and
 you'll overflow into fields you never wanted to touch.

 Moreover, compilers are free to put padding between members name and
 extension.

No, compiler can't add anything between. 'char' is always byte-aligned.




Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Markus Armbruster
Kirill A. Shutemov kir...@shutemov.name writes:

 On Wed, Jan 20, 2010 at 2:15 PM, Markus Armbruster arm...@redhat.com wrote:
 Kevin Wolf kw...@redhat.com writes:

 Am 20.01.2010 12:09, schrieb Kirill A. Shutemov:
 On Wed, Jan 20, 2010 at 12:33 PM, Daniel P. Berrange
 berra...@redhat.com wrote:
 On Wed, Jan 20, 2010 at 08:19:26AM +0200, Kirill A. Shutemov wrote:
 On Wed, Jan 20, 2010 at 1:56 AM, Juan Quintela quint...@redhat.com 
 wrote:
 [...]
 diff --git a/block/vvfat.c b/block/vvfat.c
 index 063f731..df957e5 100644
 --- a/block/vvfat.c
 +++ b/block/vvfat.c
 @@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s,
     {
        direntry_t* entry=array_get_next((s-directory));
        entry-attributes=0x28; /* archive | volume label */
 -       snprintf((char*)entry-name,11,QEMU VVFAT);
 +       memcpy(entry-name,QEMU VVF,8);
 +       memcpy(entry-extension,AT ,3);
     }

 Better to use

 memcpy(entry-name, QEMU VVFAT, 11);

 memcpy() doesn't check bounds.

 No, this is evil, and may well be flagged by static analysis tools.

 If so, the tool is stupid.

 It doesn't *currently* check bounds.

 No. memcpy() will never check bounds. It's totaly different from strcpy,
 http://gcc.gnu.org/ml/gcc-patches/2009-06/msg00419.html

 Regardless if deliberately overflowing the buffer works or doesn't
 making it explicit is better. Someone might reorder the struct or add
 new fields in between (okay, unlikely in this case, but still) and
 you'll overflow into fields you never wanted to touch.

 Moreover, compilers are free to put padding between members name and
 extension.

 No, compiler can't add anything between. 'char' is always byte-aligned.

You got some reading to do then.




Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Kirill A. Shutemov
On Wed, Jan 20, 2010 at 3:03 PM, Markus Armbruster arm...@redhat.com wrote:
 Kirill A. Shutemov kir...@shutemov.name writes:
 No, compiler can't add anything between. 'char' is always byte-aligned.

 You got some reading to do then.

Do you want to say that it's not true? Could you provide an example
when 'char' isn't byte-aligned?




Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Kirill A. Shutemov
2010/1/20 Gleb Natapov g...@redhat.com:
 On Wed, Jan 20, 2010 at 02:03:04PM +0100, Markus Armbruster wrote:
 Kirill A. Shutemov kir...@shutemov.name writes:
  No, compiler can't add anything between. 'char' is always byte-aligned.

 You got some reading to do then.

 To be fair this structure is packed, but this is not the reason to write
 stupid code of course.

In what way does it stupid? Compiler can't insert pads between two
arrays of 'char'.




Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Gleb Natapov
On Wed, Jan 20, 2010 at 04:02:19PM +0200, Kirill A. Shutemov wrote:
 2010/1/20 Gleb Natapov g...@redhat.com:
  On Wed, Jan 20, 2010 at 02:03:04PM +0100, Markus Armbruster wrote:
  Kirill A. Shutemov kir...@shutemov.name writes:
   No, compiler can't add anything between. 'char' is always byte-aligned.
 
  You got some reading to do then.
 
  To be fair this structure is packed, but this is not the reason to write
  stupid code of course.
 
 In what way does it stupid? Compiler can't insert pads between two
 arrays of 'char'.
Because this is not wise write tricky code especially if it buys you
nothing. This is not C obfuscation contest and it will bite you later.
What to search where extension[] is initialized? grep extension will
not find it! Need to change structure layout? Have to change unrelated
code too, but, of course, can't even know that. So can you please tell
us why that code should stay like it is now?

--
Gleb.




Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Markus Armbruster
[Some quoted material restored]

Kirill A. Shutemov kir...@shutemov.name writes:

 On Wed, Jan 20, 2010 at 3:03 PM, Markus Armbruster arm...@redhat.com wrote:
 Kirill A. Shutemov kir...@shutemov.name writes:
 On Wed, Jan 20, 2010 at 2:15 PM, Markus Armbruster arm...@redhat.com 
 wrote:
 Kevin Wolf kw...@redhat.com writes:
 Regardless if deliberately overflowing the buffer works or doesn't
 making it explicit is better. Someone might reorder the struct or add
 new fields in between (okay, unlikely in this case, but still) and
 you'll overflow into fields you never wanted to touch.

 Moreover, compilers are free to put padding between members name and
 extension.

 No, compiler can't add anything between. 'char' is always byte-aligned.

 You got some reading to do then.

 Do you want to say that it's not true? Could you provide an example
 when 'char' isn't byte-aligned?

I was wrong, because I overlooked __attribute__((packed)).

ISO/IEC 9899:1999 6.7.2.1 guarantees a number of things for structs,
chiefly members stay in order, no padding before the first member.  But
it does not restrict padding between members or at the end in any way,
so compilers may pad there how they see fit.  In particular, there is no
rule that a compiler may only add padding to satisfy the next member's
alignment requirement.

__attribute__((packed)) tightens the spec to eliminate padding.

Regardless, the deliberate buffer overflow to hopefully save a few bytes
and cycles is a dirty, brittle trick for no good reason.  If this really
must be hand-optimized (numbers, please), do it cleanly, the way Dan
suggested.




Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread malc
On Wed, 20 Jan 2010, Kirill A. Shutemov wrote:

 2010/1/20 Gleb Natapov g...@redhat.com:
  On Wed, Jan 20, 2010 at 02:03:04PM +0100, Markus Armbruster wrote:
  Kirill A. Shutemov kir...@shutemov.name writes:
   No, compiler can't add anything between. 'char' is always byte-aligned.
 
  You got some reading to do then.
 
  To be fair this structure is packed, but this is not the reason to write
  stupid code of course.
 
 In what way does it stupid? Compiler can't insert pads between two
 arrays of 'char'.

Can you cite chapter and verse of the standard where it's spelled out?

-- 
mailto:av1...@comtv.ru




Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Anthony Liguori

On 01/20/2010 12:19 AM, Kirill A. Shutemov wrote:

On Wed, Jan 20, 2010 at 1:56 AM, Juan Quintelaquint...@redhat.com  wrote:
   

From: Kirill A. Shutemovkir...@shutemov.name

CCblock/vvfat.o
cc1: warnings being treated as errors
block/vvfat.c: In function 'commit_one_file':
block/vvfat.c:2259: error: ignoring return value of 'ftruncate', declared with 
attribute warn_unused_result
make: *** [block/vvfat.o] Error 1
  CCblock/vvfat.o
In file included from /usr/include/stdio.h:912,
 from ./qemu-common.h:19,
 from block/vvfat.c:27:
In function 'snprintf',
inlined from 'init_directories' at block/vvfat.c:871,
inlined from 'vvfat_open' at block/vvfat.c:1068:
/usr/include/bits/stdio2.h:65: error: call to __builtin___snprintf_chk will 
always overflow destination buffer
make: *** [block/vvfat.o] Error 1

Signed-off-by: Kirill A. Shutemovkir...@shutemov.name
Signed-off-by: Juan Quintelaquint...@redhat.com
---
  block/vvfat.c |9 +++--
  1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index 063f731..df957e5 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s,
 {
direntry_t* entry=array_get_next((s-directory));
entry-attributes=0x28; /* archive | volume label */
-   snprintf((char*)entry-name,11,QEMU VVFAT);
+   memcpy(entry-name,QEMU VVF,8);
+   memcpy(entry-extension,AT ,3);
 }
 

Better to use

memcpy(entry-name, QEMU VVFAT, 11);

memcpy() doesn't check bounds.
   


Relying on such things is bad form because it isn't obvious to a casual 
reader what is happening.  You have to know that entry-name is 8 chars 
long and realize that it will overflow into extension.  Since that info 
is all the way in the structure definition, the result is difficult to 
read code.


Any other discussions about whether the standards allow such a thing or 
whether tools are stupid is irrelevant.  It's a neat trick but it 
results in more difficult to maintain code.


Regards,

Anthony Liguori




Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE

2010-01-20 Thread Jamie Lokier
Kirill A. Shutemov wrote:
 On Wed, Jan 20, 2010 at 3:03 PM, Markus Armbruster arm...@redhat.com wrote:
  Kirill A. Shutemov kir...@shutemov.name writes:
  No, compiler can't add anything between. 'char' is always byte-aligned.
 
  You got some reading to do then.
 
 Do you want to say that it's not true? Could you provide an example
 when 'char' isn't byte-aligned?

I have no example, but that doesn't mean there is no architecture, ABI
or host OS where it happens.  Architectures can be surprising.

It's very easy to make assumptions which break on some architecture
you've never tested on.

Take this code:

struct part1 {
char c[5];
};

struct part2 {
char c[3];
};

struct all {
struct part1 p1;
struct part2 p2;
};

What do you think the size is on ARM?  Hint: not 8 when using GCC  4,
but it is 8 when using current GCC and the later ARM ABI.

This broke some data parsing application when it was ported from x86
to ARM, because of a wrong assumption about structure layout that
works on nearly all architectures and passed all testing prior to the port.

-- Jamie