aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Fox <pgf@brightstareng.com>2007-11-05 23:09:03 +0000
committerPaul Fox <pgf@brightstareng.com>2007-11-05 23:09:03 +0000
commitcb981638f502f4cc5ea830edc7ef62ab71112186 (patch)
tree19e370f6fe6a0da625b541b9fcbe09eb202c7654
parentf8b21d0933a06120bcac6981eb022b0c68e199f0 (diff)
downloadbusybox-w32-cb981638f502f4cc5ea830edc7ef62ab71112186.tar.gz
busybox-w32-cb981638f502f4cc5ea830edc7ef62ab71112186.tar.bz2
busybox-w32-cb981638f502f4cc5ea830edc7ef62ab71112186.zip
change safety check on zip header to allow for extra length, and
revert the header read to use the correct constant rather than sizeof. at least one version of gcc (armv4-linux-gcc-3.4.1) pads the struct to 28 bytes in spite of the packing.
-rw-r--r--archival/unzip.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/archival/unzip.c b/archival/unzip.c
index 56a5eb625..8462822f1 100644
--- a/archival/unzip.c
+++ b/archival/unzip.c
@@ -41,8 +41,10 @@ enum {
41#endif 41#endif
42}; 42};
43 43
44#define ZIP_HEADER_LEN 26
45
44typedef union { 46typedef union {
45 uint8_t raw[26]; 47 uint8_t raw[ZIP_HEADER_LEN];
46 struct { 48 struct {
47 uint16_t version; /* 0-1 */ 49 uint16_t version; /* 0-1 */
48 uint16_t flags; /* 2-3 */ 50 uint16_t flags; /* 2-3 */
@@ -57,8 +59,14 @@ typedef union {
57 } formatted ATTRIBUTE_PACKED; 59 } formatted ATTRIBUTE_PACKED;
58} zip_header_t; 60} zip_header_t;
59 61
62/* Check the offset of the last element, not the length. This leniency
63 * allows for poor packing, whereby the overall struct may be too long,
64 * even though the elements are all in the right place.
65 */
60struct BUG_zip_header_must_be_26_bytes { 66struct BUG_zip_header_must_be_26_bytes {
61 char BUG_zip_header_must_be_26_bytes[sizeof(zip_header_t) == 26 ? 1 : -1]; 67 char BUG_zip_header_must_be_26_bytes[
68 offsetof(zip_header_t, formatted.extra_len) + 2 ==
69 ZIP_HEADER_LEN ? 1 : -1];
62}; 70};
63 71
64#define FIX_ENDIANNESS(zip_header) do { \ 72#define FIX_ENDIANNESS(zip_header) do { \
@@ -256,7 +264,7 @@ int unzip_main(int argc, char **argv)
256 bb_error_msg_and_die("invalid zip magic %08X", magic); 264 bb_error_msg_and_die("invalid zip magic %08X", magic);
257 265
258 /* Read the file header */ 266 /* Read the file header */
259 xread(src_fd, zip_header.raw, sizeof(zip_header)); 267 xread(src_fd, zip_header.raw, ZIP_HEADER_LEN);
260 FIX_ENDIANNESS(zip_header); 268 FIX_ENDIANNESS(zip_header);
261 if ((zip_header.formatted.method != 0) && (zip_header.formatted.method != 8)) { 269 if ((zip_header.formatted.method != 0) && (zip_header.formatted.method != 8)) {
262 bb_error_msg_and_die("unsupported method %d", zip_header.formatted.method); 270 bb_error_msg_and_die("unsupported method %d", zip_header.formatted.method);