journal: make journal_file_copy_entry() robust towards copying invalid/half-written source journal files (#37732)

This commit is contained in:
Lennart Poettering
2025-06-04 20:51:24 +02:00
committed by GitHub
2 changed files with 28 additions and 20 deletions
+19 -15
View File
@@ -376,15 +376,14 @@ int decompress_blob_xz(
size_t used;
ret = sym_lzma_code(&s, LZMA_FINISH);
if (ret == LZMA_STREAM_END)
break;
else if (ret != LZMA_OK)
if (ret != LZMA_OK)
return -ENOMEM;
if (dst_max > 0 && (space - s.avail_out) >= dst_max)
break;
else if (dst_max > 0 && space == dst_max)
if (dst_max > 0 && space == dst_max)
return -ENOBUFS;
used = space - s.avail_out;
@@ -510,20 +509,22 @@ int decompress_blob(
size_t* dst_size,
size_t dst_max) {
if (compression == COMPRESSION_XZ)
switch (compression) {
case COMPRESSION_XZ:
return decompress_blob_xz(
src, src_size,
dst, dst_size, dst_max);
else if (compression == COMPRESSION_LZ4)
case COMPRESSION_LZ4:
return decompress_blob_lz4(
src, src_size,
dst, dst_size, dst_max);
else if (compression == COMPRESSION_ZSTD)
case COMPRESSION_ZSTD:
return decompress_blob_zstd(
src, src_size,
dst, dst_size, dst_max);
else
default:
return -EPROTONOSUPPORT;
}
}
int decompress_startswith_xz(
@@ -734,27 +735,30 @@ int decompress_startswith(
size_t prefix_len,
uint8_t extra) {
if (compression == COMPRESSION_XZ)
switch (compression) {
case COMPRESSION_XZ:
return decompress_startswith_xz(
src, src_size,
buffer,
prefix, prefix_len,
extra);
else if (compression == COMPRESSION_LZ4)
case COMPRESSION_LZ4:
return decompress_startswith_lz4(
src, src_size,
buffer,
prefix, prefix_len,
extra);
else if (compression == COMPRESSION_ZSTD)
case COMPRESSION_ZSTD:
return decompress_startswith_zstd(
src, src_size,
buffer,
prefix, prefix_len,
extra);
else
default:
return -EBADMSG;
}
}
int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes, uint64_t *ret_uncompressed_size) {
@@ -1318,10 +1322,10 @@ int decompress_stream(const char *filename, int fdf, int fdt, uint64_t max_bytes
if (endswith(filename, ".lz4"))
return decompress_stream_lz4(fdf, fdt, max_bytes);
else if (endswith(filename, ".xz"))
if (endswith(filename, ".xz"))
return decompress_stream_xz(fdf, fdt, max_bytes);
else if (endswith(filename, ".zst"))
if (endswith(filename, ".zst"))
return decompress_stream_zstd(fdf, fdt, max_bytes);
else
return -EPROTONOSUPPORT;
return -EPROTONOSUPPORT;
}
+9 -5
View File
@@ -1842,8 +1842,11 @@ static int journal_file_append_data(
assert(f);
/* Return a recognizable error for data that is submitted for *writing*. Note that we leave EBADMSG
* for bad messages we *read*. And EINVAL is too generic an error (which might be triggered by all
* kinds of other places). Hence use a separate EUCLEAN here. */
if (!data || size == 0)
return -EINVAL;
return -EUCLEAN;
hash = journal_file_hash_data(f, data, size);
@@ -1855,7 +1858,7 @@ static int journal_file_append_data(
eq = memchr(data, '=', size);
if (!eq)
return -EINVAL;
return -EUCLEAN;
osize = journal_file_data_payload_offset(f) + size;
r = journal_file_append_object(f, OBJECT_DATA, osize, &o, &p);
@@ -4456,10 +4459,11 @@ int journal_file_copy_entry(
return r;
assert(r > 0);
if (l == 0)
return -EBADMSG;
r = journal_file_append_data(to, data, l, &u, &h);
if (r == -EUCLEAN) {
log_debug_errno(r, "Entry item %"PRIu64" invalid, skipping over it: %m", i);
continue;
}
if (r < 0)
return r;