GNOME Bugzilla – Bug 718433
Shotwell crash in gp_load_file_into_buffer/memcpy (SIGSEGV) when trying to import images
Last modified: 2013-11-26 20:58:09 UTC
---- Reported by shotwell-maint@gnome.bugs 2012-02-06 11:21:00 -0800 ---- Original Redmine bug id: 4719 Original URL: http://redmine.yorba.org/issues/4719 Searchable id: yorba-bug-4719 Original author: Peter Seiderer Original description: Problem found with Showwell-11.5 on openSUSE 12.1 (x86_64), crash in gp_load_file_into_buffer/memcpy (SIGSEGV) when trying to import images. Found a reason (and fix) for the bug, boils down to a size mismatch with the parameters when calling gp_file_get_data_and_size() on x86_64 system (could reproduce this only in a 'configure --debug' build, no crash with release build). Problem analysis (gdb trace/comments): $ gdb ./shotwell (gdb) run Program received signal SIGSEGV, Segmentation fault. 0x00007ffff02b5540 in __memcpy_ssse3 () from /lib64/libc.so.6 (gdb) where #0 0x00007ffff02b5540 in __memcpy_ssse3 () from /lib64/libc.so.6 #1 0x0000000000604c9a in gp_load_file_into_buffer (context=0x1911740, camera=0x194c950, folder=0x1873270 "/DCIM/100CANON", filename=0xe33a50 "IMG_0001.JPG", filetype=GP_FILE_TYPE_EXIF, result_length1=0x7fffffffb1c0, error=0x7fffffffb1b8) at /home/seiderer/Work/shotwell/shotwell/src/camera/GPhoto.vala:248 #2 0x0000000000603c87 in gp_load_metadata (context=0x1911740, camera=0x194c950, folder=0x1873270 "/DCIM/100CANON", filename=0xe33a50 "IMG_0001.JPG", error= 0x7fffffffb2a8) at /home/seiderer/Work/shotwell/shotwell/src/camera/GPhoto.vala:176 #3 0x0000000000615331 in import_page_load_previews_and_metadata (self=0x12d4570, import_list=0x142f040) at /home/seiderer/Work/shotwell/shotwell/src/camera/ImportPage.vala:1405 #4 0x00000000006114d9 in import_page_refresh_camera (self=0x12d4570) at /home/seiderer/Work/shotwell/shotwell/src/camera/ImportPage.vala:1125 #5 0x000000000060fa85 in import_page_try_refreshing_camera (self=0x12d4570, fail_on_locked=0) at /home/seiderer/Work/shotwell/shotwell/src/camera/ImportPage.vala:952 #6 0x000000000060f936 in import_page_real_switched_to (base=0x12d4570) at /home/seiderer/Work/shotwell/shotwell/src/camera/ImportPage.vala:943 ... (gdb) frame 1 #1 0x0000000000604c9a in gp_load_file_into_buffer (context=0x1911740, camera=0x194c950, folder=0x1873270 "/DCIM/100CANON", filename=0xe33a50 "IMG_0001.JPG", filetype=GP_FILE_TYPE_EXIF, result_length1=0x7fffffffb1c0, error=0x7fffffffb1b8) at /home/seiderer/Work/shotwell/shotwell/src/camera/GPhoto.vala:248 248 Memory.copy(buffer, data, buffer.length); (gdb) p buffer $1 = (guint8 *) 0x1955110 "" (gdb) p data $2 = (guint8 *) 0x0 ---> data (the location from where to copy) is null (gdb) p buffer.length Attempt to extract a component of a value that is not a structure. ---> gdb could not show vala data types, take a look at the compiled version of GPhoto.vala, ---> a generated C file src/camera/GPhoto.c where the memcpy takes place: 2182 #line 248 "/home/seiderer/Work/shotwell/shotwell/src/camera/GPhoto.vala" 2183 _tmp31__length1 = buffer_length1; 2184 #line 248 "/home/seiderer/Work/shotwell/shotwell/src/camera/GPhoto.vala" 2185 memcpy (_tmp29_, _tmp30_, (gsize) _tmp31__length1); 2186 #line 250 "/home/seiderer/Work/shotwell/shotwell/src/camera/GPhoto.vala" (gdb) p _tmp29_ $3 = (guint8 *) 0x1955110 "" (gdb) p _tmp30_ $4 = (guint8 *) 0x0 ---> _tmp30_/data is really null (no gdb debug info failure) (gdb) p _tmp31__length1 $5 = 21336 ---> _tmp31__length1/buffer.length is set, so take a look at vala source code (gdb) list 234 235 res = camera.get_file(folder, filename, filetype, camera_file, context); 236 if (res != Result.OK) 237 throw new GPhotoError.LIBRARY("[%d] Error retrieving file object for %s/%s: %s", 238 (int) res, folder, filename, res.as_string()); 239 240 // if buffer can be loaded into memory, return a copy of that (can't return buffer itself 241 // as it will be destroyed when the camera_file is unref'd) 242 unowned uint8[] data; 243 res = camera_file.get_data_and_size(out data); 244 if (res != Result.OK) 245 return null; 246 247 uint8[] buffer = new uint8[data.length]; 248 Memory.copy(buffer, data, buffer.length); 249 250 return buffer; ---> camera_file.get_data_and_size(out data) return code is checked, but data is null? ---> one more look at the generated C file 2123 #line 243 "/home/seiderer/Work/shotwell/shotwell/src/camera/GPhoto.vala" 2124 _tmp21_ = camera_file; 2125 #line 243 "/home/seiderer/Work/shotwell/shotwell/src/camera/GPhoto.vala" 2126 _tmp24_ = gp_file_get_data_and_size (_tmp21_, &_tmp22_, &_tmp23_); ---> check the parameters for the gp_file_get_data_and_size(CameraFile*, const char **data, unsigned long int *size) call (gdb) p _tmp24_ $6 = 0 ---> return value is o.k. (gdb) p _tmp22_ $7 = (guint8 *) 0x0 ---> data is set to null (gdb) p _tmp23_ $8 = 21336 ---> size seems to be o.k. ---> what now? check the data types... (gdb) ptype _tmp22_ type = unsigned char * ---> o.k. (gdb) ptype _tmp23_ type = int ---> here it is what causes the bug, on x86_64 the type 'int' is 4 bytes long ---> and the type 'unsigned long' is 8 bytes (gdb) p sizeof(int) $9 = 4 (gdb) p sizeof(unsigned long) $10 = 8 ---> take a look at the address of _tmp22_ (data) and _tmp23_ (size) (gdb) p &_tmp22_ $11 = (guint8 **) 0x7fffffffb008 (gdb) p &_tmp23_ $12 = (gint *) 0x7fffffffb004 ---> what happens? From libgphoto2-2.4.11/libgphoto2/gphoto2-file.c 350 gp_file_get_data_and_size (CameraFile *file, const char **data, 351 unsigned long int *size) 352 { 353 CHECK_NULL (file); 354 355 switch (file->accesstype) { 356 case GP_FILE_ACCESSTYPE_MEMORY: 357 if (data) 358 *data = file->data; 359 if (size) 360 *size = file->size; 361 break; ---> first at line 358 file->data pointer/8 bytes are written to the adress &_tmp22_/0x7fffffffb008 ---> second at line 360 file->size/8 bytes are written to the address & &_tmp23/0x7fffffffb004 ---> overwriting 4 bytes of _tmp22_ (because of the type mismatch) which leads to the null pointer ---> in the memcopy Patch with new libgphoto2/get_data_and_size() vala binding and adjusted calls in src/camera/GPhoto.vala attached. Thanks for the nice tool ;-) Peter List of references for this bug: [1] [http://sourceforge.net/mailarchive/forum.php?thread_name=20110408115901.G G10318%40suse.de&forum_name=gphoto-devel](http://sourceforge.net/mailarchive/f orum.php?thread_name=20110408115901.GG10318%40suse.de&forum_name=gphoto-devel) [2] https://bugs.launchpad.net/ubuntu/+source/libgphoto2/+bug/750294 [3] https://bugs.launchpad.net/ubuntu/+source/shotwell/+bug/850471 [4] [https://sourceforge.net/tracker/?func=detail&aid=3409690&group_id=8874&at id=108874](https://sourceforge.net/tracker/?func=detail&aid=3409690&group_id=8 874&atid=108874) ---- Additional Comments From shotwell-maint@gnome.bugs 2013-05-01 11:38:00 -0700 ---- ### History #### #1 Updated by Lucas Beeler almost 2 years ago * **Status** changed from _Open_ to _5_ * **Assignee** set to _Peter Seiderer_ * **Priority** changed from _Normal_ to _High_ * **Target version** set to _0.12_ * **Resolution** set to _fixed_ Fixed in 76bfbc2edfe7e45664a4cf7c8be4101bc8c67b9d. Thanks Peter! #### #2 Updated by Charles Lindsay 7 months ago * **Status** changed from _5_ to _Fixed_ --- Bug imported by chaz@yorba.org 2013-11-25 21:56 UTC --- This bug was previously known as _bug_ 4719 at http://redmine.yorba.org/show_bug.cgi?id=4719 Imported an attachment (id=262352) Unknown Component Using default product and component set in Parameters Unknown milestone "unknown in product shotwell. Setting to default milestone for this product, "---". Setting qa contact to the default for this product. This bug either had no qa contact or an invalid one.