From a06087ca70753a1364f8d45114c7d352deea2966 Mon Sep 17 00:00:00 2001 From: Gwyn Judd Date: Mon, 23 Jul 2018 14:04:27 +1200 Subject: [PATCH] Fix buffer overrun when individual path length exceeds USTAR_uname_size The value of strlen(nameChar) would be either bogus, or exceed the value of USTAR_uname_size, leading to overrun. --- Classes/NVHTarFile.m | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Classes/NVHTarFile.m b/Classes/NVHTarFile.m index d633826..2b5b21b 100644 --- a/Classes/NVHTarFile.m +++ b/Classes/NVHTarFile.m @@ -481,8 +481,6 @@ - (void)writeHeader:(char *)buffer forPath:(NSString *)path withBasePath:(NSStri NSString *groupName = [attributes objectForKey:NSFileGroupOwnerAccountName]; unsigned long long fileSize = [[attributes objectForKey:NSFileSize] longLongValue]; - char nameChar[USTAR_name_size]; - [self writeString:path toChar:nameChar withLength:USTAR_name_size]; char unameChar[USTAR_uname_size]; [self writeString:ownerName toChar:unameChar withLength:USTAR_uname_size]; char gnameChar[USTAR_gname_size]; @@ -500,7 +498,10 @@ - (void)writeHeader:(char *)buffer forPath:(NSString *)path withBasePath:(NSStri format_number([modificationDate timeIntervalSince1970], buffer + USTAR_mtime_offset, USTAR_mtime_size, USTAR_mtime_max_size, 0); - unsigned long nameLength = strlen(nameChar); + unsigned long nameLength = path.length; + char* nameChar = (char*)malloc(nameLength+1); + [self writeString:path toChar:nameChar withLength:nameLength+1]; + if (nameLength <= USTAR_name_size) memcpy(buffer + USTAR_name_offset, nameChar, nameLength); else { @@ -513,10 +514,12 @@ - (void)writeHeader:(char *)buffer forPath:(NSString *)path withBasePath:(NSStri */ if (p == nameChar) p = strchr(p + 1, '/'); - memcpy(buffer + USTAR_prefix_offset, nameChar, p - nameChar); + memcpy(buffer + USTAR_prefix_offset, nameChar, (p - nameChar) > USTAR_prefix_size ? USTAR_prefix_size:(p - nameChar)); memcpy(buffer + USTAR_name_offset, p + 1, nameChar + nameLength - p - 1); } + + free(nameChar); memcpy(buffer+USTAR_uname_offset,unameChar,USTAR_uname_size); memcpy(buffer+USTAR_gname_offset,gnameChar,USTAR_gname_size);