Fixed memory leak in read_header() in list.c (#1917631)
upstream commit: https://git.savannah.gnu.org/cgit/tar.git/commit/?id=d9d4435692150fa8ff68e1b1a473d187cc3fd777
This commit is contained in:
parent
ac75693777
commit
0bea5fee49
122
tar-1.33-fix-read-header-mem-leak.patch
Normal file
122
tar-1.33-fix-read-header-mem-leak.patch
Normal file
@ -0,0 +1,122 @@
|
||||
From: Sergey Poznyakoff <gray@gnu.org>
|
||||
Subject: [PATCH] Bug reported in https://savannah.gnu.org/bugs/?59897
|
||||
|
||||
* src/list.c (read_header): Don't return directly from the loop.
|
||||
Instead set the status and break. Return the status. Free
|
||||
next_long_name and next_long_link before returning.
|
||||
---
|
||||
src/list.c | 38 +++++++++++++++++++++++++++-----------
|
||||
1 file changed, 27 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/list.c b/src/list.c
|
||||
index 95b53f8..6ad2ef2 100644
|
||||
--- a/src/list.c
|
||||
+++ b/src/list.c
|
||||
@@ -419,26 +419,27 @@ read_header (union block **return_block, struct tar_stat_info *info,
|
||||
enum read_header_mode mode)
|
||||
{
|
||||
union block *header;
|
||||
- union block *header_copy;
|
||||
char *bp;
|
||||
union block *data_block;
|
||||
size_t size, written;
|
||||
- union block *next_long_name = 0;
|
||||
- union block *next_long_link = 0;
|
||||
+ union block *next_long_name = NULL;
|
||||
+ union block *next_long_link = NULL;
|
||||
size_t next_long_name_blocks = 0;
|
||||
size_t next_long_link_blocks = 0;
|
||||
+ enum read_header status = HEADER_SUCCESS;
|
||||
|
||||
while (1)
|
||||
{
|
||||
- enum read_header status;
|
||||
-
|
||||
header = find_next_block ();
|
||||
*return_block = header;
|
||||
if (!header)
|
||||
- return HEADER_END_OF_FILE;
|
||||
+ {
|
||||
+ status = HEADER_END_OF_FILE;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
if ((status = tar_checksum (header, false)) != HEADER_SUCCESS)
|
||||
- return status;
|
||||
+ break;
|
||||
|
||||
/* Good block. Decode file size and return. */
|
||||
|
||||
@@ -448,7 +449,10 @@ read_header (union block **return_block, struct tar_stat_info *info,
|
||||
{
|
||||
info->stat.st_size = OFF_FROM_HEADER (header->header.size);
|
||||
if (info->stat.st_size < 0)
|
||||
- return HEADER_FAILURE;
|
||||
+ {
|
||||
+ status = HEADER_FAILURE;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (header->header.typeflag == GNUTYPE_LONGNAME
|
||||
@@ -458,10 +462,14 @@ read_header (union block **return_block, struct tar_stat_info *info,
|
||||
|| header->header.typeflag == SOLARIS_XHDTYPE)
|
||||
{
|
||||
if (mode == read_header_x_raw)
|
||||
- return HEADER_SUCCESS_EXTENDED;
|
||||
+ {
|
||||
+ status = HEADER_SUCCESS_EXTENDED;
|
||||
+ break;
|
||||
+ }
|
||||
else if (header->header.typeflag == GNUTYPE_LONGNAME
|
||||
|| header->header.typeflag == GNUTYPE_LONGLINK)
|
||||
{
|
||||
+ union block *header_copy;
|
||||
size_t name_size = info->stat.st_size;
|
||||
size_t n = name_size % BLOCKSIZE;
|
||||
size = name_size + BLOCKSIZE;
|
||||
@@ -528,7 +536,10 @@ read_header (union block **return_block, struct tar_stat_info *info,
|
||||
xheader_decode_global (&xhdr);
|
||||
xheader_destroy (&xhdr);
|
||||
if (mode == read_header_x_global)
|
||||
- return HEADER_SUCCESS_EXTENDED;
|
||||
+ {
|
||||
+ status = HEADER_SUCCESS_EXTENDED;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Loop! */
|
||||
@@ -547,6 +558,7 @@ read_header (union block **return_block, struct tar_stat_info *info,
|
||||
name = next_long_name->buffer + BLOCKSIZE;
|
||||
recent_long_name = next_long_name;
|
||||
recent_long_name_blocks = next_long_name_blocks;
|
||||
+ next_long_name = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -578,6 +590,7 @@ read_header (union block **return_block, struct tar_stat_info *info,
|
||||
name = next_long_link->buffer + BLOCKSIZE;
|
||||
recent_long_link = next_long_link;
|
||||
recent_long_link_blocks = next_long_link_blocks;
|
||||
+ next_long_link = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -589,9 +602,12 @@ read_header (union block **return_block, struct tar_stat_info *info,
|
||||
}
|
||||
assign_string (&info->link_name, name);
|
||||
|
||||
- return HEADER_SUCCESS;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
+ free (next_long_name);
|
||||
+ free (next_long_link);
|
||||
+ return status;
|
||||
}
|
||||
|
||||
#define ISOCTAL(c) ((c)>='0'&&(c)<='7')
|
||||
--
|
||||
2.26.0
|
||||
|
6
tar.spec
6
tar.spec
@ -5,7 +5,7 @@ Summary: GNU file archiving program
|
||||
Name: tar
|
||||
Epoch: 2
|
||||
Version: 1.33
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
License: GPLv3+
|
||||
URL: https://www.gnu.org/software/tar/
|
||||
|
||||
@ -19,6 +19,7 @@ Patch3: tar-1.29-wildcards.patch
|
||||
Patch4: tar-1.28-atime-rofs.patch
|
||||
Patch9: tar-1.28-document-exclude-mistakes.patch
|
||||
Patch10: tar-1.33-fix-capabilities-test.patch
|
||||
Patch11: tar-1.33-fix-read-header-mem-leak.patch
|
||||
|
||||
BuildRequires: make
|
||||
BuildRequires: gcc
|
||||
@ -113,6 +114,9 @@ make check || (
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Jan 25 2021 Ondrej Dubaj <odubaj@redhat.com> - 1.33-2
|
||||
- Fixed memory leak in read_header() in list.c (#1917631)
|
||||
|
||||
* Thu Jan 07 2021 Pavel Raiskup <praiskup@redhat.com> - 1.33-1
|
||||
- new upstream release (see the packaged NEWS file)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user