From 487c5fd319a3d85694d52fb81b3e3b5c7d09a54d Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 16 Mar 2023 08:56:14 -0700 Subject: [PATCH] libsparse: Propagate failures when resparsing files. MappedFile creation can fail due to out of memory, but this condition is not handled properly when resparsing. The error is silently ignored and the result is a corrupt file. Bug: 273933042 Bug: 268872725 Test: fastboot update on Windows Google: 2495615 Change-Id: I4d0f24d6ba390e2328de8f0e3637d17663743df5 Signed-off-by: CxDxVER --- libsparse/sparse.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/libsparse/sparse.cpp b/libsparse/sparse.cpp index 396e7eb0c582..ca7e5fe62666 100644 --- a/libsparse/sparse.cpp +++ b/libsparse/sparse.cpp @@ -260,8 +260,8 @@ unsigned int sparse_file_block_size(struct sparse_file* s) { return s->block_size; } -static struct backed_block* move_chunks_up_to_len(struct sparse_file* from, struct sparse_file* to, - unsigned int len) { +static int move_chunks_up_to_len(struct sparse_file* from, struct sparse_file* to, unsigned int len, + backed_block** out_bb) { int64_t count = 0; struct output_file* out_counter; struct backed_block* last_bb = nullptr; @@ -282,7 +282,7 @@ static struct backed_block* move_chunks_up_to_len(struct sparse_file* from, stru out_counter = output_file_open_callback(out_counter_write, &count, to->block_size, to->len, false, true, 0, false); if (!out_counter) { - return nullptr; + return -1; } for (bb = start; bb; bb = backed_block_iter_next(bb)) { @@ -319,7 +319,8 @@ static struct backed_block* move_chunks_up_to_len(struct sparse_file* from, stru out: output_file_close(out_counter); - return bb; + *out_bb = bb; + return 0; } int sparse_file_resparse(struct sparse_file* in_s, unsigned int max_len, struct sparse_file** out_s, @@ -337,7 +338,15 @@ int sparse_file_resparse(struct sparse_file* in_s, unsigned int max_len, struct do { s = sparse_file_new(in_s->block_size, in_s->len); - bb = move_chunks_up_to_len(in_s, s, max_len); + if (move_chunks_up_to_len(in_s, s, max_len, &bb) < 0) { + sparse_file_destroy(s); + for (int i = 0; i < c && i < out_s_count; i++) { + sparse_file_destroy(out_s[i]); + out_s[i] = nullptr; + } + sparse_file_destroy(tmp); + return -1; + } if (c < out_s_count) { out_s[c] = s;