1 /*- 2 * Copyright (c) 2003-2007 Tim Kientzle 3 * Copyright (c) 2012 Michihiro NAKAJIMA 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include "archive_platform.h" 28 29 __FBSDID("$FreeBSD$"); 30 31 #ifdef HAVE_UNISTD_H 32 #include <unistd.h> 33 #endif 34 #ifdef HAVE_ERRNO_H 35 #include <errno.h> 36 #endif 37 #ifdef HAVE_STDLIB_H 38 #include <stdlib.h> 39 #endif 40 #ifdef HAVE_STRING_H 41 #include <string.h> 42 #endif 43 #ifdef HAVE_UNISTD_H 44 #include <unistd.h> 45 #endif 46 #ifdef HAVE_LZO_LZOCONF_H 47 #include <lzo/lzoconf.h> 48 #endif 49 #ifdef HAVE_LZO_LZO1X_H 50 #include <lzo/lzo1x.h> 51 #endif 52 #ifdef HAVE_ZLIB_H 53 #include <zlib.h> /* for crc32 and adler32 */ 54 #endif 55 56 #include "archive.h" 57 #if !defined(HAVE_ZLIB_H) &&\ 58 defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) 59 #include "archive_crc32.h" 60 #endif 61 #include "archive_endian.h" 62 #include "archive_private.h" 63 #include "archive_read_private.h" 64 65 #ifndef HAVE_ZLIB_H 66 #define adler32 lzo_adler32 67 #endif 68 69 #define LZOP_HEADER_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a" 70 #define LZOP_HEADER_MAGIC_LEN 9 71 72 #if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) 73 struct read_lzop { 74 unsigned char *out_block; 75 size_t out_block_size; 76 int64_t total_out; 77 int flags; 78 uint32_t compressed_cksum; 79 uint32_t uncompressed_cksum; 80 size_t compressed_size; 81 size_t uncompressed_size; 82 size_t unconsumed_bytes; 83 char in_stream; 84 char eof; /* True = found end of compressed data. */ 85 }; 86 87 #define FILTER 0x0800 88 #define CRC32_HEADER 0x1000 89 #define EXTRA_FIELD 0x0040 90 #define ADLER32_UNCOMPRESSED 0x0001 91 #define ADLER32_COMPRESSED 0x0002 92 #define CRC32_UNCOMPRESSED 0x0100 93 #define CRC32_COMPRESSED 0x0200 94 #define MAX_BLOCK_SIZE (64 * 1024 * 1024) 95 96 static ssize_t lzop_filter_read(struct archive_read_filter *, const void **); 97 static int lzop_filter_close(struct archive_read_filter *); 98 #endif 99 100 static int lzop_bidder_bid(struct archive_read_filter_bidder *, 101 struct archive_read_filter *); 102 static int lzop_bidder_init(struct archive_read_filter *); 103 104 static const struct archive_read_filter_bidder_vtable 105 lzop_bidder_vtable = { 106 .bid = lzop_bidder_bid, 107 .init = lzop_bidder_init, 108 }; 109 110 int 111 archive_read_support_filter_lzop(struct archive *_a) 112 { 113 struct archive_read *a = (struct archive_read *)_a; 114 115 if (__archive_read_register_bidder(a, NULL, NULL, 116 &lzop_bidder_vtable) != ARCHIVE_OK) 117 return (ARCHIVE_FATAL); 118 119 /* Signal the extent of lzop support with the return value here. */ 120 #if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) 121 return (ARCHIVE_OK); 122 #else 123 /* Return ARCHIVE_WARN since this always uses an external program. */ 124 archive_set_error(_a, ARCHIVE_ERRNO_MISC, 125 "Using external lzop program for lzop decompression"); 126 return (ARCHIVE_WARN); 127 #endif 128 } 129 130 /* 131 * Bidder just verifies the header and returns the number of verified bits. 132 */ 133 static int 134 lzop_bidder_bid(struct archive_read_filter_bidder *self, 135 struct archive_read_filter *filter) 136 { 137 const unsigned char *p; 138 ssize_t avail; 139 140 (void)self; /* UNUSED */ 141 142 p = __archive_read_filter_ahead(filter, LZOP_HEADER_MAGIC_LEN, &avail); 143 if (p == NULL || avail == 0) 144 return (0); 145 146 if (memcmp(p, LZOP_HEADER_MAGIC, LZOP_HEADER_MAGIC_LEN)) 147 return (0); 148 149 return (LZOP_HEADER_MAGIC_LEN * 8); 150 } 151 152 #if !defined(HAVE_LZO_LZOCONF_H) || !defined(HAVE_LZO_LZO1X_H) 153 /* 154 * If we don't have the library on this system, we can't do the 155 * decompression directly. We can, however, try to run "lzop -d" 156 * in case that's available. 157 */ 158 static int 159 lzop_bidder_init(struct archive_read_filter *self) 160 { 161 int r; 162 163 r = __archive_read_program(self, "lzop -d"); 164 /* Note: We set the format here even if __archive_read_program() 165 * above fails. We do, after all, know what the format is 166 * even if we weren't able to read it. */ 167 self->code = ARCHIVE_FILTER_LZOP; 168 self->name = "lzop"; 169 return (r); 170 } 171 #else 172 173 static const struct archive_read_filter_vtable 174 lzop_reader_vtable = { 175 .read = lzop_filter_read, 176 .close = lzop_filter_close 177 }; 178 179 /* 180 * Initialize the filter object. 181 */ 182 static int 183 lzop_bidder_init(struct archive_read_filter *self) 184 { 185 struct read_lzop *state; 186 187 self->code = ARCHIVE_FILTER_LZOP; 188 self->name = "lzop"; 189 190 state = (struct read_lzop *)calloc(sizeof(*state), 1); 191 if (state == NULL) { 192 archive_set_error(&self->archive->archive, ENOMEM, 193 "Can't allocate data for lzop decompression"); 194 return (ARCHIVE_FATAL); 195 } 196 197 self->data = state; 198 self->vtable = &lzop_reader_vtable; 199 200 return (ARCHIVE_OK); 201 } 202 203 static int 204 consume_header(struct archive_read_filter *self) 205 { 206 struct read_lzop *state = (struct read_lzop *)self->data; 207 const unsigned char *p, *_p; 208 unsigned checksum, flags, len, method, version; 209 210 /* 211 * Check LZOP magic code. 212 */ 213 p = __archive_read_filter_ahead(self->upstream, 214 LZOP_HEADER_MAGIC_LEN, NULL); 215 if (p == NULL) 216 return (ARCHIVE_EOF); 217 218 if (memcmp(p, LZOP_HEADER_MAGIC, LZOP_HEADER_MAGIC_LEN)) 219 return (ARCHIVE_EOF); 220 __archive_read_filter_consume(self->upstream, 221 LZOP_HEADER_MAGIC_LEN); 222 223 p = __archive_read_filter_ahead(self->upstream, 29, NULL); 224 if (p == NULL) 225 goto truncated; 226 _p = p; 227 version = archive_be16dec(p); 228 p += 4;/* version(2 bytes) + library version(2 bytes) */ 229 230 if (version >= 0x940) { 231 unsigned reqversion = archive_be16dec(p); p += 2; 232 if (reqversion < 0x900) { 233 archive_set_error(&self->archive->archive, 234 ARCHIVE_ERRNO_MISC, "Invalid required version"); 235 return (ARCHIVE_FAILED); 236 } 237 } 238 239 method = *p++; 240 if (method < 1 || method > 3) { 241 archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, 242 "Unsupported method"); 243 return (ARCHIVE_FAILED); 244 } 245 246 if (version >= 0x940) { 247 unsigned level = *p++; 248 #if 0 249 unsigned default_level[] = {0, 3, 1, 9}; 250 #endif 251 if (level == 0) 252 /* Method is 1..3 here due to check above. */ 253 #if 0 /* Avoid an error Clang Static Analyzer claims 254 "Value stored to 'level' is never read". */ 255 level = default_level[method]; 256 #else 257 ;/* NOP */ 258 #endif 259 else if (level > 9) { 260 archive_set_error(&self->archive->archive, 261 ARCHIVE_ERRNO_MISC, "Invalid level"); 262 return (ARCHIVE_FAILED); 263 } 264 } 265 266 flags = archive_be32dec(p); p += 4; 267 268 if (flags & FILTER) 269 p += 4; /* Skip filter */ 270 p += 4; /* Skip mode */ 271 if (version >= 0x940) 272 p += 8; /* Skip mtime */ 273 else 274 p += 4; /* Skip mtime */ 275 len = *p++; /* Read filename length */ 276 len += p - _p; 277 /* Make sure we have all bytes we need to calculate checksum. */ 278 p = __archive_read_filter_ahead(self->upstream, len + 4, NULL); 279 if (p == NULL) 280 goto truncated; 281 if (flags & CRC32_HEADER) 282 checksum = crc32(crc32(0, NULL, 0), p, len); 283 else 284 checksum = adler32(adler32(0, NULL, 0), p, len); 285 if (archive_be32dec(p + len) != checksum) 286 #ifndef DONT_FAIL_ON_CRC_ERROR 287 goto corrupted; 288 #endif 289 __archive_read_filter_consume(self->upstream, len + 4); 290 if (flags & EXTRA_FIELD) { 291 /* Skip extra field */ 292 p = __archive_read_filter_ahead(self->upstream, 4, NULL); 293 if (p == NULL) 294 goto truncated; 295 len = archive_be32dec(p); 296 __archive_read_filter_consume(self->upstream, len + 4 + 4); 297 } 298 state->flags = flags; 299 state->in_stream = 1; 300 return (ARCHIVE_OK); 301 truncated: 302 archive_set_error(&self->archive->archive, 303 ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data"); 304 return (ARCHIVE_FAILED); 305 corrupted: 306 archive_set_error(&self->archive->archive, 307 ARCHIVE_ERRNO_FILE_FORMAT, "Corrupted lzop header"); 308 return (ARCHIVE_FAILED); 309 } 310 311 static int 312 consume_block_info(struct archive_read_filter *self) 313 { 314 struct read_lzop *state = (struct read_lzop *)self->data; 315 const unsigned char *p; 316 unsigned flags = state->flags; 317 318 p = __archive_read_filter_ahead(self->upstream, 4, NULL); 319 if (p == NULL) 320 goto truncated; 321 state->uncompressed_size = archive_be32dec(p); 322 __archive_read_filter_consume(self->upstream, 4); 323 if (state->uncompressed_size == 0) 324 return (ARCHIVE_EOF); 325 if (state->uncompressed_size > MAX_BLOCK_SIZE) 326 goto corrupted; 327 328 p = __archive_read_filter_ahead(self->upstream, 4, NULL); 329 if (p == NULL) 330 goto truncated; 331 state->compressed_size = archive_be32dec(p); 332 __archive_read_filter_consume(self->upstream, 4); 333 if (state->compressed_size > state->uncompressed_size) 334 goto corrupted; 335 336 if (flags & (CRC32_UNCOMPRESSED | ADLER32_UNCOMPRESSED)) { 337 p = __archive_read_filter_ahead(self->upstream, 4, NULL); 338 if (p == NULL) 339 goto truncated; 340 state->compressed_cksum = state->uncompressed_cksum = 341 archive_be32dec(p); 342 __archive_read_filter_consume(self->upstream, 4); 343 } 344 if ((flags & (CRC32_COMPRESSED | ADLER32_COMPRESSED)) && 345 state->compressed_size < state->uncompressed_size) { 346 p = __archive_read_filter_ahead(self->upstream, 4, NULL); 347 if (p == NULL) 348 goto truncated; 349 state->compressed_cksum = archive_be32dec(p); 350 __archive_read_filter_consume(self->upstream, 4); 351 } 352 return (ARCHIVE_OK); 353 truncated: 354 archive_set_error(&self->archive->archive, 355 ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data"); 356 return (ARCHIVE_FAILED); 357 corrupted: 358 archive_set_error(&self->archive->archive, 359 ARCHIVE_ERRNO_FILE_FORMAT, "Corrupted lzop header"); 360 return (ARCHIVE_FAILED); 361 } 362 363 static ssize_t 364 lzop_filter_read(struct archive_read_filter *self, const void **p) 365 { 366 struct read_lzop *state = (struct read_lzop *)self->data; 367 const void *b; 368 lzo_uint out_size; 369 uint32_t cksum; 370 int ret, r; 371 372 if (state->unconsumed_bytes) { 373 __archive_read_filter_consume(self->upstream, 374 state->unconsumed_bytes); 375 state->unconsumed_bytes = 0; 376 } 377 if (state->eof) 378 return (0); 379 380 for (;;) { 381 if (!state->in_stream) { 382 ret = consume_header(self); 383 if (ret < ARCHIVE_OK) 384 return (ret); 385 if (ret == ARCHIVE_EOF) { 386 state->eof = 1; 387 return (0); 388 } 389 } 390 ret = consume_block_info(self); 391 if (ret < ARCHIVE_OK) 392 return (ret); 393 if (ret == ARCHIVE_EOF) 394 state->in_stream = 0; 395 else 396 break; 397 } 398 399 if (state->out_block == NULL || 400 state->out_block_size < state->uncompressed_size) { 401 void *new_block; 402 403 new_block = realloc(state->out_block, state->uncompressed_size); 404 if (new_block == NULL) { 405 archive_set_error(&self->archive->archive, ENOMEM, 406 "Can't allocate data for lzop decompression"); 407 return (ARCHIVE_FATAL); 408 } 409 state->out_block = new_block; 410 state->out_block_size = state->uncompressed_size; 411 } 412 413 b = __archive_read_filter_ahead(self->upstream, 414 state->compressed_size, NULL); 415 if (b == NULL) { 416 archive_set_error(&self->archive->archive, 417 ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data"); 418 return (ARCHIVE_FATAL); 419 } 420 if (state->flags & CRC32_COMPRESSED) 421 cksum = crc32(crc32(0, NULL, 0), b, state->compressed_size); 422 else if (state->flags & ADLER32_COMPRESSED) 423 cksum = adler32(adler32(0, NULL, 0), b, state->compressed_size); 424 else 425 cksum = state->compressed_cksum; 426 if (cksum != state->compressed_cksum) { 427 archive_set_error(&self->archive->archive, 428 ARCHIVE_ERRNO_MISC, "Corrupted data"); 429 return (ARCHIVE_FATAL); 430 } 431 432 /* 433 * If the both uncompressed size and compressed size are the same, 434 * we do not decompress this block. 435 */ 436 if (state->uncompressed_size == state->compressed_size) { 437 *p = b; 438 state->total_out += state->compressed_size; 439 state->unconsumed_bytes = state->compressed_size; 440 return ((ssize_t)state->uncompressed_size); 441 } 442 443 /* 444 * Drive lzo uncompression. 445 */ 446 out_size = (lzo_uint)state->uncompressed_size; 447 r = lzo1x_decompress_safe(b, (lzo_uint)state->compressed_size, 448 state->out_block, &out_size, NULL); 449 switch (r) { 450 case LZO_E_OK: 451 if (out_size == state->uncompressed_size) 452 break; 453 archive_set_error(&self->archive->archive, 454 ARCHIVE_ERRNO_MISC, "Corrupted data"); 455 return (ARCHIVE_FATAL); 456 case LZO_E_OUT_OF_MEMORY: 457 archive_set_error(&self->archive->archive, ENOMEM, 458 "lzop decompression failed: out of memory"); 459 return (ARCHIVE_FATAL); 460 default: 461 archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, 462 "lzop decompression failed: %d", r); 463 return (ARCHIVE_FATAL); 464 } 465 466 if (state->flags & CRC32_UNCOMPRESSED) 467 cksum = crc32(crc32(0, NULL, 0), state->out_block, 468 state->uncompressed_size); 469 else if (state->flags & ADLER32_UNCOMPRESSED) 470 cksum = adler32(adler32(0, NULL, 0), state->out_block, 471 state->uncompressed_size); 472 else 473 cksum = state->uncompressed_cksum; 474 if (cksum != state->uncompressed_cksum) { 475 archive_set_error(&self->archive->archive, 476 ARCHIVE_ERRNO_MISC, "Corrupted data"); 477 return (ARCHIVE_FATAL); 478 } 479 480 __archive_read_filter_consume(self->upstream, state->compressed_size); 481 *p = state->out_block; 482 state->total_out += out_size; 483 return ((ssize_t)out_size); 484 } 485 486 /* 487 * Clean up the decompressor. 488 */ 489 static int 490 lzop_filter_close(struct archive_read_filter *self) 491 { 492 struct read_lzop *state = (struct read_lzop *)self->data; 493 494 free(state->out_block); 495 free(state); 496 return (ARCHIVE_OK); 497 } 498 499 #endif 500