Unpacking detects and defends against malicious ELF

This commit is contained in:
John Reiser 2024-03-28 07:48:55 -07:00 committed by Markus F.X.J. Oberhumer
parent d1f62e3ab4
commit 3949af6d3c
2 changed files with 18 additions and 8 deletions

View File

@ -6484,13 +6484,17 @@ void PackLinuxElf64::un_shlib_1(
struct { struct {
struct l_info l; struct l_info l;
struct p_info p; struct p_info p;
struct b_info b;
} hdr; } hdr;
fi->readx(&hdr, sizeof(hdr)); fi->readx(&hdr, sizeof(hdr));
if (hdr.l.l_magic != UPX_MAGIC_LE32 if (hdr.l.l_magic != UPX_MAGIC_LE32
|| hdr.l.l_lsize != (unsigned)lsize || get_te16(&hdr.l.l_lsize) != (unsigned)lsize
|| hdr.p.p_filesize != ph.u_file_size) { || get_te32(&hdr.p.p_filesize) != ph.u_file_size
throwCantUnpack("corrupt l_info/p_info"); || get_te32(&hdr.b.sz_unc) < sz_elf_hdrs // peek: 1st b_info covers Elf headers
) {
throwCantUnpack("corrupt l_info/p_info/b_info");
} }
fi->seek(-(off_t)sizeof(struct b_info), SEEK_CUR); // hdr.b_info was a peek
// The default layout for a shared library created by binutils-2.29 // The default layout for a shared library created by binutils-2.29
// (Fedora 28; 2018) has two PT_LOAD: permissions r-x and rw-. // (Fedora 28; 2018) has two PT_LOAD: permissions r-x and rw-.
@ -6680,13 +6684,17 @@ void PackLinuxElf32::un_shlib_1(
struct { struct {
struct l_info l; struct l_info l;
struct p_info p; struct p_info p;
struct b_info b;
} hdr; } hdr;
fi->readx(&hdr, sizeof(hdr)); fi->readx(&hdr, sizeof(hdr));
if (hdr.l.l_magic != UPX_MAGIC_LE32 if (hdr.l.l_magic != UPX_MAGIC_LE32
|| hdr.l.l_lsize != (unsigned)lsize || get_te16(&hdr.l.l_lsize) != (unsigned)lsize
|| hdr.p.p_filesize != ph.u_file_size) { || get_te32(&hdr.p.p_filesize) != ph.u_file_size
throwCantUnpack("corrupt l_info/p_info"); || get_te32(&hdr.b.sz_unc) < sz_elf_hdrs // peek: 1st b_info covers Elf headers
) {
throwCantUnpack("corrupt l_info/p_info/b_info");
} }
fi->seek(-(off_t)sizeof(struct b_info), SEEK_CUR); // hdr.b_info was a peek
// The default layout for a shared library created by binutils-2.29 // The default layout for a shared library created by binutils-2.29
// (Fedora 28; 2018) has two PT_LOAD: permissions r-x and rw-. // (Fedora 28; 2018) has two PT_LOAD: permissions r-x and rw-.

View File

@ -491,8 +491,10 @@ unsigned PackUnix::unpackExtent(unsigned wanted, OutputFile *fo,
throwCantUnpack("corrupt b_info"); throwCantUnpack("corrupt b_info");
// place the input for overlapping de-compression // place the input for overlapping de-compression
// FIXME: inlen cheats OVERHEAD; assumes small wanted peek length int j = inlen + sz_unc + OVERHEAD - sz_cpr;
int j = inlen + blocksize + OVERHEAD - sz_cpr; if (ibuf.getSize() < (unsigned)(j + sz_cpr)) {
throwCantUnpack("corrupt b_info");
}
fi->readx(ibuf+j, sz_cpr); fi->readx(ibuf+j, sz_cpr);
total_in += sz_cpr; total_in += sz_cpr;
// update checksum of compressed data // update checksum of compressed data