diff options
| -rw-r--r-- | archival/tar.c | 37 | ||||
| -rw-r--r-- | messages.c | 6 | ||||
| -rw-r--r-- | tar.c | 37 | 
3 files changed, 71 insertions, 9 deletions
| diff --git a/archival/tar.c b/archival/tar.c index 6dcda53ef..e4bdd0a6c 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -39,6 +39,7 @@  #include "internal.h"  #define BB_DECLARE_EXTERN  #define bb_need_io_error +#define bb_need_name_longer_then_foo  #include "messages.c"  #include <stdio.h>  #include <dirent.h> @@ -57,12 +58,13 @@  #define MINOR(dev) ((dev)&0xff)  #endif +#define NAME_SIZE	100  /* POSIX tar Header Block, from POSIX 1003.1-1990  */  struct TarHeader  {                                  /* byte offset */ -	char name[100];               /*   0-99 */ +	char name[NAME_SIZE];         /*   0-99 */  	char mode[8];                 /* 100-107 */  	char uid[8];                  /* 108-115 */  	char gid[8];                  /* 116-123 */ @@ -70,7 +72,7 @@ struct TarHeader  	char mtime[12];               /* 136-147 */  	char chksum[8];               /* 148-155 */  	char typeflag;                /* 156-156 */ -	char linkname[100];           /* 157-256 */ +	char linkname[NAME_SIZE];     /* 157-256 */  	char magic[6];                /* 257-262 */  	char version[2];              /* 263-264 */  	char uname[32];               /* 265-296 */ @@ -102,6 +104,8 @@ enum TarFileType  	DIRTYPE  = '5',            /* directory */  	FIFOTYPE = '6',            /* FIFO special */  	CONTTYPE = '7',            /* reserved */ +	GNULONGLINK = 'K',         /* GNU long (>100 chars) link name */ +	GNULONGNAME = 'L',         /* GNU long (>100 chars) file name */  };  typedef enum TarFileType TarFileType; @@ -496,6 +500,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,  {  	int status, tarFd=-1;  	int errorFlag=FALSE; +	int skipNextHeaderFlag=FALSE;  	TarHeader rawHeader;  	TarInfo header;  	char** tmpList; @@ -517,7 +522,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,  	/* Read the tar file, and iterate over it one file at a time */  	while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) { -		/* First, try to read the header */ +		/* Try to read the header */  		if ( readTarHeader(&rawHeader, &header) == FALSE ) {  			if ( *(header.name) == '\0' ) {  				goto endgame; @@ -531,6 +536,19 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,  				goto endgame;  		header.tarFd = tarFd; +		/* Skip funky extra GNU headers that precede long files */ +		if ( (header.type == GNULONGNAME) || (header.type == GNULONGLINK) ) { +			skipNextHeaderFlag=TRUE; +			tarExtractRegularFile(&header, FALSE, FALSE); +			continue; +		} +		if ( skipNextHeaderFlag == TRUE ) {  +			skipNextHeaderFlag=FALSE; +			errorMsg(name_longer_then_foo, NAME_SIZE);  +			tarExtractRegularFile(&header, FALSE, FALSE); +			continue; +		} +  #if defined BB_FEATURE_TAR_EXCLUDE  		{  			int skipFlag=FALSE; @@ -671,7 +689,15 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,  				if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE)  					errorFlag=TRUE;  				break; +#if 0 +			/* Handled earlier */ +			case GNULONGNAME: +			case GNULONGLINK: +				skipNextHeaderFlag=TRUE; +				break; +#endif  			default: +				errorMsg("Unknown file type '%c' in tar file\n", header.type);  				close( tarFd);  				return( FALSE);  		} @@ -897,6 +923,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*  		return( TRUE);  	} +	if (strlen(fileName) >= NAME_SIZE) { +		errorMsg(name_longer_then_foo, NAME_SIZE); +		return ( TRUE); +	} +  	if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) {  		return( FALSE);  	}  diff --git a/messages.c b/messages.c index 34b39f258..f7a772cbd 100644 --- a/messages.c +++ b/messages.c @@ -81,9 +81,9 @@  #if defined bb_need_too_few_args || ! defined BB_DECLARE_EXTERN  	BB_DEF_MESSAGE(too_few_args, "too few arguments\n")  #endif - - - +#if defined bb_need_name_longer_then_foo || ! defined BB_DECLARE_EXTERN +	BB_DEF_MESSAGE(name_longer_then_foo, "Names longer then %d chars not supported.\n") +#endif  #endif /* _BB_MESSAGES_C */ @@ -39,6 +39,7 @@  #include "internal.h"  #define BB_DECLARE_EXTERN  #define bb_need_io_error +#define bb_need_name_longer_then_foo  #include "messages.c"  #include <stdio.h>  #include <dirent.h> @@ -57,12 +58,13 @@  #define MINOR(dev) ((dev)&0xff)  #endif +#define NAME_SIZE	100  /* POSIX tar Header Block, from POSIX 1003.1-1990  */  struct TarHeader  {                                  /* byte offset */ -	char name[100];               /*   0-99 */ +	char name[NAME_SIZE];         /*   0-99 */  	char mode[8];                 /* 100-107 */  	char uid[8];                  /* 108-115 */  	char gid[8];                  /* 116-123 */ @@ -70,7 +72,7 @@ struct TarHeader  	char mtime[12];               /* 136-147 */  	char chksum[8];               /* 148-155 */  	char typeflag;                /* 156-156 */ -	char linkname[100];           /* 157-256 */ +	char linkname[NAME_SIZE];     /* 157-256 */  	char magic[6];                /* 257-262 */  	char version[2];              /* 263-264 */  	char uname[32];               /* 265-296 */ @@ -102,6 +104,8 @@ enum TarFileType  	DIRTYPE  = '5',            /* directory */  	FIFOTYPE = '6',            /* FIFO special */  	CONTTYPE = '7',            /* reserved */ +	GNULONGLINK = 'K',         /* GNU long (>100 chars) link name */ +	GNULONGNAME = 'L',         /* GNU long (>100 chars) file name */  };  typedef enum TarFileType TarFileType; @@ -496,6 +500,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,  {  	int status, tarFd=-1;  	int errorFlag=FALSE; +	int skipNextHeaderFlag=FALSE;  	TarHeader rawHeader;  	TarInfo header;  	char** tmpList; @@ -517,7 +522,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,  	/* Read the tar file, and iterate over it one file at a time */  	while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) { -		/* First, try to read the header */ +		/* Try to read the header */  		if ( readTarHeader(&rawHeader, &header) == FALSE ) {  			if ( *(header.name) == '\0' ) {  				goto endgame; @@ -531,6 +536,19 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,  				goto endgame;  		header.tarFd = tarFd; +		/* Skip funky extra GNU headers that precede long files */ +		if ( (header.type == GNULONGNAME) || (header.type == GNULONGLINK) ) { +			skipNextHeaderFlag=TRUE; +			tarExtractRegularFile(&header, FALSE, FALSE); +			continue; +		} +		if ( skipNextHeaderFlag == TRUE ) {  +			skipNextHeaderFlag=FALSE; +			errorMsg(name_longer_then_foo, NAME_SIZE);  +			tarExtractRegularFile(&header, FALSE, FALSE); +			continue; +		} +  #if defined BB_FEATURE_TAR_EXCLUDE  		{  			int skipFlag=FALSE; @@ -671,7 +689,15 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,  				if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE)  					errorFlag=TRUE;  				break; +#if 0 +			/* Handled earlier */ +			case GNULONGNAME: +			case GNULONGLINK: +				skipNextHeaderFlag=TRUE; +				break; +#endif  			default: +				errorMsg("Unknown file type '%c' in tar file\n", header.type);  				close( tarFd);  				return( FALSE);  		} @@ -897,6 +923,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*  		return( TRUE);  	} +	if (strlen(fileName) >= NAME_SIZE) { +		errorMsg(name_longer_then_foo, NAME_SIZE); +		return ( TRUE); +	} +  	if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) {  		return( FALSE);  	}  | 
