more checking of Mach_header when unpacking for MachOS
https://github.com/upx/upx/issues/783 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65532 modified: p_mach.cpp
This commit is contained in:
+10
-3
@@ -1468,6 +1468,8 @@ umin(unsigned a, unsigned b)
|
|||||||
return (a <= b) ? a : b;
|
return (a <= b) ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_N_CMDS 256
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void PackMachBase<T>::unpack(OutputFile *fo)
|
void PackMachBase<T>::unpack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
@@ -1529,7 +1531,7 @@ void PackMachBase<T>::unpack(OutputFile *fo)
|
|||||||
|| mhdri.filetype != mhdr->filetype)
|
|| mhdri.filetype != mhdr->filetype)
|
||||||
throwCantUnpack("file header corrupted");
|
throwCantUnpack("file header corrupted");
|
||||||
unsigned const ncmds = mhdr->ncmds;
|
unsigned const ncmds = mhdr->ncmds;
|
||||||
if (!ncmds || 256 < ncmds) { // arbitrary limit
|
if (!ncmds || MAX_N_CMDS < ncmds) { // arbitrary limit
|
||||||
char msg[40]; snprintf(msg, sizeof(msg),
|
char msg[40]; snprintf(msg, sizeof(msg),
|
||||||
"bad Mach_header.ncmds = %d", ncmds);
|
"bad Mach_header.ncmds = %d", ncmds);
|
||||||
throwCantUnpack(msg);
|
throwCantUnpack(msg);
|
||||||
@@ -1643,6 +1645,11 @@ tribool PackMachBase<T>::canUnpack()
|
|||||||
|
|
||||||
unsigned const ncmds = mhdri.ncmds;
|
unsigned const ncmds = mhdri.ncmds;
|
||||||
int headway = (int)mhdri.sizeofcmds;
|
int headway = (int)mhdri.sizeofcmds;
|
||||||
|
if (!ncmds || MAX_N_CMDS < ncmds || file_size < headway) {
|
||||||
|
char msg[80]; snprintf(msg, sizeof(msg),
|
||||||
|
"bad Mach_header ncmds=%d sizeofcmds=0x%x", ncmds, headway);
|
||||||
|
throwCantUnpack(msg);
|
||||||
|
}
|
||||||
// old style: LC_SEGMENT + LC_UNIXTHREAD [smaller, varies by $ARCH]
|
// old style: LC_SEGMENT + LC_UNIXTHREAD [smaller, varies by $ARCH]
|
||||||
// new style: 3*LC_SEGMENT + LC_MAIN [larger]
|
// new style: 3*LC_SEGMENT + LC_MAIN [larger]
|
||||||
if ((2 == ncmds
|
if ((2 == ncmds
|
||||||
@@ -1954,8 +1961,8 @@ tribool PackMachBase<T>::canPack()
|
|||||||
my_cpusubtype = mhdri.cpusubtype;
|
my_cpusubtype = mhdri.cpusubtype;
|
||||||
|
|
||||||
unsigned const ncmds = mhdri.ncmds;
|
unsigned const ncmds = mhdri.ncmds;
|
||||||
if (!ncmds || 256 < ncmds) { // arbitrary, but guard against garbage
|
if (!ncmds || MAX_N_CMDS < ncmds) { // arbitrary, but guard against garbage
|
||||||
throwCantPack("256 < Mach_header.ncmds");
|
throwCantPack("%d < Mach_header.ncmds", MAX_N_CMDS);
|
||||||
}
|
}
|
||||||
unsigned const sz_mhcmds = (unsigned)mhdri.sizeofcmds;
|
unsigned const sz_mhcmds = (unsigned)mhdri.sizeofcmds;
|
||||||
unsigned headway = umin(sz_mhcmds, file_size - sizeof(mhdri));
|
unsigned headway = umin(sz_mhcmds, file_size - sizeof(mhdri));
|
||||||
|
|||||||
Reference in New Issue
Block a user