Better checking of Mach_header.ncmds, .sizeofcmds
Improves earlier fix. https://github.com/upx/upx/issues/447 modified: p_mach.cpp
This commit is contained in:
committed by
Markus F.X.J. Oberhumer
parent
f17d9967c2
commit
21d102c84f
+10
-7
@@ -1532,11 +1532,15 @@ int PackMachBase<T>::canUnpack()
|
||||
return false;
|
||||
my_cpusubtype = mhdri.cpusubtype;
|
||||
|
||||
unsigned const ncmds = mhdri.ncmds;
|
||||
int headway = (int)mhdri.sizeofcmds;
|
||||
// old style: LC_SEGMENT + LC_UNIXTHREAD [smaller, varies by $ARCH]
|
||||
// new style: 3*LC_SEGMENT + LC_MAIN [larger]
|
||||
// FIXME: So this test is weak.
|
||||
if (headway < (int)(sizeof(Mach_segment_command) + 4*4)) {
|
||||
if ((2 == ncmds
|
||||
&& headway < (int)(sizeof(Mach_segment_command) + 4*4))
|
||||
|| (3 <= ncmds
|
||||
&& headway < (int)(3 * sizeof(Mach_segment_command)
|
||||
+ sizeof(Mach_main_command)))) {
|
||||
infoWarning("Mach_header.sizeofcmds = %d too small", headway);
|
||||
throwCantUnpack("file corrupted");
|
||||
}
|
||||
@@ -1554,7 +1558,6 @@ int PackMachBase<T>::canUnpack()
|
||||
off_t offLINK = 0;
|
||||
unsigned pos_next = 0;
|
||||
unsigned nseg = 0;
|
||||
unsigned const ncmds = mhdri.ncmds;
|
||||
Mach_command const *ptr = (Mach_command const *)rawmseg;
|
||||
for (unsigned j= 0; j < ncmds;
|
||||
ptr = (Mach_command const *)(ptr->cmdsize + (char const *)ptr), ++j) {
|
||||
@@ -1805,6 +1808,10 @@ bool PackMachBase<T>::canPack()
|
||||
return false;
|
||||
my_cpusubtype = mhdri.cpusubtype;
|
||||
|
||||
unsigned const ncmds = mhdri.ncmds;
|
||||
if (!ncmds || 256 < ncmds) { // arbitrary, but guard against garbage
|
||||
throwCantPack("256 < Mach_header.ncmds");
|
||||
}
|
||||
unsigned const sz_mhcmds = (unsigned)mhdri.sizeofcmds;
|
||||
unsigned headway = file_size - sizeof(mhdri);
|
||||
if (headway < sz_mhcmds) {
|
||||
@@ -1819,10 +1826,6 @@ bool PackMachBase<T>::canPack()
|
||||
rawmseg = (Mach_segment_command *)(void *)rawmseg_buf;
|
||||
fi->readx(rawmseg, mhdri.sizeofcmds);
|
||||
|
||||
unsigned const ncmds = mhdri.ncmds;
|
||||
if (256 < ncmds) { // arbitrary, but guard against garbage
|
||||
throwCantPack("256 < Mach_header.ncmds");
|
||||
}
|
||||
msegcmd_buf.alloc(sizeof(Mach_segment_command) * ncmds);
|
||||
msegcmd = (Mach_segment_command *)msegcmd_buf.getVoidPtr();
|
||||
unsigned char const *ptr = (unsigned char const *)rawmseg;
|
||||
|
||||
Reference in New Issue
Block a user