X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fcompress.c;h=383f6a6e9665b84ac280b9d3c57e8f0f847c4f70;hb=c85770ad84af4bcaace5055147d53da6fe28ef9a;hp=49d694ac28273f751f909c3bbf7dfe17bf3eb6e4;hpb=d89c8fdf48c7bad5816b9f2e77e8361721f22517;p=elogind.git diff --git a/src/journal/compress.c b/src/journal/compress.c index 49d694ac2..383f6a6e9 100644 --- a/src/journal/compress.c +++ b/src/journal/compress.c @@ -19,7 +19,6 @@ along with systemd; If not, see . ***/ -#include #include #include #include @@ -47,8 +46,15 @@ static const char* const object_compressed_table[_OBJECT_COMPRESSED_MAX] = { DEFINE_STRING_TABLE_LOOKUP(object_compressed, int); -int compress_blob_xz(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size) { +int compress_blob_xz(const void *src, uint64_t src_size, void *dst, size_t *dst_size) { #ifdef HAVE_XZ + static const lzma_options_lzma opt = { + 1u << 20u, NULL, 0, LZMA_LC_DEFAULT, LZMA_LP_DEFAULT, + LZMA_PB_DEFAULT, LZMA_MODE_FAST, 128, LZMA_MF_HC3, 4}; + static const lzma_filter filters[2] = { + {LZMA_FILTER_LZMA2, (lzma_options_lzma*) &opt}, + {LZMA_VLI_UNKNOWN, NULL} + }; lzma_ret ret; size_t out_pos = 0; @@ -60,8 +66,11 @@ int compress_blob_xz(const void *src, uint64_t src_size, void *dst, uint64_t *ds /* Returns < 0 if we couldn't compress the data or the * compressed result is longer than the original */ - ret = lzma_easy_buffer_encode(LZMA_PRESET_DEFAULT, LZMA_CHECK_NONE, NULL, - src, src_size, dst, &out_pos, src_size - 1); + if (src_size < 80) + return -ENOBUFS; + + ret = lzma_stream_buffer_encode((lzma_filter*) filters, LZMA_CHECK_NONE, NULL, + src, src_size, dst, &out_pos, src_size - 1); if (ret != LZMA_OK) return -ENOBUFS; @@ -72,7 +81,7 @@ int compress_blob_xz(const void *src, uint64_t src_size, void *dst, uint64_t *ds #endif } -int compress_blob_lz4(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size) { +int compress_blob_lz4(const void *src, uint64_t src_size, void *dst, size_t *dst_size) { #ifdef HAVE_LZ4 int r; @@ -102,12 +111,12 @@ int compress_blob_lz4(const void *src, uint64_t src_size, void *dst, uint64_t *d int decompress_blob_xz(const void *src, uint64_t src_size, - void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size, uint64_t dst_max) { + void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) { #ifdef HAVE_XZ _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT; lzma_ret ret; - uint64_t space; + size_t space; assert(src); assert(src_size > 0); @@ -120,9 +129,9 @@ int decompress_blob_xz(const void *src, uint64_t src_size, if (ret != LZMA_OK) return -ENOMEM; - space = MIN(src_size * 2, dst_max ?: (uint64_t) -1); + space = MIN(src_size * 2, dst_max ?: (size_t) -1); if (!greedy_realloc(dst, dst_alloc_size, space, 1)) - return false; + return -ENOMEM; s.next_in = src; s.avail_in = src_size; @@ -131,7 +140,7 @@ int decompress_blob_xz(const void *src, uint64_t src_size, s.avail_out = space; for (;;) { - uint64_t used; + size_t used; ret = lzma_code(&s, LZMA_FINISH); @@ -146,9 +155,9 @@ int decompress_blob_xz(const void *src, uint64_t src_size, return -ENOBUFS; used = space - s.avail_out; - space = MIN(2 * space, dst_max ?: (uint64_t) -1); + space = MIN(2 * space, dst_max ?: (size_t) -1); if (!greedy_realloc(dst, dst_alloc_size, space, 1)) - return false; + return -ENOMEM; s.avail_out = space - used; s.next_out = *dst + used; @@ -162,12 +171,11 @@ int decompress_blob_xz(const void *src, uint64_t src_size, } int decompress_blob_lz4(const void *src, uint64_t src_size, - void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size, uint64_t dst_max) { + void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) { #ifdef HAVE_LZ4 char* out; - uint64_t size; - int r; + int r, size; /* LZ4 uses int for size */ assert(src); assert(src_size > 0); @@ -180,7 +188,9 @@ int decompress_blob_lz4(const void *src, uint64_t src_size, return -EBADMSG; size = le64toh( *(le64_t*)src ); - if (size > *dst_alloc_size) { + if (size < 0 || (le64_t) size != *(le64_t*)src) + return -EFBIG; + if ((size_t) size > *dst_alloc_size) { out = realloc(*dst, size); if (!out) return -ENOMEM; @@ -190,7 +200,7 @@ int decompress_blob_lz4(const void *src, uint64_t src_size, out = *dst; r = LZ4_decompress_safe(src + 8, out, src_size - 8, size); - if (r < 0 || (uint64_t) r != size) + if (r < 0 || r != size) return -EBADMSG; *dst_size = size; @@ -202,7 +212,7 @@ int decompress_blob_lz4(const void *src, uint64_t src_size, int decompress_blob(int compression, const void *src, uint64_t src_size, - void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size, uint64_t dst_max) { + void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) { if (compression == OBJECT_COMPRESSED_XZ) return decompress_blob_xz(src, src_size, dst, dst_alloc_size, dst_size, dst_max); @@ -215,8 +225,8 @@ int decompress_blob(int compression, int decompress_startswith_xz(const void *src, uint64_t src_size, - void **buffer, uint64_t *buffer_size, - const void *prefix, uint64_t prefix_len, + void **buffer, size_t *buffer_size, + const void *prefix, size_t prefix_len, uint8_t extra) { #ifdef HAVE_XZ @@ -274,8 +284,8 @@ int decompress_startswith_xz(const void *src, uint64_t src_size, } int decompress_startswith_lz4(const void *src, uint64_t src_size, - void **buffer, uint64_t *buffer_size, - const void *prefix, uint64_t prefix_len, + void **buffer, size_t *buffer_size, + const void *prefix, size_t prefix_len, uint8_t extra) { #ifdef HAVE_LZ4 /* Checks whether the decompressed blob starts with the @@ -315,8 +325,8 @@ int decompress_startswith_lz4(const void *src, uint64_t src_size, int decompress_startswith(int compression, const void *src, uint64_t src_size, - void **buffer, uint64_t *buffer_size, - const void *prefix, uint64_t prefix_len, + void **buffer, size_t *buffer_size, + const void *prefix, size_t prefix_len, uint8_t extra) { if (compression == OBJECT_COMPRESSED_XZ) return decompress_startswith_xz(src, src_size, @@ -333,6 +343,7 @@ int decompress_startswith(int compression, } int compress_stream_xz(int fdf, int fdt, off_t max_bytes) { +#ifdef HAVE_XZ _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT; lzma_ret ret; @@ -344,7 +355,7 @@ int compress_stream_xz(int fdf, int fdt, off_t max_bytes) { ret = lzma_easy_encoder(&s, LZMA_PRESET_DEFAULT, LZMA_CHECK_CRC64); if (ret != LZMA_OK) { - log_error("Failed to initialize XZ encoder: code %d", ret); + log_error("Failed to initialize XZ encoder: code %u", ret); return -EINVAL; } @@ -379,7 +390,7 @@ int compress_stream_xz(int fdf, int fdt, off_t max_bytes) { ret = lzma_code(&s, action); if (ret != LZMA_OK && ret != LZMA_STREAM_END) { - log_error("Compression failed: code %d", ret); + log_error("Compression failed: code %u", ret); return -EBADMSG; } @@ -388,15 +399,12 @@ int compress_stream_xz(int fdf, int fdt, off_t max_bytes) { n = sizeof(out) - s.avail_out; - errno = 0; k = loop_write(fdt, out, n, false); if (k < 0) return k; - if (k != n) - return errno ? -errno : -EIO; if (ret == LZMA_STREAM_END) { - log_debug("XZ compression finished (%zu -> %zu bytes, %.1f%%)", + log_debug("XZ compression finished (%"PRIu64" -> %"PRIu64" bytes, %.1f%%)", s.total_in, s.total_out, (double) s.total_out / s.total_in * 100); @@ -404,6 +412,9 @@ int compress_stream_xz(int fdf, int fdt, off_t max_bytes) { } } } +#else + return -EPROTONOSUPPORT; +#endif } #define LZ4_BUFSIZE (512*1024) @@ -445,10 +456,10 @@ int compress_stream_lz4(int fdf, int fdt, off_t max_bytes) { total_in += n; - r = LZ4_compress_limitedOutput_continue(&lz4_data, buf, out, n, n); + r = LZ4_compress_continue(&lz4_data, buf, out, n); if (r == 0) { - log_debug("Compressed size exceeds original, aborting compression."); - return -ENOBUFS; + log_error("LZ4 compression failed."); + return -EBADMSG; } header = htole32(r); @@ -463,8 +474,6 @@ int compress_stream_lz4(int fdf, int fdt, off_t max_bytes) { n = loop_write(fdt, out, r, false); if (n < 0) return n; - if (n != r) - return errno ? -errno : -EIO; total_out += sizeof(header) + r; @@ -502,7 +511,7 @@ int decompress_stream_xz(int fdf, int fdt, off_t max_bytes) { ret = lzma_stream_decoder(&s, UINT64_MAX, 0); if (ret != LZMA_OK) { - log_error("Failed to initialize XZ decoder: code %d", ret); + log_error("Failed to initialize XZ decoder: code %u", ret); return -ENOMEM; } @@ -528,7 +537,7 @@ int decompress_stream_xz(int fdf, int fdt, off_t max_bytes) { ret = lzma_code(&s, action); if (ret != LZMA_OK && ret != LZMA_STREAM_END) { - log_error("Decompression failed: code %d", ret); + log_error("Decompression failed: code %u", ret); return -EBADMSG; } @@ -544,15 +553,12 @@ int decompress_stream_xz(int fdf, int fdt, off_t max_bytes) { max_bytes -= n; } - errno = 0; k = loop_write(fdt, out, n, false); if (k < 0) return k; - if (k != n) - return errno ? -errno : -EIO; if (ret == LZMA_STREAM_END) { - log_debug("XZ decompression finished (%zu -> %zu bytes, %.1f%%)", + log_debug("XZ decompression finished (%"PRIu64" -> %"PRIu64" bytes, %.1f%%)", s.total_in, s.total_out, (double) s.total_out / s.total_in * 100); @@ -583,14 +589,12 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) { return log_oom(); for (;;) { - ssize_t n, m; + ssize_t m; int r; - n = read(fdf, &header, sizeof(header)); - if (n < 0) - return -errno; - if (n != sizeof(header)) - return errno ? -errno : -EIO; + r = loop_read_exact(fdf, &header, sizeof(header), false); + if (r < 0) + return r; m = le32toh(header); if (m == 0) @@ -612,12 +616,9 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) { if (!GREEDY_REALLOC(buf, buf_size, m)) return log_oom(); - errno = 0; - n = loop_read(fdf, buf, m, false); - if (n < 0) - return n; - if (n != m) - return errno ? -errno : -EIO; + r = loop_read_exact(fdf, buf, m, false); + if (r < 0) + return r; r = LZ4_decompress_safe_continue(&lz4_data, buf, out, m, 4*LZ4_BUFSIZE); if (r <= 0) @@ -630,12 +631,9 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) { return -EFBIG; } - errno = 0; - n = loop_write(fdt, out, r, false); - if (n < 0) - return n; - if (n != r) - return errno ? -errno : -EIO; + r = loop_write(fdt, out, r, false); + if (r < 0) + return r; } log_debug("LZ4 decompression finished (%zu -> %zu bytes, %.1f%%)",