** Attachment added: "Patch for 6"
https://bugs.launchpad.net/ubuntu/+source/unar/+bug/2168659/+attachment/6003085/+files/XAD7ZipParser.patch.txt
** Description changed:
Three more bugs from the same porting effort:
4. XADSkipHandle: broken insertion loop (heap overflow on out-of-order skips)
`XADSkipHandle.m:156-160`
```objc
for(int i=numregions-1;i>index;i++)
{
regions[i+1].actual=regions[i].actual;
regions[i+1].skip=regions[i].skip-end+start;
}
```
It is meant to shift regions up to make room for a new skip (the loop
must run *downwards*: `i--`). With `i++` it runs *upwards* instead:
whenever the new skip is not appended after all existing regions (`index
< numregions-1`), the loop keeps writing `regions[i+1]` past the
allocation — a heap buffer overflow — and never performs the intended
shift, corrupting the region table.
**Why it went unnoticed:** all current call sites (ALZip multi-volume,
split-file handling) append skips in increasing offset order, so `index`
always equals the last region and the loop body never executes. The bug
is latent, waiting for the first caller that adds an out-of-order skip.
** Potential fix:** `for(int i=numregions-1;i>index;i--)`.
5. NowCompress: reads uninitialized memory on degenerate headers
`XADNowCompressHandle.m:195-200`
```objc
if(nextblock>=numblocks)
{
if(![self readNextFileHeader]) return 0;
}
uint32_t offset=blocks[nextblock].offset; // may still be out of range
```
`readNextFileHeader` can succeed while leaving `numblocks == 0`
(degenerate header), after which `blocks[nextblock]` reads uninitialized
malloc memory.
**Potential fix:** `if(nextblock>=(int)blocks.size()) return 0;`.
6. XAD7ZipParser: truncation of values to signed 32-bit
64-bit integer values returned by `ReadNumber()` are cast directly to
signed `(int)`. Malformed archives can cause signed integer truncation
or negative lengths/counts.
** Potential fix:** Preserving uint64_t through all parsing and bounds-
- checking before narrowing conversions prevents overflow attacks. Diff is
- like this:
-
- ```
- --- a/XADMaster/XAD7ZipParser.m
- +++ b/XADMaster/XAD7ZipParser.m
- @@ -534,3 +534,5 @@ -(void)parseFolderForHandle:(CSHandle *)handle
dictionary:(NSMutableDictionary *
- {
- - int numcoders=(int)ReadNumber(handle);
- + uint64_t numcoders_val=ReadNumber(handle);
- + if(numcoders_val>1024) [XADException raiseIllegalDataException];
- + int numcoders=(int)numcoders_val;
- NSMutableArray *instreams=[NSMutableArray array];
- @@ -547,4 +549,7 @@ -(void)parseFolderForHandle:(CSHandle *)handle
dictionary:(NSMutableDictionary *
- if(flags&0x10)
- {
- - numinstreams=(int)ReadNumber(handle);
- - numoutstreams=(int)ReadNumber(handle);
- + uint64_t numin=ReadNumber(handle);
- + uint64_t numout=ReadNumber(handle);
- + if(numin>1024||numout>1024) [XADException
raiseIllegalDataException];
- + numinstreams=(int)numin;
- + numoutstreams=(int)numout;
- }
- @@ -553,3 +558,7 @@ -(void)parseFolderForHandle:(CSHandle *)handle
dictionary:(NSMutableDictionary *
- NSData *props=nil;
- - if(flags&0x20) props=[handle
readDataOfLength:(int)ReadNumber(handle)];
- + if(flags&0x20)
- + {
- + uint64_t propslen=ReadNumber(handle);
- + if(propslen>65536) [XADException
raiseIllegalDataException];
- + props=[handle readDataOfLength:(int)propslen];
- + }
-
- @@ -588,2 +597,4 @@ -(void)parseFolderForHandle:(CSHandle *)handle
dictionary:(NSMutableDictionary *
- + if(totaloutstreams==0) [XADException raiseIllegalDataException];
- +
- // Load binding pairs
- int numbindpairs=totaloutstreams-1;
- for(int i=0;i<numbindpairs;i++)
- @@ -591,4 +602,6 @@ -(void)parseFolderForHandle:(CSHandle *)handle
dictionary:(NSMutableDictionary *
- uint64_t inindex=ReadNumber(handle);
- uint64_t outindex=ReadNumber(handle);
- +
if(inindex>=(uint64_t)totalinstreams||outindex>=(uint64_t)totaloutstreams)
- + [XADException raiseIllegalDataException];
-
SetNumberEntryInArray(instreams,(int)inindex,outindex,@"SourceIndex");
-
SetNumberEntryInArray(outstreams,(int)outindex,inindex,@"DestinationIndex");
- @@ -598,2 +611,5 @@ -(void)parseFolderForHandle:(CSHandle *)handle
dictionary:(NSMutableDictionary *
- int numpackedstreams=totalinstreams-numbindpairs;
- +
if(numpackedstreams<0||*packedstreamindex+numpackedstreams>(int)[packedstreams
count])
- + [XADException raiseIllegalDataException];
- +
- if(numpackedstreams==1)
- @@ -611,3 +627,7 @@ -(void)parseFolderForHandle:(CSHandle *)handle
dictionary:(NSMutableDictionary *
- for(int i=0;i<numpackedstreams;i++)
- -
SetObjectEntryInArray(instreams,(int)ReadNumber(handle),[packedstreams
objectAtIndex:*packedstreamindex+i],@"PackedStream");
- + {
- + uint64_t sindex=ReadNumber(handle);
- + if(sindex>=(uint64_t)totalinstreams) [XADException
raiseIllegalDataException];
- +
SetObjectEntryInArray(instreams,(int)sindex,[packedstreams
objectAtIndex:*packedstreamindex+i],@"PackedStream");
- + }
- }
- @@ -638,3 +658,5 @@ -(void)parseSubStreamsInfoForHandle:(CSHandle *)handle
folders:(NSArray *)folder
- for(int i=0;i<numfolders;i++)
- {
- - int
numsubstreams=(int)ReadNumber(handle);
- + uint64_t numsub=ReadNumber(handle);
- + if(numsub>1000000) [XADException
raiseIllegalDataException];
- + int numsubstreams=(int)numsub;
- if(numsubstreams!=1) // Re-use default
substream when there is only one
-
- ```
+ checking before narrowing conversions prevents overflow attacks.
+ Proposed patch is lower.
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2168659
Title:
Potential memory corruption
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/unar/+bug/2168659/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs