Fix compilation with _FORTIFY_SOURCE
Subsystems (2)
cover Fix compilation with _FORTIFY_SOURCE
Hi
This series is a work on top of Kirill previous patches. Changes are:
- I addressed all reviewers comments
- Improved some error messages
- Check that it is valid to return -errno (switched lots of places to just return -1).
- check correctly system() result for errors.
- -fstack-protector-all is only used if compiler accept it
And new additions:
- add WARN_UNUSED_RESULT
- check pipe() use in xen code.
- fix mmap_frag() returned -EINVAL when users only deal with -1 for errors.
Kirill, could you coment on the series?
Still not completely happy:
- qemu_write_full() just loops if write() returns 0. it is only used for pipes and files, but pipes and files shouldn't give you short writes in the 1st place. Not sure what to do here.
- check write() errors against -EINVAL/-EINTR/-EAGAIN series where not consistent on this regard. I didn't changed any.
You can pull this series from:
git://repo.or.cz/qemu/quintela.git fortify
With this changes, I am able to compile qemu for all architectures in a linux host without a single warning.
This is important for us (Fedora) because F12 compile all packages with -Wp,-D_FORTIFY_SOURCE=2, and we had -Werror disabled due to this.
Comments?
Juan Quintela (4):
force to test result for qemu_write_full()
check pipe() return value
Check availavility of -fstack-protector-all
mmap_frag() users only check for -1 error
Kirill A. Shutemov (13):
Introduce qemu_write_full() posix-aio-compat.c: fix warning with _FORTIFY_SOURCE block/cow.c: fix warnings with _FORTIFY_SOURCE block/qcow.c: fix warnings with _FORTIFY_SOURCE block/vmdk.o: fix warnings with _FORTIFY_SOURCE block/vvfat.c: fix warnings with _FORTIFY_SOURCE block/qcow2.c: fix warnings with _FORTIFY_SOURCE net/slirp.c: fix warning with _FORTIFY_SOURCE usb-linux.c: fix warning with _FORTIFY_SOURCE vl.c: fix warning with _FORTIFY_SOURCE monitor.c: fix warnings with _FORTIFY_SOURCE linux-user/mmap.c: fix warnings with _FORTIFY_SOURCE Enable _FORTIFY_SOURCE=2
block/cow.c | 19 ++++++++++++++-- block/qcow.c | 26 ++++++++++++++++++++--- block/qcow2.c | 55 ++++++++++++++++++++++++++++++++++++++++--------- block/vmdk.c | 50 ++++++++++++++++++++++++++++++++++++--------- block/vvfat.c | 9 ++++++- configure | 4 +- hw/xen_domainbuild.c | 13 ++++++++--- linux-user/mmap.c | 8 ++++-- monitor.c | 12 +++++++++- net/slirp.c | 9 +++++++- osdep.c | 27 ++++++++++++++++++++++++ posix-aio-compat.c | 5 +++- qemu-common.h | 2 + usb-linux.c | 3 +- vl.c | 22 ++++++++++++++++--- 15 files changed, 216 insertions(+), 48 deletions(-)
PATCH 1/17 Introduce qemu_write_full()
From: Kirill A. Shutemov <[email protected]>
A variant of write(2) which handles partial write.
--- osdep.c | 27 +++++++++++++++++++++++++++ qemu-common.h | 1 + 2 files changed, 28 insertions(+), 0 deletions(-)
osdep.c +27 -0
@@ -243,6 +243,33 @@ int qemu_open(const char *name, int flags, ...)return ret; } +/* +* A variant of write(2) which handles partial write. +* +* Return the number of bytes transferred. +* Set errno if fewer than `count' bytes are written. +*/ +ssize_t qemu_write_full (int fd,const void *buf,size_t count) +{ +ssize_t ret =0 ; +ssize_t total =0 ; + +while (count) { + ret =write (fd, buf, count); +if (ret <0 ) { +if (errno ==EINTR ) +continue ; +break ; + } + + count -= ret; + buf += ret; + total += ret; + } + +return total; +} +#ifndef _WIN32/* * Creates a pipe with FD_CLOEXEC set on both file descriptors
qemu-common.h +1 -0
@@ -160,6 +160,7 @@ void qemu_mutex_lock_iothread(void);void qemu_mutex_unlock_iothread (void );int qemu_open (const char *name,int flags, ...); +ssize_t qemu_write_full (int fd,const void *buf,size_t count);void qemu_set_cloexec (int fd);#ifndef _WIN32
Signature · 1 line
1.6.5.2
PATCH 2/17 force to test result for qemu_write_full()
In reply to Juan Quintela--- qemu-common.h | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
qemu-common.h +2 -1
@@ -160,7 +160,8 @@ void qemu_mutex_lock_iothread(void);void qemu_mutex_unlock_iothread (void );int qemu_open (const char *name,int flags, ...); -ssize_t qemu_write_full (int fd,const void *buf,size_t count); +ssize_t qemu_write_full(int fd, const void *buf, size_t count) + QEMU_WARN_UNUSED_RESULT;void qemu_set_cloexec (int fd);#ifndef _WIN32
Signature · 1 line
1.6.5.2
PATCH 3/17 posix-aio-compat.c: fix warning with _FORTIFY_SOURCE
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
CC posix-aio-compat.o
cc1: warnings being treated as errorsposix-aio-compat.c: In function 'aio_signal_handler':
posix-aio-compat.c:505: error: ignoring return value of 'write', declared with attribute warn_unused_result
make: *** [posix-aio-compat.o] Error 1
--- posix-aio-compat.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
posix-aio-compat.c +4 -1
@@ -501,8 +501,11 @@ static void aio_signal_handler(int signum) {if (posix_aio_state) {char byte =0 ; +ssize_t ret; -write (posix_aio_state->wfd, &byte,sizeof (byte)); + ret =write (posix_aio_state->wfd, &byte,sizeof (byte)); +if (ret <0 && errno !=EAGAIN ) +die ("write()" ); }qemu_service_io ();
Signature · 1 line
1.6.5.2
PATCH 4/17 block/cow.c: fix warnings with _FORTIFY_SOURCE
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
CC block/cow.o
cc1: warnings being treated as errorsblock/cow.c: In function 'cow_create':block/cow.c:251: error: ignoring return value of 'write', declared with attribute warn_unused_result block/cow.c:253: error: ignoring return value of 'ftruncate', declared with attribute warn_unused_result
make: *** [block/cow.o] Error 1
--- block/cow.c | 19 ++++++++++++++++--- 1 files changed, 16 insertions(+), 3 deletions(-)
block/cow.c +16 -3
@@ -209,6 +209,7 @@ static int cow_create(const char *filename, QEMUOptionParameter *options)struct stat st;int64_t image_sectors =0 ;const char *image_filename =NULL ; +int ret;/* Read out options */ while (options && options->name) {
@@ -248,11 +249,23 @@ static int cow_create(const char *filename, QEMUOptionParameter *options) } cow_header.sectorsize =cpu_to_be32 (512 ); cow_header.size =cpu_to_be64 (image_sectors *512 ); -write (cow_fd, &cow_header,sizeof (cow_header)); + ret =qemu_write_full (cow_fd, &cow_header,sizeof (cow_header)); +if (ret !=sizeof (cow_header)) { + ret =-1 ; + goto exit; + } +/* resize to include at least all the bitmap */ -ftruncate (cow_fd,sizeof (cow_header) + ((image_sectors +7 ) >>3 )); + ret =ftruncate (cow_fd,sizeof (cow_header) + ((image_sectors +7 ) >>3 )); +if (ret) { + ret = -errno; + goto exit; + } + + ret =0 ; +exit:close (cow_fd); -return 0 ; +return ret; }static void cow_flush (BlockDriverState *bs)
Signature · 1 line
1.6.5.2
PATCH 5/17 block/qcow.c: fix warnings with _FORTIFY_SOURCE
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
CC block/qcow.o
cc1: warnings being treated as errorsblock/qcow.c: In function 'qcow_create':block/qcow.c:804: error: ignoring return value of 'write', declared with attribute warn_unused_result block/qcow.c:806: error: ignoring return value of 'write', declared with attribute warn_unused_result block/qcow.c:811: error: ignoring return value of 'write', declared with attribute warn_unused_result
make: *** [block/qcow.o] Error 1
--- block/qcow.c | 26 ++++++++++++++++++++++---- 1 files changed, 22 insertions(+), 4 deletions(-)
block/qcow.c +22 -4
@@ -750,6 +750,7 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options)int64_t total_size =0 ;const char *backing_file =NULL ;int flags =0 ; +int ret;/* Read out options */ while (options && options->name) {
@@ -801,17 +802,34 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options) }/* write all the data */ -write (fd, &header,sizeof (header)); + ret =qemu_write_full (fd, &header,sizeof (header)); +if (ret !=sizeof (header)) { + ret =-1 ; + goto exit; + } +if (backing_file) { -write (fd, backing_file, backing_filename_len); + ret =qemu_write_full (fd, backing_file, backing_filename_len); +if (ret != backing_filename_len) { + ret =-1 ; + goto exit; + } + }lseek (fd, header_size,SEEK_SET ); tmp =0 ;for (i =0 ;i < l1_size; i++) { -write (fd, &tmp,sizeof (tmp)); + ret =qemu_write_full (fd, &tmp,sizeof (tmp)); +if (ret !=sizeof (tmp)) { + ret =-1 ; + goto exit; + } } + + ret =0 ; +exit:close (fd); -return 0 ; +return ret; }static int qcow_make_empty (BlockDriverState *bs)
Signature · 1 line
1.6.5.2
PATCH 6/17 block/vmdk.o: fix warnings with _FORTIFY_SOURCE
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
CC block/vmdk.o
cc1: warnings being treated as errorsblock/vmdk.c: In function 'vmdk_snapshot_create':block/vmdk.c:236: error: ignoring return value of 'ftruncate', declared with attribute warn_unused_result block/vmdk.c: In function 'vmdk_create':block/vmdk.c:775: error: ignoring return value of 'write', declared with attribute warn_unused_result block/vmdk.c:776: error: ignoring return value of 'write', declared with attribute warn_unused_result block/vmdk.c:778: error: ignoring return value of 'ftruncate', declared with attribute warn_unused_result block/vmdk.c:784: error: ignoring return value of 'write', declared with attribute warn_unused_result block/vmdk.c:790: error: ignoring return value of 'write', declared with attribute warn_unused_result block/vmdk.c:807: error: ignoring return value of 'write', declared with attribute warn_unused_result
make: *** [block/vmdk.o] Error 1
--- block/vmdk.c | 50 ++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 40 insertions(+), 10 deletions(-)
block/vmdk.c +40 -10
@@ -233,7 +233,8 @@ static int vmdk_snapshot_create(const char *filename, const char *backing_file)memset (&header,0 ,sizeof (header));memcpy (&header,&hdr[4 ],sizeof (header));// skip the VMDK4_MAGIC -ftruncate (snp_fd, header.grain_offset <<9 ); +if (ftruncate (snp_fd, header.grain_offset <<9 )) + goto fail;/* the descriptor offset = 0x200 */ if (lseek (p_fd,0x200 ,SEEK_SET ) ==-1 ) goto fail;
@@ -716,6 +717,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)int64_t total_size =0 ;const char *backing_file =NULL ;int flags =0 ; +int ret;// Read out options while (options && options->name) {
@@ -772,22 +774,44 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) header.check_bytes[3 ] =0xa ;/* write all the data */ -write (fd, &magic,sizeof (magic)); -write (fd, &header,sizeof (header)); + ret =qemu_write_full (fd, &magic,sizeof (magic)); +if (ret !=sizeof (magic)) { + ret =-1 ; + goto exit; + } + ret =qemu_write_full (fd, &header,sizeof (header)); +if (ret !=sizeof (header)) { + ret =-1 ; + goto exit; + } -ftruncate (fd, header.grain_offset <<9 ); + ret =ftruncate (fd, header.grain_offset <<9 ); +if (ret <0 ) { + ret =-1 ; + goto exit; + }/* write grain directory */ lseek (fd,le64_to_cpu (header.rgd_offset) <<9 ,SEEK_SET );for (i =0 , tmp = header.rgd_offset + gd_size; - i < gt_count; i++, tmp += gt_size) -write (fd, &tmp,sizeof (tmp)); + i < gt_count; i++, tmp += gt_size) { + ret =qemu_write_full (fd, &tmp,sizeof (tmp)); +if (ret !=sizeof (tmp)) { + ret =-1 ; + goto exit; + } + }/* write backup grain directory */ lseek (fd,le64_to_cpu (header.gd_offset) <<9 ,SEEK_SET );for (i =0 , tmp = header.gd_offset + gd_size; - i < gt_count; i++, tmp += gt_size) -write (fd, &tmp,sizeof (tmp)); + i < gt_count; i++, tmp += gt_size) { + ret =qemu_write_full (fd, &tmp,sizeof (tmp)); +if (ret !=sizeof (tmp)) { + ret =-1 ; + goto exit; + } + }/* compose the descriptor */ real_filename = filename;
@@ -804,10 +828,16 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)/* write the descriptor */ lseek (fd,le64_to_cpu (header.desc_offset) <<9 ,SEEK_SET ); -write (fd, desc,strlen (desc)); + ret =qemu_write_full (fd, desc,strlen (desc)); +if (ret !=strlen (desc)) { + ret =-1 ; + goto exit; + } + ret =0 ; +exit:close (fd); -return 0 ; +return ret; }static void vmdk_close (BlockDriverState *bs)
Signature · 1 line
1.6.5.2
PATCH 7/17 block/vvfat.c: fix warnings with _FORTIFY_SOURCE
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
CC block/vvfat.o
cc1: warnings being treated as errorsblock/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
--- block/vvfat.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)
block/vvfat.c +7 -2
@@ -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 ); }/* Now build FAT, and write back information into directory */
@@ -2256,7 +2257,11 @@ static int commit_one_file(BDRVVVFATState* s, c = c1; } -ftruncate (fd, size); +if (ftruncate (fd, size)) { +perror ("ftruncate()" ); +close (fd); +return -4 ; + }close (fd);return commit_mappings (s, first_cluster, dir_index);
Signature · 1 line
1.6.5.2
PATCH 8/17 block/qcow2.c: fix warnings with _FORTIFY_SOURCE
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
CC block/qcow2.o
cc1: warnings being treated as errorsblock/qcow2.c: In function 'qcow_create2':block/qcow2.c:829: error: ignoring return value of 'write', declared with attribute warn_unused_result block/qcow2.c:838: error: ignoring return value of 'write', declared with attribute warn_unused_result block/qcow2.c:839: error: ignoring return value of 'write', declared with attribute warn_unused_result block/qcow2.c:841: error: ignoring return value of 'write', declared with attribute warn_unused_result block/qcow2.c:844: error: ignoring return value of 'write', declared with attribute warn_unused_result block/qcow2.c:849: error: ignoring return value of 'write', declared with attribute warn_unused_result block/qcow2.c:852: error: ignoring return value of 'write', declared with attribute warn_unused_result block/qcow2.c:855: error: ignoring return value of 'write', declared with attribute warn_unused_result
make: *** [block/qcow2.o] Error 1
--- block/qcow2.c | 55 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 45 insertions(+), 10 deletions(-)
block/qcow2.c +45 -10
@@ -842,7 +842,7 @@ static int qcow_create2(const char *filename, int64_t total_size,uint64_t tmp, offset;QCowCreateState s1, *s = &s1;QCowExtension ext_bf = {0 ,0 }; - +int ret;memset (s,0 ,sizeof (*s));
@@ -925,7 +925,11 @@ static int qcow_create2(const char *filename, int64_t total_size, ref_clusters * s->cluster_size);/* write all the data */ -write (fd, &header,sizeof (header)); + ret =qemu_write_full (fd, &header,sizeof (header)); +if (ret !=sizeof (header)) { + ret =-1 ; + goto exit; + }if (backing_file) {if (backing_format_len) {char zero[16 ];
@@ -934,25 +938,56 @@ static int qcow_create2(const char *filename, int64_t total_size,memset (zero,0 ,sizeof (zero));cpu_to_be32s (&ext_bf.magic);cpu_to_be32s (&ext_bf.len); -write (fd, &ext_bf,sizeof (ext_bf)); -write (fd, backing_format, backing_format_len); + ret =qemu_write_full (fd, &ext_bf,sizeof (ext_bf)); +if (ret !=sizeof (ext_bf)) { + ret =-1 ; + goto exit; + } + ret =qemu_write_full (fd, backing_format, backing_format_len); +if (ret != backing_format_len) { + ret =-1 ; + goto exit; + }if (padding >0 ) { -write (fd, zero, padding); + ret =qemu_write_full (fd, zero, padding); +if (ret != padding) { + ret =-1 ; + goto exit; + } } } -write (fd, backing_file, backing_filename_len); + ret =qemu_write_full (fd, backing_file, backing_filename_len); +if (ret != backing_filename_len) { + ret =-1 ; + goto exit; + } }lseek (fd, s->l1_table_offset,SEEK_SET ); tmp =0 ;for (i =0 ;i < l1_size; i++) { -write (fd, &tmp,sizeof (tmp)); + ret =qemu_write_full (fd, &tmp,sizeof (tmp)); +if (ret !=sizeof (tmp)) { + ret =-1 ; + goto exit; + } }lseek (fd, s->refcount_table_offset,SEEK_SET ); -write (fd, s->refcount_table, s->cluster_size); + ret =qemu_write_full (fd, s->refcount_table, s->cluster_size); +if (ret != s->cluster_size) { + ret =-1 ; + goto exit; + }lseek (fd, s->refcount_block_offset,SEEK_SET ); -write (fd, s->refcount_block, ref_clusters * s->cluster_size); + ret =qemu_write_full (fd, s->refcount_block, + ref_clusters * s->cluster_size); +if (ret != s->cluster_size) { + ret =-1 ; + goto exit; + } + ret =0 ; +exit:qemu_free (s->refcount_table);qemu_free (s->refcount_block);close (fd);
@@ -966,7 +1001,7 @@ static int qcow_create2(const char *filename, int64_t total_size,bdrv_close (bs); } -return 0 ; +return ret; }static int qcow_create (const char *filename,QEMUOptionParameter *options)
Signature · 1 line
1.6.5.2
PATCH 9/17 net/slirp.c: fix warning with _FORTIFY_SOURCE
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
CC net/slirp.o
cc1: warnings being treated as errorsnet/slirp.c: In function 'slirp_smb_cleanup':net/slirp.c:470: error: ignoring return value of 'system', declared with attribute warn_unused_result
make: *** [net/slirp.o] Error 1
--- net/slirp.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-)
net/slirp.c +8 -1
@@ -464,10 +464,17 @@ int net_slirp_redir(const char *redir_str)static void slirp_smb_cleanup (SlirpState *s) {char cmd[128 ]; +int ret;if (s->smb_dir[0 ] !='\0' ) {snprintf (cmd,sizeof (cmd),"rm -rf %s" , s->smb_dir); -system (cmd); + ret =system (cmd); +if (!WIFEXITED (ret)) { +qemu_error ("'%s' failed.\n" , cmd); + }else if (WEXITSTATUS (ret)) { +qemu_error ("'%s' failed. Error code: %d\n" , + cmd,WEXITSTATUS (ret)); + } s->smb_dir[0 ] ='\0' ; } }
Signature · 1 line
1.6.5.2
PATCH 10/17 usb-linux.c: fix warning with _FORTIFY_SOURCE
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
CC usb-linux.o
cc1: warnings being treated as errorsusb-linux.c: In function 'usb_host_read_file':
usb-linux.c:1204: error: ignoring return value of 'fgets', declared with attribute warn_unused_result
make: *** [usb-linux.o] Error 1
--- usb-linux.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
usb-linux.c +1 -2
@@ -1201,9 +1201,8 @@ static int usb_host_read_file(char *line, size_t line_size, const char *device_f device_file); f =fopen (filename,"r" );if (f) { -fgets (line, line_size, f); + ret =fgets (line, line_size, f) !=NULL ;fclose (f); - ret =1 ;#if 0 } else {if (mon)
Signature · 1 line
1.6.5.2
PATCH 11/17 vl.c: fix warning with _FORTIFY_SOURCE
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
CC i386-softmmu/vl.o
cc1: warnings being treated as errors/usr/src/RPM/BUILD/qemu-0.11.92/vl.c: In function 'qemu_event_increment':/usr/src/RPM/BUILD/qemu-0.11.92/vl.c:3404: error: ignoring return value of 'write', declared with attribute warn_unused_result /usr/src/RPM/BUILD/qemu-0.11.92/vl.c: In function 'main':/usr/src/RPM/BUILD/qemu-0.11.92/vl.c:5774: error: ignoring return value of 'write', declared with attribute warn_unused_result /usr/src/RPM/BUILD/qemu-0.11.92/vl.c:6064: error: ignoring return value of 'chdir', declared with attribute warn_unused_result /usr/src/RPM/BUILD/qemu-0.11.92/vl.c:6083: error: ignoring return value of 'chdir', declared with attribute warn_unused_result make[1]: *** [vl.o] Error 1
--- vl.c | 22 ++++++++++++++++++---- 1 files changed, 18 insertions(+), 4 deletions(-)
vl.c +18 -4
@@ -3176,11 +3176,17 @@ static int io_thread_fd = -1;static void qemu_event_increment (void ) {static const char byte =0 ; +ssize_t ret;if (io_thread_fd ==-1 )return ; -write (io_thread_fd, &byte,sizeof (byte)); + ret =write (io_thread_fd, &byte,sizeof (byte)); +if (ret <0 && (errno !=EINTR && errno !=EAGAIN )) { +fprintf (stderr,"qemu_event_increment: write() filed: %s\n" , +strerror (errno)); +exit (1 ); + } }static void qemu_event_read (void *opaque)
@@ -5585,7 +5591,9 @@ int main(int argc, char **argv, char **envp)#ifndef _WIN32if (daemonize) {uint8_t status =1 ; -write (fds[1 ], &status,1 ); +if (write (fds[1 ], &status,1 ) !=1 ) { +perror ("daemonize. Writing to pipe\n" ); + } } else#endif fprintf (stderr,"Could not acquire pid file: %s\n" ,strerror (errno));
@@ -5884,7 +5892,10 @@ int main(int argc, char **argv, char **envp)if (len !=1 )exit (1 ); -chdir ("/" ); +if (chdir ("/" )) { +perror ("not able to chdir to /" ); +exit (1 ); + }TFR (fd =qemu_open ("/dev/null" ,O_RDWR ));if (fd ==-1 )exit (1 );
@@ -5903,7 +5914,10 @@ int main(int argc, char **argv, char **envp)fprintf (stderr,"chroot failed\n" );exit (1 ); } -chdir ("/" ); +if (chdir ("/" )) { +perror ("not able to chdir to /" ); +exit (1 ); + } }if (run_as) {
Signature · 1 line
1.6.5.2
PATCH 12/17 monitor.c: fix warnings with _FORTIFY_SOURCE
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
CC i386-softmmu/monitor.o
cc1: warnings being treated as errors/usr/src/RPM/BUILD/qemu-0.11.92/monitor.c: In function 'do_memory_save':/usr/src/RPM/BUILD/qemu-0.11.92/monitor.c:1318: error: ignoring return value of 'fwrite', declared with attribute warn_unused_result /usr/src/RPM/BUILD/qemu-0.11.92/monitor.c: In function 'do_physical_memory_save':/usr/src/RPM/BUILD/qemu-0.11.92/monitor.c:1345: error: ignoring return value of 'fwrite', declared with attribute warn_unused_result make[1]: *** [monitor.o] Error 1
--- monitor.c | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-)
monitor.c +10 -2
@@ -1320,10 +1320,14 @@ static void do_memory_save(Monitor *mon, const QDict *qdict, QObject **ret_data)if (l > size) l = size;cpu_memory_rw_debug (env, addr, buf, l,0 ); -fwrite (buf,1 , l, f); +if (fwrite (buf,1 , l, f) != l) { +monitor_printf (mon,"fwrite() error in do_memory_save\n" ); + goto exit; + } addr += l; size -= l; } +exit:fclose (f); }
@@ -1347,11 +1351,15 @@ static void do_physical_memory_save(Monitor *mon, const QDict *qdict,if (l > size) l = size;cpu_physical_memory_rw (addr, buf, l,0 ); -fwrite (buf,1 , l, f); +if (fwrite (buf,1 , l, f) != l) { +monitor_printf (mon,"fwrite() error in do_physical_memory_save\n" ); + goto exit; + }fflush (f); addr += l; size -= l; } +exit:fclose (f); }
Signature · 1 line
1.6.5.2
PATCH 13/17 linux-user/mmap.c: fix warnings with _FORTIFY_SOURCE
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
CC i386-linux-user/mmap.o
cc1: warnings being treated as errors/usr/src/RPM/BUILD/qemu-0.11.92/linux-user/mmap.c: In function 'mmap_frag':/usr/src/RPM/BUILD/qemu-0.11.92/linux-user/mmap.c:253: error: ignoring return value of 'pread', declared with attribute warn_unused_result /usr/src/RPM/BUILD/qemu-0.11.92/linux-user/mmap.c: In function 'target_mmap':/usr/src/RPM/BUILD/qemu-0.11.92/linux-user/mmap.c:477: error: ignoring return value of 'pread', declared with attribute warn_unused_result make[1]: *** [mmap.o] Error 1
--- linux-user/mmap.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)
linux-user/mmap.c +4 -2
@@ -250,7 +250,8 @@ static int mmap_frag(abi_ulong real_start,mprotect (host_start, qemu_host_page_size, prot1 |PROT_WRITE );/* read the corresponding file data */ -pread (fd,g2h (start), end - start, offset); +if (pread (fd,g2h (start), end - start, offset) ==-1 ) +return -1 ;/* put final protection */ if (prot_new != (prot1 |PROT_WRITE ))
@@ -474,7 +475,8 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, -1, 0);if (retaddr ==-1 ) goto fail; -pread (fd,g2h (start), len, offset); +if (pread (fd,g2h (start), len, offset) ==-1 ) + goto fail;if (!(prot &PROT_WRITE )) { ret =target_mprotect (start, len, prot);if (ret !=0 ) {
Signature · 1 line
1.6.5.2
PATCH 14/17 check pipe() return value
In reply to Juan Quintela--- hw/xen_domainbuild.c | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-)
hw/xen_domainbuild.c +9 -4
@@ -156,15 +156,18 @@ quit:return ; } -static void xen_domain_watcher (void ) +static int xen_domain_watcher (void ) {int qemu_running =1 ;int fd[2 ], i, n, rc;char byte; -pipe (fd); +if (pipe (fd) !=0 ) { +qemu_log ("%s: Huh? pipe error: %s\n" , __FUNCTION__,strerror (errno)); +return -1 ; + }if (fork () !=0 ) -return ;/* not child */ +return 0 ;/* not child */ /* close all file handles, except stdio/out/err, * our watch pipe and the xen interface handle */
@@ -238,7 +241,9 @@ int xen_domain_build_pv(const char *kernel, const char *ramdisk, }qemu_log ("xen: created domain %d\n" , xen_domid);atexit (xen_domain_cleanup); -xen_domain_watcher (); +if (xen_domain_watcher () ==-1 ) { + goto err; + }xenstore_domain_init1 (kernel, ramdisk, cmdline);
Signature · 1 line
1.6.5.2
PATCH 15/17 Enable _FORTIFY_SOURCE=2
In reply to Juan QuintelaFrom: Kirill A. Shutemov <[email protected]>
_FORTIFY_SOURCE is a Glibc feature which adds memory and string function protection.
--- configure | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
configure +1 -1
@@ -97,7 +97,7 @@ CFLAGS="-g $CFLAGS" QEMU_CFLAGS="-Wall -Wundef -Wendif-labels -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS" QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS" QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS" -QEMU_CFLAGS="-U_FORTIFY_SOURCE $QEMU_CFLAGS" +QEMU_CFLAGS="-D_FORTIFY_SOURCE=2 $QEMU_CFLAGS" QEMU_CFLAGS="-I. -I\$(SRC_PATH) $QEMU_CFLAGS" LDFLAGS="-g $LDFLAGS"
Signature · 1 line
1.6.5.2
PATCH 16/17 Check availavility of -fstack-protector-all
In reply to Juan Quintela--- configure | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
configure +1 -1
@@ -101,7 +101,7 @@ QEMU_CFLAGS="-D_FORTIFY_SOURCE=2 $QEMU_CFLAGS" QEMU_CFLAGS="-I. -I\$(SRC_PATH) $QEMU_CFLAGS" LDFLAGS="-g $LDFLAGS" -gcc_flags="-Wold-style-declaration -Wold-style-definition" +gcc_flags="-Wold-style-declaration -Wold-style-definition -fstack-protector-all" cat > $TMPC << EOF int main(void) { } EOF
Signature · 1 line
1.6.5.2
PATCH 17/17 mmap_frag() users only check for -1 error
In reply to Juan Quintela--- linux-user/mmap.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
linux-user/mmap.c +1 -1
@@ -243,7 +243,7 @@ static int mmap_frag(abi_ulong real_start,possible while it is a shared mapping */ if ((flags &MAP_TYPE ) ==MAP_SHARED && (prot &PROT_WRITE )) -return -EINVAL ; +return -1 ;/* adjust protection to be able to read */ if (!(prot1 &PROT_WRITE ))
Signature · 1 line
1.6.5.2
Re: [Qemu-devel] [PATCH 01/17] Introduce qemu_write_full()
In reply to Juan QuintelaQuoted 30 lines · Juan Quintela
From: Kirill A. Shutemov <[email protected]>
A variant of write(2) which handles partial write.
Signed-off-by Kirill A. Shutemov <[email protected]>Signed-off-by Juan Quintela <[email protected]>--- osdep.c | 27 +++++++++++++++++++++++++++ qemu-common.h | 1 + 2 files changed, 28 insertions(+), 0 deletions(-)osdep.c +11
-0@@ -243,6 +243,33 @@ int qemu_open(const char *name, int flags, ...)return ret; } +/* +* A variant of write(2) which handles partial write. +* +* Return the number of bytes transferred. +* Set errno if fewer than `count' bytes are written. +*/ +ssize_t qemu_write_full (int fd,const void *buf,size_t count) +{ +ssize_t ret =0 ; +ssize_t total =0 ; +
osdep.c int qemu_open(const char *name, int flags, ...) · line 266
Quoted 10 lines
osdep.c +10
-0+while (count) { + ret =write (fd, buf, count); +if (ret <0 ) { +if (errno ==EINTR ) +continue ; +break ; + } + + count -= ret; + buf += ret;
Constraint violation (6.5.6)
Quoted 22 lines
osdep.c +6
-0+ total += ret; + } + +return total; +} +#ifndef _WIN32/* * Creates a pipe with FD_CLOEXEC set on both file descriptors qemu-common.h +1
-0@@ -160,6 +160,7 @@ void qemu_mutex_lock_iothread(void);void qemu_mutex_unlock_iothread (void );int qemu_open (const char *name,int flags, ...); +ssize_t qemu_write_full (int fd,const void *buf,size_t count);void qemu_set_cloexec (int fd);#ifndef _WIN32
Signature · 1 line
mailto:[email protected]
[Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE
In reply to Juan QuintelaQuoted 30 lines · Juan Quintela
From: Kirill A. Shutemov <[email protected]>
CC block/vvfat.o
cc1: warnings being treated as errorsblock/vvfat.c: In function 'commit_one_file':block/vvfat.c:2259: error: ignoring return value of 'ftruncate', declared with attributewarn_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,
fromblock/vvfat.c:27:
In function 'snprintf',
inlined from 'init_directories' atblock/vvfat.c:871,
inlined from 'vvfat_open' atblock/vvfat.c:1068:/usr/include/bits/stdio2.h:65: error: call to__builtin___snprintf_chkwill always overflow destination buffer
make: *** [block/vvfat.o] Error 1Signed-off-by Kirill A. Shutemov <[email protected]>Signed-off-by Juan Quintela <[email protected]>---
block/vvfat.c | 9 +++++++--1 files changed, 7 insertions(+), 2 deletions(-)block/vvfat.c +0
-0@@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s, { direntry_t* entry=array_get_next(&(s->directory));
Quoted 5 lines
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.
Quoted 18 lines
/* Now build FAT, and write back information into directory */
block/vvfat.c +5
-2@@ -2256,7 +2257,11 @@ static int commit_one_file(BDRVVVFATState* s, c = c1; } - ftruncate(fd, size); + if (ftruncate(fd, size)) { + perror("ftruncate()"); + close(fd); + return -4; + } close(fd); return commit_mappings(s, first_cluster, dir_index); --1.6.5.2
Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE
Quoted 39 lines · Kirill A. Shutemov
Quoted 30 lines · Juan Quintela
From: Kirill A. Shutemov <[email protected]>
CC block/vvfat.o
cc1: warnings being treated as errorsblock/vvfat.c: In function 'commit_one_file':block/vvfat.c:2259: error: ignoring return value of 'ftruncate', declared with attributewarn_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,
fromblock/vvfat.c:27:
In function 'snprintf',
inlined from 'init_directories' atblock/vvfat.c:871,
inlined from 'vvfat_open' atblock/vvfat.c:1068:/usr/include/bits/stdio2.h:65: error: call to__builtin___snprintf_chkwill always overflow destination buffer
make: *** [block/vvfat.o] Error 1Signed-off-by Kirill A. Shutemov <[email protected]>Signed-off-by Juan Quintela <[email protected]>---
block/vvfat.c | 9 +++++++--1 files changed, 7 insertions(+), 2 deletions(-)block/vvfat.c +0
-0@@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s, { direntry_t* entry=array_get_next(&(s->directory));Quoted 5 lines
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
Quoted 3 lines
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
Signature · 4 lines
|: 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
Quoted 40 lines · Daniel P. Berrange
Quoted 39 lines · Kirill A. Shutemov
Quoted 30 lines · Juan Quintela
From: Kirill A. Shutemov <[email protected]>
CC block/vvfat.o
cc1: warnings being treated as errorsblock/vvfat.c: In function 'commit_one_file':block/vvfat.c:2259: error: ignoring return value of 'ftruncate', declared with attributewarn_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,
fromblock/vvfat.c:27:
In function 'snprintf',
inlined from 'init_directories' atblock/vvfat.c:871,
inlined from 'vvfat_open' atblock/vvfat.c:1068:/usr/include/bits/stdio2.h:65: error: call to__builtin___snprintf_chkwill always overflow destination buffer
make: *** [block/vvfat.o] Error 1Signed-off-by Kirill A. Shutemov <[email protected]>Signed-off-by Juan Quintela <[email protected]>---
block/vvfat.c | 9 +++++++--1 files changed, 7 insertions(+), 2 deletions(-)block/vvfat.c +0
-0@@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s, { direntry_t* entry=array_get_next(&(s->directory));Quoted 5 lines
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
Quoted 5 lines
Quoted 3 lines
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
Quoted 13 lines
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
Am 20.01.2010 12:09, schrieb Kirill A. Shutemov:
Quoted 42 lines
Quoted 40 lines · Daniel P. Berrange
Quoted 39 lines · Kirill A. Shutemov
Quoted 28 lines · Juan Quintela
From: Kirill A. Shutemov <[email protected]>
CC
block/vvfat.o
cc1: warnings being treated as errorsblock/vvfat.c: In function 'commit_one_file':block/vvfat.c:2259: error: ignoring return value of 'ftruncate', declared with attributewarn_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' atblock/vvfat.c:871,
inlined from 'vvfat_open' atblock/vvfat.c:1068:/usr/include/bits/stdio2.h:65: error: call to__builtin___snprintf_chkwill always overflow destination buffer
make: *** [block/vvfat.o] Error 1Signed-off-by Kirill A. Shutemov <[email protected]>Signed-off-by Juan Quintela <[email protected]>--- block/vvfat.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)block/vvfat.c +0
-0block/vvfat.c static int init_directories(BDRVVVFATState* s, · line 873
Quoted 7 lines
block/vvfat.c +2
-1@@ -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
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
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
Quoted 5 lines · Kevin Wolf
Am 20.01.2010 12:09, schrieb Kirill A. Shutemov:
Quoted 4 lines
Quoted 2 lines · Daniel P. Berrange
Quoted 1 line · Kirill A. Shutemov
On Wed, Jan 20, 2010 at 1:56 AM, Juan Quintela <[email protected]> wrote:
[...]
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
block/vvfat.c static int init_directories(BDRVVVFATState* s, · line 873
Quoted 12 lines
block/vvfat.c +2
-1@@ -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
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
memcpy(entry->name, "QEMU VVFAT", 11);
memcpy()doesn't check bounds.
No, this is evil, and may well be flagged by static analysis tools.
Quoted 9 lines
Quoted 4 lines
Quoted 1 line
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.htmlRegardless 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
Quoted 23 lines · Markus Armbruster
Quoted 5 lines · Kevin Wolf
Am 20.01.2010 12:09, schrieb Kirill A. Shutemov:
Quoted 4 lines
Quoted 2 lines · Daniel P. Berrange
Quoted 1 line · Kirill A. Shutemov
On Wed, Jan 20, 2010 at 1:56 AM, Juan Quintela <[email protected]> wrote:
[...]
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 7 lines
block/vvfat.c +0
-0@@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s, { direntry_t* entry=array_get_next(&(s->directory));Quoted 5 lines
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
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
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.
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Quoted 1 line
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
Quoted 7 lines
Quoted 4 lines
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
Quoted 42 lines · Kirill A. Shutemov
Quoted 23 lines · Markus Armbruster
Quoted 5 lines · Kevin Wolf
Am 20.01.2010 12:09, schrieb Kirill A. Shutemov:
Quoted 4 lines
Quoted 2 lines · Daniel P. Berrange
Quoted 1 line · Kirill A. Shutemov
On Wed, Jan 20, 2010 at 1:56 AM, Juan Quintela <[email protected]> wrote:
[...]
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 7 lines
block/vvfat.c +0
-0@@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s, { direntry_t* entry=array_get_next(&(s->directory));Quoted 5 lines
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
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
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.
Quoted 10 lines
Quoted 9 lines
Quoted 4 lines
Quoted 1 line
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.htmlRegardless 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.
Quoted 4 lines
Quoted 2 lines
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
Quoted 44 lines · Markus Armbruster
Quoted 42 lines · Kirill A. Shutemov
Quoted 23 lines · Markus Armbruster
Quoted 5 lines · Kevin Wolf
Am 20.01.2010 12:09, schrieb Kirill A. Shutemov:
Quoted 4 lines
Quoted 2 lines · Daniel P. Berrange
Quoted 1 line · Kirill A. Shutemov
On Wed, Jan 20, 2010 at 1:56 AM, Juan Quintela <[email protected]> wrote:
[...]
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 7 lines
block/vvfat.c +0
-0@@ -868,7 +868,8 @@ static int init_directories(BDRVVVFATState* s, { direntry_t* entry=array_get_next(&(s->directory));Quoted 5 lines
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
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
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.
Quoted 10 lines
Quoted 9 lines
Quoted 4 lines
Quoted 1 line
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.htmlRegardless 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.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
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.
To be fair this structure is packed, but this is not the reason to write stupid code of course.
--
Gleb.
Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE
In reply to Markus ArmbrusterQuoted 4 lines · Markus Armbruster
Quoted 1 line · Kirill A. Shutemov
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
In reply to Gleb Natapov2010/1/20 Gleb Natapov <[email protected]>:
Quoted 8 lines · Markus Armbruster
Quoted 5 lines
Quoted 1 line · Kirill A. Shutemov
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
Quoted 5 lines · Kirill A. Shutemov
2010/1/20 Gleb Natapov <[email protected]>:
Quoted 4 lines · Markus Armbruster
Quoted 3 lines
Quoted 1 line · Kirill A. Shutemov
No, compiler can't add anything between. 'char' is always byte-aligned.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
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
In reply to Kirill A. Shutemov[Some quoted material restored]
Quoted 12 lines · Kirill A. Shutemov
Quoted 11 lines · Markus Armbruster
Quoted 10 lines · Kirill A. Shutemov
Quoted 8 lines · Markus Armbruster
Quoted 4 lines · Kevin Wolf
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.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
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
In reply to Kirill A. ShutemovQuoted 5 lines · Kirill A. Shutemov
2010/1/20 Gleb Natapov <[email protected]>:
Quoted 4 lines · Markus Armbruster
Quoted 3 lines
Quoted 1 line · Kirill A. Shutemov
No, compiler can't add anything between. 'char' is always byte-aligned.
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
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?
Signature · 1 line
mailto:[email protected]
Re: [Qemu-devel] Re: [PATCH 07/17] block/vvfat.c: fix warnings with _FORTIFY_SOURCE
In reply to Kirill A. ShutemovQuoted 40 lines · Kirill A. Shutemov
Quoted 28 lines · Juan Quintela
From: Kirill A. Shutemov<[email protected]>
CC
block/vvfat.o
cc1: warnings being treated as errorsblock/vvfat.c: In function 'commit_one_file':block/vvfat.c:2259: error: ignoring return value of 'ftruncate', declared with attributewarn_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' atblock/vvfat.c:871,
inlined from 'vvfat_open' atblock/vvfat.c:1068:/usr/include/bits/stdio2.h:65: error: call to__builtin___snprintf_chkwill always overflow destination buffer
make: *** [block/vvfat.o] Error 1Signed-off-by Kirill A. Shutemov<[email protected]>Signed-off-by Juan Quintela<[email protected]>--- block/vvfat.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)block/vvfat.c +0
-0block/vvfat.c static int init_directories(BDRVVVFATState* s, · line 874
Quoted 8 lines
block/vvfat.c +2
-1@@ -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
Quoted 4 lines
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
In reply to Kirill A. ShutemovQuoted 8 lines · Kirill A. Shutemov
Quoted 4 lines · Markus Armbruster
Quoted 1 line · Kirill A. Shutemov
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
Anthony Liguori
AppliedRe: [Qemu-devel] [PATCH 01/17] Introduce qemu_write_full()
In reply to Juan QuintelaQuoted 7 lines · Juan Quintela
From: Kirill A. Shutemov<[email protected]>
A variant of write(2) which handles partial write.
Signed-off-by Kirill A. Shutemov<[email protected]>Signed-off-by Juan Quintela<[email protected]>
Applied all. Thanks.
Regards,
Anthony Liguori
Quoted 56 lines
--- osdep.c | 27 +++++++++++++++++++++++++++ qemu-common.h | 1 + 2 files changed, 28 insertions(+), 0 deletions(-)osdep.c +27
-0@@ -243,6 +243,33 @@ int qemu_open(const char *name, int flags, ...)return ret; } +/* +* A variant of write(2) which handles partial write. +* +* Return the number of bytes transferred. +* Set errno if fewer than `count' bytes are written. +*/ +ssize_t qemu_write_full (int fd,const void *buf,size_t count) +{ +ssize_t ret =0 ; +ssize_t total =0 ; + +while (count) { + ret =write (fd, buf, count); +if (ret<0 ) { +if (errno ==EINTR ) +continue ; +break ; + } + + count -= ret; + buf += ret; + total += ret; + } + +return total; +} +#ifndef _WIN32/* * Creates a pipe with FD_CLOEXEC set on both file descriptors qemu-common.h +1
-0@@ -160,6 +160,7 @@ void qemu_mutex_lock_iothread(void);void qemu_mutex_unlock_iothread (void );int qemu_open (const char *name,int flags, ...); +ssize_t qemu_write_full (int fd,const void *buf,size_t count);void qemu_set_cloexec (int fd);#ifndef _WIN32