Bug#443880: libzzip crash is unaligned access

2007-11-07 Thread AnĂ­bal Monsalve Salazar
On Wed, Nov 07, 2007 at 12:38:23AM +, brian m. carlson wrote:
tags 443880 + patch
kthxbye

The crash in __zzip_parse_root_directory is a bus error on sparc, which 
is a dead giveaway that it's an unaligned access.  The problem is that 
d is a zzip_disk_entry, which is required to be aligned, but zz_offset 
is not guaranteed to be a multiple of sizeof(*d).

In fact, line 456 explicitly updates zz_offset to something that is 
often *not* a multiple of 4, so using a char * (fd_map, from mmap) will 
result in an unaligned access.  The way to solve this is to explicitly 
allocate memory for d, then memcpy the data from fd_map to d, since 
memcpy is guaranteed to work for memory of any alignment.  

An untested patch to do this is attached.

Thank you!

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 713 440 7475 | http://crustytoothpaste.ath.cx/~bmc | My opinion only
a typesetting engine: http://crustytoothpaste.ath.cx/~bmc/code/thwack
OpenPGP: RSA v4 4096b 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187

Enrico, please test the new debian packages available at:

http://people.debian.org/~anibal/zziplib/

--- zip.c.orig 2007-11-06 23:59:24.0 +
+++ zip.c  2007-11-07 00:35:40.0 +
@@ -402,7 +402,10 @@
 uint16_t u_extras, u_comment, u_namlen;
 
 if (fd_map) 
-  { d = (void*)(fd_map+zz_fd_gap+zz_offset); } /* 
fd_map+fd_gap==u_rootseek */
+  {
+d = dirent;
+memcpy(d, fd_map+zz_fd_gap+zz_offset, sizeof(*d)); /* 
fd_map+fd_gap==u_rootseek */
+}
 else
 {
 if (io-fd.seeks(fd, zz_rootseek+zz_offset, SEEK_SET)  0)


signature.asc
Description: Digital signature


Bug#443880: libzzip crash is unaligned access

2007-11-06 Thread brian m. carlson

tags 443880 + patch
kthxbye

The crash in __zzip_parse_root_directory is a bus error on sparc, which 
is a dead giveaway that it's an unaligned access.  The problem is that 
d is a zzip_disk_entry, which is required to be aligned, but zz_offset 
is not guaranteed to be a multiple of sizeof(*d).


In fact, line 456 explicitly updates zz_offset to something that is 
often *not* a multiple of 4, so using a char * (fd_map, from mmap) will 
result in an unaligned access.  The way to solve this is to explicitly 
allocate memory for d, then memcpy the data from fd_map to d, since 
memcpy is guaranteed to work for memory of any alignment.  


An untested patch to do this is attached.
--
brian m. carlson / brian with sandals: Houston, Texas, US
+1 713 440 7475 | http://crustytoothpaste.ath.cx/~bmc | My opinion only
a typesetting engine: http://crustytoothpaste.ath.cx/~bmc/code/thwack
OpenPGP: RSA v4 4096b 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187
--- zip.c.orig	2007-11-06 23:59:24.0 +
+++ zip.c	2007-11-07 00:35:40.0 +
@@ -402,7 +402,10 @@
 uint16_t u_extras, u_comment, u_namlen;
 
 if (fd_map) 
-	{ d = (void*)(fd_map+zz_fd_gap+zz_offset); } /* fd_map+fd_gap==u_rootseek */
+	{
+d = dirent;
+memcpy(d, fd_map+zz_fd_gap+zz_offset, sizeof(*d)); /* fd_map+fd_gap==u_rootseek */
+}
 else
 {
 if (io-fd.seeks(fd, zz_rootseek+zz_offset, SEEK_SET)  0)


signature.asc
Description: Digital signature