0,0 → 1,93 |
Origin: upstream, http://repo.or.cz/w/libtar.git/commitdiff/45448e8bae671c2f7e80b860ae0fc0cedf2bdc04 |
From: Chris Frey <cdfrey@foursquare.net> |
Date: Tue, 1 Oct 2013 15:58:52 -0400 |
Subject: [PATCH] Fixed size_t overflow bug, as reported by Timo Warns |
|
--- |
lib/block.c | 38 ++++++++++++++++++++++++-------------- |
1 file changed, 24 insertions(+), 14 deletions(-) |
|
diff --git a/lib/block.c b/lib/block.c |
index 2917dc6..092bc28 100644 |
--- a/lib/block.c |
+++ b/lib/block.c |
@@ -90,8 +90,8 @@ th_read_internal(TAR *t) |
int |
th_read(TAR *t) |
{ |
- int i, j; |
- size_t sz; |
+ int i; |
+ size_t sz, j, blocks; |
char *ptr; |
|
#ifdef DEBUG |
@@ -118,21 +118,26 @@ th_read(TAR *t) |
if (TH_ISLONGLINK(t)) |
{ |
sz = th_get_size(t); |
- j = (sz / T_BLOCKSIZE) + (sz % T_BLOCKSIZE ? 1 : 0); |
+ blocks = (sz / T_BLOCKSIZE) + (sz % T_BLOCKSIZE ? 1 : 0); |
+ if (blocks > ((size_t)-1 / T_BLOCKSIZE)) |
+ { |
+ errno = E2BIG; |
+ return -1; |
+ } |
#ifdef DEBUG |
printf(" th_read(): GNU long linkname detected " |
- "(%ld bytes, %d blocks)\n", sz, j); |
+ "(%ld bytes, %d blocks)\n", sz, blocks); |
#endif |
- t->th_buf.gnu_longlink = (char *)malloc(j * T_BLOCKSIZE); |
+ t->th_buf.gnu_longlink = (char *)malloc(blocks * T_BLOCKSIZE); |
if (t->th_buf.gnu_longlink == NULL) |
return -1; |
|
- for (ptr = t->th_buf.gnu_longlink; j > 0; |
- j--, ptr += T_BLOCKSIZE) |
+ for (j = 0, ptr = t->th_buf.gnu_longlink; j < blocks; |
+ j++, ptr += T_BLOCKSIZE) |
{ |
#ifdef DEBUG |
printf(" th_read(): reading long linkname " |
- "(%d blocks left, ptr == %ld)\n", j, ptr); |
+ "(%d blocks left, ptr == %ld)\n", blocks-j, ptr); |
#endif |
i = tar_block_read(t, ptr); |
if (i != T_BLOCKSIZE) |
@@ -163,21 +168,26 @@ th_read(TAR *t) |
if (TH_ISLONGNAME(t)) |
{ |
sz = th_get_size(t); |
- j = (sz / T_BLOCKSIZE) + (sz % T_BLOCKSIZE ? 1 : 0); |
+ blocks = (sz / T_BLOCKSIZE) + (sz % T_BLOCKSIZE ? 1 : 0); |
+ if (blocks > ((size_t)-1 / T_BLOCKSIZE)) |
+ { |
+ errno = E2BIG; |
+ return -1; |
+ } |
#ifdef DEBUG |
printf(" th_read(): GNU long filename detected " |
- "(%ld bytes, %d blocks)\n", sz, j); |
+ "(%ld bytes, %d blocks)\n", sz, blocks); |
#endif |
- t->th_buf.gnu_longname = (char *)malloc(j * T_BLOCKSIZE); |
+ t->th_buf.gnu_longname = (char *)malloc(blocks * T_BLOCKSIZE); |
if (t->th_buf.gnu_longname == NULL) |
return -1; |
|
- for (ptr = t->th_buf.gnu_longname; j > 0; |
- j--, ptr += T_BLOCKSIZE) |
+ for (j = 0, ptr = t->th_buf.gnu_longname; j < blocks; |
+ j++, ptr += T_BLOCKSIZE) |
{ |
#ifdef DEBUG |
printf(" th_read(): reading long filename " |
- "(%d blocks left, ptr == %ld)\n", j, ptr); |
+ "(%d blocks left, ptr == %ld)\n", blocks-j, ptr); |
#endif |
i = tar_block_read(t, ptr); |
if (i != T_BLOCKSIZE) |
-- |
1.8.4.rc3 |
|