blob: f63bcc1090d722fc7f1504620f9cfb50c267b53b [file] [log] [blame]
From 77797b83e8d9ed0f691fb8cb1900de071ad68329 Mon Sep 17 00:00:00 2001
From: Daniel Verkamp <dverkamp@chromium.org>
Date: Fri, 4 Oct 2019 12:31:32 -0700
Subject: [PATCH] Fix sparse file offset overflow on 32-bit systems
On architectures where size_t is 32 bits but file offsets are 64 bits
(such as 32-bit Linux with _FILE_OFFSET_BITS=64), the POSIX disk reader
would incorrectly skip large sparse regions due to a 32-bit integer
overflow in _archive_read_data_block().
The bytes variable was used to store the difference between two 64-bit
integers, but bytes is a size_t. Since this value of bytes was not used
after the block handling sparse offsets (it is always overwritten in the
block below), replace it with an int64_t sparse_bytes variable that can
always represent the difference without truncation.
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
---
libarchive/archive_read_disk_posix.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c
index 87963c3c..f62d182e 100644
--- a/libarchive/archive_read_disk_posix.c
+++ b/libarchive/archive_read_disk_posix.c
@@ -694,6 +694,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
struct tree *t = a->tree;
int r;
ssize_t bytes;
+ int64_t sparse_bytes;
size_t buffbytes;
int empty_sparse_region = 0;
@@ -792,9 +793,9 @@ _archive_read_data_block(struct archive *_a, const void **buff,
a->archive.state = ARCHIVE_STATE_FATAL;
goto abort_read_data;
}
- bytes = t->current_sparse->offset - t->entry_total;
- t->entry_remaining_bytes -= bytes;
- t->entry_total += bytes;
+ sparse_bytes = t->current_sparse->offset - t->entry_total;
+ t->entry_remaining_bytes -= sparse_bytes;
+ t->entry_total += sparse_bytes;
}
/*
--
2.23.0.581.g78d2f28ef7-goog