diff options
author | Paul Fox <pgf@brightstareng.com> | 2007-11-05 23:09:03 +0000 |
---|---|---|
committer | Paul Fox <pgf@brightstareng.com> | 2007-11-05 23:09:03 +0000 |
commit | cb981638f502f4cc5ea830edc7ef62ab71112186 (patch) | |
tree | 19e370f6fe6a0da625b541b9fcbe09eb202c7654 | |
parent | f8b21d0933a06120bcac6981eb022b0c68e199f0 (diff) | |
download | busybox-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.c | 14 |
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 | |||
44 | typedef union { | 46 | typedef 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 | */ | ||
60 | struct BUG_zip_header_must_be_26_bytes { | 66 | struct 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); |