Validate fat_head; CERT-FI id:000000,sig:06,src:000000,op:flip1,pos:7
This commit is contained in:
parent
f0aef9b28b
commit
35944cbfc1
@ -243,6 +243,7 @@ void InputFile::sopen(const char *name, int flags, int shflags)
|
|||||||
else
|
else
|
||||||
throwIOException(_name, errno);
|
throwIOException(_name, errno);
|
||||||
}
|
}
|
||||||
|
_length_orig = _length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -294,6 +295,10 @@ off_t InputFile::tell() const
|
|||||||
return super::tell();
|
return super::tell();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
off_t InputFile::st_size_orig() const
|
||||||
|
{
|
||||||
|
return _length_orig;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
|
|||||||
@ -108,6 +108,9 @@ public:
|
|||||||
|
|
||||||
virtual void seek(off_t off, int whence);
|
virtual void seek(off_t off, int whence);
|
||||||
virtual off_t tell() const;
|
virtual off_t tell() const;
|
||||||
|
virtual off_t st_size_orig() const;
|
||||||
|
protected:
|
||||||
|
off_t _length_orig;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1443,6 +1443,34 @@ PackMachFat::~PackMachFat()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned PackMachFat::check_fat_head()
|
||||||
|
{
|
||||||
|
struct Mach_fat_arch const *const arch = &fat_head.arch[0];
|
||||||
|
unsigned nfat = fat_head.fat.nfat_arch;
|
||||||
|
if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic
|
||||||
|
|| N_FAT_ARCH < nfat) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (unsigned j=0; j < nfat; ++j) {
|
||||||
|
unsigned const align = arch[j].align;
|
||||||
|
unsigned const mask = ~(~0u<<align);
|
||||||
|
unsigned const size = arch[j].size;
|
||||||
|
unsigned const offset = arch[j].offset;
|
||||||
|
if (align < 12 || align > 24) { // heuristic
|
||||||
|
throwUnknownExecutableFormat("align", 0);
|
||||||
|
}
|
||||||
|
if (mask > size) {
|
||||||
|
throwUnknownExecutableFormat("size", 0);
|
||||||
|
}
|
||||||
|
if (mask & offset
|
||||||
|
|| fi->st_size_orig() < (size + offset)
|
||||||
|
|| fi->st_size_orig() <= offset) { // redundant unless overflow
|
||||||
|
throwUnknownExecutableFormat("offset", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nfat;
|
||||||
|
}
|
||||||
|
|
||||||
const int *PackMachFat::getCompressionMethods(int /*method*/, int /*level*/) const
|
const int *PackMachFat::getCompressionMethods(int /*method*/, int /*level*/) const
|
||||||
{
|
{
|
||||||
static const int m_nrv2e[] = { M_NRV2E_LE32, M_END };
|
static const int m_nrv2e[] = { M_NRV2E_LE32, M_END };
|
||||||
@ -1549,8 +1577,9 @@ void PackMachFat::unpack(OutputFile *fo)
|
|||||||
fo->write(&fat_head, sizeof(fat_head.fat) +
|
fo->write(&fat_head, sizeof(fat_head.fat) +
|
||||||
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
|
fat_head.fat.nfat_arch * sizeof(fat_head.arch[0]));
|
||||||
}
|
}
|
||||||
|
unsigned const nfat = check_fat_head();
|
||||||
unsigned length;
|
unsigned length;
|
||||||
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
|
for (unsigned j=0; j < nfat; ++j) {
|
||||||
unsigned base = (fo ? fo->unset_extent() : 0); // actual length
|
unsigned base = (fo ? fo->unset_extent() : 0); // actual length
|
||||||
base += ~(~0u<<fat_head.arch[j].align) & (0-base); // align up
|
base += ~(~0u<<fat_head.arch[j].align) & (0-base); // align up
|
||||||
if (fo) {
|
if (fo) {
|
||||||
@ -1631,11 +1660,8 @@ bool PackMachFat::canPack()
|
|||||||
struct Mach_fat_arch *arch = &fat_head.arch[0];
|
struct Mach_fat_arch *arch = &fat_head.arch[0];
|
||||||
|
|
||||||
fi->readx(&fat_head, sizeof(fat_head));
|
fi->readx(&fat_head, sizeof(fat_head));
|
||||||
if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic
|
unsigned const nfat = check_fat_head();
|
||||||
|| N_FAT_ARCH < fat_head.fat.nfat_arch) {
|
for (unsigned j=0; j < nfat; ++j) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
|
|
||||||
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
switch (arch[j].cputype) {
|
switch (arch[j].cputype) {
|
||||||
@ -1684,11 +1710,11 @@ int PackMachFat::canUnpack()
|
|||||||
struct Mach_fat_arch *arch = &fat_head.arch[0];
|
struct Mach_fat_arch *arch = &fat_head.arch[0];
|
||||||
|
|
||||||
fi->readx(&fat_head, sizeof(fat_head));
|
fi->readx(&fat_head, sizeof(fat_head));
|
||||||
if (Mach_fat_header::FAT_MAGIC!=fat_head.fat.magic
|
unsigned const nfat = check_fat_head();
|
||||||
|| N_FAT_ARCH < fat_head.fat.nfat_arch) {
|
if (0 == nfat) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (unsigned j=0; j < fat_head.fat.nfat_arch; ++j) {
|
for (unsigned j=0; j < nfat; ++j) {
|
||||||
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
fi->set_extent(fat_head.arch[j].offset, fat_head.arch[j].size);
|
||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
switch (arch[j].cputype) {
|
switch (arch[j].cputype) {
|
||||||
|
|||||||
@ -855,6 +855,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// implementation
|
// implementation
|
||||||
|
virtual unsigned check_fat_head(); // number of architectures
|
||||||
virtual void pack(OutputFile *fo);
|
virtual void pack(OutputFile *fo);
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
virtual void list();
|
virtual void list();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user