mirror of
https://github.com/upx/upx
synced 2025-10-05 19:20:23 +08:00
Detect too-short Mach_command, also be careful in recovery
fuzzing from leon.weiss AT @ruhr-uni-bochum.de https://github.com/upx/upx/issues/875 https://github.com/upx/upx/issues/874 modified: p_mach.cpp
This commit is contained in:
parent
7b06ba0b78
commit
a49d023bd0
|
@ -1678,6 +1678,12 @@ tribool PackMachBase<T>::canUnpack()
|
||||||
Mach_command const *ptr = (Mach_command const *)rawmseg;
|
Mach_command const *ptr = (Mach_command const *)rawmseg;
|
||||||
for (unsigned j= 0; j < ncmds;
|
for (unsigned j= 0; j < ncmds;
|
||||||
ptr = (Mach_command const *)(ptr->cmdsize + (char const *)ptr), ++j) {
|
ptr = (Mach_command const *)(ptr->cmdsize + (char const *)ptr), ++j) {
|
||||||
|
if (headway < (int)sizeof(Mach_command)) {
|
||||||
|
char buf[200]; snprintf(buf, sizeof(buf),
|
||||||
|
"bad Mach_command[%u]{@0x%zx,+0x%x}",
|
||||||
|
j, (sizeof(mhdri) + ((char const *)ptr - (char const *)rawmseg)), headway);
|
||||||
|
throwCantPack(buf);
|
||||||
|
}
|
||||||
unsigned const cmd = ptr->cmd;
|
unsigned const cmd = ptr->cmd;
|
||||||
unsigned const cmdsize = ptr->cmdsize;
|
unsigned const cmdsize = ptr->cmdsize;
|
||||||
if (is_bad_linker_command(cmd, cmdsize, headway, lc_seg, sizeof(Addr))) {
|
if (is_bad_linker_command(cmd, cmdsize, headway, lc_seg, sizeof(Addr))) {
|
||||||
|
@ -1769,7 +1775,8 @@ tribool PackMachBase<T>::canUnpack()
|
||||||
fi->seek(offLINK - bufsize, SEEK_SET);
|
fi->seek(offLINK - bufsize, SEEK_SET);
|
||||||
}
|
}
|
||||||
MemBuffer buf(bufsize);
|
MemBuffer buf(bufsize);
|
||||||
MemBuffer buf3(bufsize);
|
MemBuffer buf3(upx::max(bufsize, 0x1008u));
|
||||||
|
buf3.clear();
|
||||||
|
|
||||||
fi->readx(buf, bufsize);
|
fi->readx(buf, bufsize);
|
||||||
// Do not overwrite buf[]; For scratch space, then use buf3 instead.
|
// Do not overwrite buf[]; For scratch space, then use buf3 instead.
|
||||||
|
@ -1882,9 +1889,13 @@ tribool PackMachBase<T>::canUnpack()
|
||||||
unsigned const *p;
|
unsigned const *p;
|
||||||
for (p = (unsigned const *)&buf3[0x1000]; p > lo; ) if (*--p) {
|
for (p = (unsigned const *)&buf3[0x1000]; p > lo; ) if (*--p) {
|
||||||
overlay_offset = *(TE32 const *)p;
|
overlay_offset = *(TE32 const *)p;
|
||||||
|
if ((unsigned)file_size < (overlay_offset + sizeof(PackHeader) + sizeof(overlay_offset)))
|
||||||
|
throwCantUnpack("file corrupted");
|
||||||
if ((off_t)overlay_offset < offLINK) {
|
if ((off_t)overlay_offset < offLINK) {
|
||||||
overlay_offset = ((char const *)p - (char const *)lo) +
|
overlay_offset = ((char const *)p - (char const *)lo) +
|
||||||
(offLINK - 0x1000) - overlay_offset + sizeof(l_info);
|
(offLINK - 0x1000) - overlay_offset + sizeof(l_info);
|
||||||
|
if ((unsigned)file_size < (overlay_offset + sizeof(PackHeader) + sizeof(overlay_offset)))
|
||||||
|
throwCantUnpack("file corrupted");
|
||||||
fi->seek(overlay_offset, SEEK_SET);
|
fi->seek(overlay_offset, SEEK_SET);
|
||||||
fi->readx(buf3, bufsize);
|
fi->readx(buf3, bufsize);
|
||||||
if (b_ptr->sz_unc < 0x4000
|
if (b_ptr->sz_unc < 0x4000
|
||||||
|
@ -1985,6 +1996,12 @@ tribool PackMachBase<T>::canPack()
|
||||||
unsigned char const *ptr = (unsigned char const *)rawmseg;
|
unsigned char const *ptr = (unsigned char const *)rawmseg;
|
||||||
for (unsigned j= 0; j < ncmds; ++j) {
|
for (unsigned j= 0; j < ncmds; ++j) {
|
||||||
Mach_segment_command const *segptr = (Mach_segment_command const *)ptr;
|
Mach_segment_command const *segptr = (Mach_segment_command const *)ptr;
|
||||||
|
if (headway < sizeof(Mach_command)) {
|
||||||
|
char buf[200]; snprintf(buf, sizeof(buf),
|
||||||
|
"bad Mach_command[%u]{@0x%zx,+0x%x}",
|
||||||
|
j, (sizeof(mhdri) + ((char const *)segptr - (char const *)rawmseg)), headway);
|
||||||
|
throwCantPack(buf);
|
||||||
|
}
|
||||||
unsigned const cmd = segptr->cmd &~ LC_REQ_DYLD;
|
unsigned const cmd = segptr->cmd &~ LC_REQ_DYLD;
|
||||||
unsigned const cmdsize = segptr->cmdsize;
|
unsigned const cmdsize = segptr->cmdsize;
|
||||||
if (is_bad_linker_command(cmd, cmdsize, headway, lc_seg, sizeof(Addr))) {
|
if (is_bad_linker_command(cmd, cmdsize, headway, lc_seg, sizeof(Addr))) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user