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:
John Reiser
2021-01-23 13:52:54 -08:00
committed by Markus F.X.J. Oberhumer
parent f17d9967c2
commit 21d102c84f
+10 -7
View File
@@ -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;