From 3e0c2966dffb5dadb512a476ef4be3d0cc51c2be Mon Sep 17 00:00:00 2001 From: Pierre Neidhardt Date: Sat, 16 Jun 2018 16:35:00 +0200 Subject: [PATCH] Protect against bad crafted input Also check for wrap-around when checking oversize involving e_shoff and e_shnum. raised by https://github.com/upx/upx/pull/190 modified: p_lx_elf.cpp --- src/p_lx_elf.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 822a7652..41e805ee 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -235,8 +235,17 @@ PackLinuxElf32::PackLinuxElf32help1(InputFile *f) sz_phdrs = 0; return; } + if (0==e_phnum) throwCantUnpack("0==e_phnum"); e_phoff = get_te32(&ehdri.e_phoff); + unsigned const last_Phdr = e_phoff + e_phnum * sizeof(Elf32_Phdr); + if (last_Phdr < e_phoff || (unsigned long)file_size < last_Phdr) { + throwCantUnpack("bad e_phoff"); + } e_shoff = get_te32(&ehdri.e_shoff); + unsigned const last_Shdr = e_shoff + e_shnum * sizeof(Elf32_Shdr); + if (last_Shdr < e_shoff || (unsigned long)file_size < last_Shdr) { + throwCantUnpack("bad e_shoff"); + } sz_phdrs = e_phnum * e_phentsize; if (f && Elf32_Ehdr::ET_DYN!=e_type) { @@ -599,8 +608,17 @@ PackLinuxElf64::PackLinuxElf64help1(InputFile *f) sz_phdrs = 0; return; } + if (0==e_phnum) throwCantUnpack("0==e_phnum"); e_phoff = get_te64(&ehdri.e_phoff); + upx_uint64_t const last_Phdr = e_phoff + e_phnum * sizeof(Elf64_Phdr); + if (last_Phdr < e_phoff || (unsigned long)file_size < last_Phdr) { + throwCantUnpack("bad e_phoff"); + } e_shoff = get_te64(&ehdri.e_shoff); + upx_uint64_t const last_Shdr = e_shoff + e_shnum * sizeof(Elf64_Shdr); + if (last_Shdr < e_shoff || (unsigned long)file_size < last_Shdr) { + throwCantUnpack("bad e_shoff"); + } sz_phdrs = e_phnum * e_phentsize; if (f && Elf64_Ehdr::ET_DYN!=e_type) { @@ -3763,6 +3781,9 @@ void PackLinuxElf64::pack4(OutputFile *fo, Filter &ft) void PackLinuxElf64::unpack(OutputFile *fo) { + if (e_phoff != sizeof(Elf64_Ehdr)) {// Phdrs not contiguous with Ehdr + throwCantUnpack("bad e_phoff"); + } unsigned const c_phnum = get_te16(&ehdri.e_phnum); upx_uint64_t old_data_off = 0; upx_uint64_t old_data_len = 0; @@ -3828,6 +3849,9 @@ void PackLinuxElf64::unpack(OutputFile *fo) unsigned total_out = 0; unsigned c_adler = upx_adler32(NULL, 0); unsigned u_adler = upx_adler32(NULL, 0); + if ((MAX_ELF_HDR - sizeof(Elf64_Ehdr))/sizeof(Elf64_Phdr) < u_phnum) { + throwCantUnpack("bad compressed e_phnum"); + } // Packed ET_EXE has no PT_DYNAMIC. // Packed ET_DYN has original PT_DYNAMIC for info needed by rtld. @@ -4383,6 +4407,9 @@ Elf64_Sym const *PackLinuxElf64::elf_lookup(char const *name) const void PackLinuxElf32::unpack(OutputFile *fo) { + if (e_phoff != sizeof(Elf32_Ehdr)) {// Phdrs not contiguous with Ehdr + throwCantUnpack("bad e_phoff"); + } unsigned const c_phnum = get_te16(&ehdri.e_phnum); unsigned old_data_off = 0; unsigned old_data_len = 0; @@ -4449,6 +4476,9 @@ void PackLinuxElf32::unpack(OutputFile *fo) unsigned total_out = 0; unsigned c_adler = upx_adler32(NULL, 0); unsigned u_adler = upx_adler32(NULL, 0); + if ((MAX_ELF_HDR - sizeof(Elf32_Ehdr))/sizeof(Elf32_Phdr) < u_phnum) { + throwCantUnpack("bad compressed e_phnum"); + } // Packed ET_EXE has no PT_DYNAMIC. // Packed ET_DYN has original PT_DYNAMIC for info needed by rtld. -- 2.17.0 id=39764ef893b7b65a8ce55e13746fed8fd0bad6e0'>build: Use only one domain for guix-manual....* Makefile.am (assert-no-store-file-names): Exclude guix-manual. * po/doc/guix.pot po/doc/contributing.pot: Merge into... * po/doc/guix-manual.pot: ...this. * po/doc/guix.fr.po po/doc/contributing.fr.po: Merge into... * po/doc/guix-manual.fr.po: ...this. * doc/local.mk: Replace old file names. * po/doc/local.mk: Replace old file names. Julien Lepiller 2018-04-19gnu: doc: Add French documentation....* doc/contributing.fr.texi: New file. * doc/guix.fr.texi: New file. * doc/local.mk (TRANSLATED_INFO): Add them. (info_TEXINFOS): Add guix.fr.texi. * po/doc/contributing.fr.po: New file. * po/doc/guix.fr.po: New file. * po/doc/local.mk (EXTRA_DIST): Add them. Julien Lepiller 2018-04-19gnu: doc: Allow documentation to be translated....* po/doc/contributing.pot: New file. * po/doc/guix.pot: New file. * po/doc/local.mk: New file. * Makefile.am: Include it. Add gettext command. Add silent rules for po4a. * configure.ac: Look for po4a-translate and po4a-updatepo. * doc/local.mk: Add rules to generate translated texi files. (TRANSLATED_INFO): New variable. (BUILT_SOURCES, EXTRA_DIST, MAINTAINERCLEANFILES): Add it. * .gitignore: Add generated files. Julien Lepiller