From: Tobias Stoeckmann Date: Wed, 1 Jul 2026 20:38:58 +0000 (+0200) Subject: Check result of archive_read_set_callback_data X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dfcc108ebd6cf67fdbc4e8a4ef061cfbc5ed8b63;p=thirdparty%2Flibarchive.git Check result of archive_read_set_callback_data The memory allocation in archive_read_set_callback_data2, which is called by archive_read_set_callback_data, could fail. Check result and properly handle failure. Resolves #3210. Signed-off-by: Tobias Stoeckmann --- diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c index b23d99dd7..add3ac485 100644 --- a/libarchive/archive_read.c +++ b/libarchive/archive_read.c @@ -135,12 +135,16 @@ archive_read_open(struct archive *a, void *client_data, archive_open_callback *client_opener, archive_read_callback *client_reader, archive_close_callback *client_closer) { + int r; + /* Old archive_read_open() is just a thin shell around * archive_read_open1. */ archive_read_set_open_callback(a, client_opener); archive_read_set_read_callback(a, client_reader); archive_read_set_close_callback(a, client_closer); - archive_read_set_callback_data(a, client_data); + r = archive_read_set_callback_data(a, client_data); + if (r < 0) + return (r); return archive_read_open1(a); } @@ -152,9 +156,13 @@ archive_read_open2(struct archive *a, void *client_data, archive_skip_callback *client_skipper, archive_close_callback *client_closer) { + int r; + /* Old archive_read_open2() is just a thin shell around * archive_read_open1. */ - archive_read_set_callback_data(a, client_data); + r = archive_read_set_callback_data(a, client_data); + if (r < 0) + return (r); archive_read_set_open_callback(a, client_opener); archive_read_set_read_callback(a, client_reader); archive_read_set_skip_callback(a, client_skipper); diff --git a/libarchive/archive_read_open_fd.c b/libarchive/archive_read_open_fd.c index c85a62a3e..358e516fa 100644 --- a/libarchive/archive_read_open_fd.c +++ b/libarchive/archive_read_open_fd.c @@ -69,6 +69,7 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size) la_seek_stat_t st; struct read_fd_data *mine; void *b; + int r; archive_clear_error(a); if (la_seek_fstat(fd, &st) != 0) { @@ -107,7 +108,9 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size) archive_read_set_skip_callback(a, file_skip); archive_read_set_seek_callback(a, file_seek); archive_read_set_close_callback(a, file_close); - archive_read_set_callback_data(a, mine); + r = archive_read_set_callback_data(a, mine); + if (r < 0) + return (r); return (archive_read_open1(a)); } diff --git a/libarchive/archive_read_open_file.c b/libarchive/archive_read_open_file.c index 6ca2ff191..e82069e50 100644 --- a/libarchive/archive_read_open_file.c +++ b/libarchive/archive_read_open_file.c @@ -70,6 +70,7 @@ archive_read_open_FILE(struct archive *a, FILE *f) struct read_FILE_data *mine; size_t block_size = 128 * 1024; void *b; + int r; archive_clear_error(a); mine = calloc(1, sizeof(*mine)); @@ -104,7 +105,9 @@ archive_read_open_FILE(struct archive *a, FILE *f) archive_read_set_skip_callback(a, FILE_skip); archive_read_set_seek_callback(a, FILE_seek); archive_read_set_close_callback(a, FILE_close); - archive_read_set_callback_data(a, mine); + r = archive_read_set_callback_data(a, mine); + if (r < 0) + return (r); return (archive_read_open1(a)); } diff --git a/libarchive/archive_read_open_memory.c b/libarchive/archive_read_open_memory.c index 460bb5ae6..441662d46 100644 --- a/libarchive/archive_read_open_memory.c +++ b/libarchive/archive_read_open_memory.c @@ -68,6 +68,7 @@ archive_read_open_memory2(struct archive *a, const void *buff, size_t size, size_t read_size) { struct read_memory_data *mine; + int r; mine = calloc(1, sizeof(*mine)); if (mine == NULL) { @@ -82,7 +83,9 @@ archive_read_open_memory2(struct archive *a, const void *buff, archive_read_set_seek_callback(a, memory_read_seek); archive_read_set_skip_callback(a, memory_read_skip); archive_read_set_close_callback(a, memory_read_close); - archive_read_set_callback_data(a, mine); + r = archive_read_set_callback_data(a, mine); + if (r < 0) + return (r); return (archive_read_open1(a)); } diff --git a/libarchive/test/read_open_memory.c b/libarchive/test/read_open_memory.c index 9262ab9d3..0c714a31e 100644 --- a/libarchive/test/read_open_memory.c +++ b/libarchive/test/read_open_memory.c @@ -86,6 +86,7 @@ read_open_memory_internal(struct archive *a, const void *buff, size_t size, size_t read_size, int level) { struct read_memory_data *mine = NULL; + int r; switch (level) { case 3: @@ -112,7 +113,12 @@ read_open_memory_internal(struct archive *a, const void *buff, archive_read_set_read_callback(a, memory_read); archive_read_set_close_callback(a, memory_read_close); - archive_read_set_callback_data(a, mine); + r = archive_read_set_callback_data(a, mine); + if (r < 0) + return (r); + __LA_FALLTHROUGH; + default: + break; } return archive_read_open1(a); }