libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \
libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \
libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu \
+ libarchive/test/test_read_format_rar5_data_ready_pointer_leak.rar.uu \
libarchive/test/test_read_format_raw.bufr.uu \
libarchive/test/test_read_format_raw.data.gz.uu \
libarchive/test/test_read_format_raw.data.Z.uu \
static int rar5_read_data_skip(struct archive_read *a);
static int push_data_ready(struct archive_read* a, struct rar5* rar,
const uint8_t* buf, size_t size, int64_t offset);
+static void clear_data_ready_stack(struct rar5* rar);
/* CDE_xxx = Circular Double Ended (Queue) return values. */
enum CDE_RETURN_VALUES {
int ret;
struct rar5* rar = get_context(a);
+ clear_data_ready_stack(rar);
free(rar->cstate.filtered_buf);
rar->cstate.filtered_buf = malloc(flt->block_length);
if(rar->cstate.window_size < (ssize_t) window_size &&
rar->cstate.window_buf)
{
+ /* The `data_ready` stack contains pointers to the `window_buf` or
+ * `filtered_buf` buffers. Since we're about to reallocate the first
+ * buffer, some of those pointers could become invalid. Therefore, we
+ * need to dispose of all entries from the stack before attempting the
+ * realloc. */
+ clear_data_ready_stack(rar);
+
/* If window_buf has been allocated before, reallocate it, so
* that its size will match new window_size. */
rar->cstate.filtered_buf = NULL;
}
+ clear_data_ready_stack(rar);
+
rar->cstate.write_ptr = 0;
rar->cstate.last_write_ptr = 0;
return ARCHIVE_RETRY;
}
+static void clear_data_ready_stack(struct rar5* rar) {
+ memset(&rar->cstate.dready, 0, sizeof(rar->cstate.dready));
+}
+
/* Pushes the `buf`, `size` and `offset` arguments to the rar->cstate.dready
* FIFO stack. Those values will be popped from this stack by the `use_data`
* function. */
free(rar->cstate.window_buf);
free(rar->cstate.filtered_buf);
+ clear_data_ready_stack(rar);
free(rar->vol.push_buf);
assertA(size == archive_read_data(a, buff, size));
assertEqualMem(buff, test_txt, size);
-
+
EPILOGUE();
}
EPILOGUE();
}
+
+DEFINE_TEST(test_read_format_rar5_data_ready_pointer_leak)
+{
+ /* oss fuzz 70024 */
+
+ char buf[4096];
+ PROLOGUE("test_read_format_rar5_data_ready_pointer_leak.rar");
+
+ /* Return codes of those calls are ignored, because this sample file
+ * is invalid. However, the unpacker shouldn't produce any SIGSEGV
+ * errors during processing. */
+
+ (void) archive_read_next_header(a, &ae);
+ (void) archive_read_data(a, buf, sizeof(buf));
+ (void) archive_read_next_header(a, &ae);
+ (void) archive_read_data(a, buf, sizeof(buf));
+ (void) archive_read_data(a, buf, sizeof(buf));
+ (void) archive_read_next_header(a, &ae);
+ /* This call shouldn't produce SIGSEGV. */
+ (void) archive_read_data(a, buf, sizeof(buf));
+
+ EPILOGUE();
+}
--- /dev/null
+begin 644 test_read_format_rar5_data_ready_pointer_leak.rar.uu
+M4F%R(1H'`0`]/-[E`@$`_R`@1#[Z5P("`P,`(/__(""`((``"2`@("`@_R`@
+M("`@(%.`*O0#`N<B`A"`("#_((`+`00@("`@(""!)/\@("`@("`@(/\@("`@
+M^I@R<00"WN<-\@$@_R`@(``C("`@("`@("`@("`@("`@("`@("`@("`@("#_
+M____("`@(/___R#_("`@("`@("#___\@_____R`@("`@("`@(/__________
+M____(/__(/\@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@________
+M_________R`@____(/____\@("`@("`@("#______________R#___\@("`@
+M("`@("`@("`@("`@("`@("`@(/\@("`@("`@("`@("`@("`@("`@("`@("`@
+M("`@("`@("`@("`@("`@("`@("`@("`@_________R`@("`@_R`@("`@("`@
+M("`@("`@(/__("`@("`@("`@("`@("`@(%.`*O0#`N<B`A"`_R`@_R#_"P$$
+M("`@("`@@23_("`@_R`@("#_("`@(/J8,G$$`M[G#?(!(/\@("``(R`@("`@
+M("`@("`@("`@("`@("`@("`@("#_("`@("`@("#_("`@("`@("`@("`@("`@
+M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("#_
+M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@____("`@("`@
+M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
+M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
+M("`@("`@("`@("`@("`@("`@_R`@("`@("`@("`@("`@("`@("`@("`@("`@
+M("!3@"KT`P+G(B`0@/\@(/\@_PL!_R"!)/\@("`@("`@(/\@("`@^I@R<00"
+MWN<-\@$@_R`@(``C("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
+M("`@("#______________R`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
+M("`@("`@("`@("`@("`@("`@("`@(/\@(/_______R`@("`@("`@("`@("`@
+M("`@("`@("`@_________R`@("`@("`@("`@("`@("`@(/________\@("`@
+M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(/\@
+M("`@("`@(/\@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
+M("`@("`@("`@("`@("`@(/\@($0^^E<"`@,#("`@(/\@@``)("`@("`@("`@
+)("`@("`@("`@
+`
+end