From cb51c818a0d2b2f1a64e084411ac5717ebb3ef38 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 29 Mar 2016 23:44:29 -0400 Subject: sys-apps/sandbox: fix crashes w/some ELFs #578524 --- .../sandbox/files/sandbox-2.11-exec-hash.patch | 96 ++++++++++++++++++++++ sys-apps/sandbox/sandbox-2.11-r1.ebuild | 82 ++++++++++++++++++ sys-apps/sandbox/sandbox-2.11.ebuild | 81 ------------------ 3 files changed, 178 insertions(+), 81 deletions(-) create mode 100644 sys-apps/sandbox/files/sandbox-2.11-exec-hash.patch create mode 100644 sys-apps/sandbox/sandbox-2.11-r1.ebuild delete mode 100644 sys-apps/sandbox/sandbox-2.11.ebuild (limited to 'sys-apps') diff --git a/sys-apps/sandbox/files/sandbox-2.11-exec-hash.patch b/sys-apps/sandbox/files/sandbox-2.11-exec-hash.patch new file mode 100644 index 00000000000..8a4cd9b0b9b --- /dev/null +++ b/sys-apps/sandbox/files/sandbox-2.11-exec-hash.patch @@ -0,0 +1,96 @@ +From e11815bb7f0656f39e122073e0e3284ec7f5d021 Mon Sep 17 00:00:00 2001 +From: Mike Frysinger +Date: Tue, 29 Mar 2016 23:35:44 -0400 +Subject: [PATCH] libsandbox: fix symtab walking with some ELFs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The strtab assumption works if there is no SysV hash table. +Add logic to handle that scenario. + +URL: https://bugs.gentoo.org/578524 +Reported-by: Toralf Förster +Signed-off-by: Mike Frysinger +--- + libsandbox/wrapper-funcs/__wrapper_exec.c | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +diff --git a/libsandbox/wrapper-funcs/__wrapper_exec.c b/libsandbox/wrapper-funcs/__wrapper_exec.c +index f7f51ab..d372366 100644 +--- a/libsandbox/wrapper-funcs/__wrapper_exec.c ++++ b/libsandbox/wrapper-funcs/__wrapper_exec.c +@@ -83,10 +83,10 @@ static bool sb_check_exec(const char *filename, char *const argv[]) + ({ \ + Elf##n##_Ehdr *ehdr = (void *)elf; \ + Elf##n##_Phdr *phdr = (void *)(elf + ehdr->e_phoff); \ +- Elf##n##_Addr vaddr, filesz, vsym = 0, vstr = 0; \ +- Elf##n##_Off offset, symoff = 0, stroff = 0; \ ++ Elf##n##_Addr vaddr, filesz, vsym = 0, vstr = 0, vhash = 0; \ ++ Elf##n##_Off offset, symoff = 0, stroff = 0, hashoff = 0; \ + Elf##n##_Dyn *dyn; \ +- Elf##n##_Sym *sym; \ ++ Elf##n##_Sym *sym, *symend; \ + uint##n##_t ent_size = 0, str_size = 0; \ + bool dynamic = false; \ + size_t i; \ +@@ -106,6 +106,7 @@ static bool sb_check_exec(const char *filename, char *const argv[]) + case DT_SYMENT: ent_size = dyn->d_un.d_val; break; \ + case DT_STRTAB: vstr = dyn->d_un.d_val; break; \ + case DT_STRSZ: str_size = dyn->d_un.d_val; break; \ ++ case DT_HASH: vhash = dyn->d_un.d_val; break; \ + } \ + ++dyn; \ + } \ +@@ -123,6 +124,8 @@ static bool sb_check_exec(const char *filename, char *const argv[]) + symoff = offset + (vsym - vaddr); \ + if (vstr >= vaddr && vstr < vaddr + filesz) \ + stroff = offset + (vstr - vaddr); \ ++ if (vhash >= vaddr && vhash < vaddr + filesz) \ ++ hashoff = offset + (vhash - vaddr); \ + } \ + \ + /* Finally walk the symbol table. This should generally be fast as \ +@@ -130,18 +133,20 @@ static bool sb_check_exec(const char *filename, char *const argv[]) + * out there do not export any symbols at all. \ + */ \ + if (symoff && stroff) { \ +- sym = (void *)(elf + symoff); \ ++ /* Hash entries are always 32-bits. */ \ ++ uint32_t *hashes = (void *)(elf + hashoff); \ + /* Nowhere is the # of symbols recorded, or the size of the symbol \ +- * table. Instead, we do what glibc does: assume that the string \ +- * table always follows the symbol table. This seems like a poor \ +- * assumption to make, but glibc has gotten by this long. We could \ +- * rely on DT_HASH and walking all the buckets to find the largest \ +- * symbol index, but that's also a bit hacky. \ ++ * table. Instead, we do what glibc does: use the sysv hash table \ ++ * if it exists, else assume that the string table always directly \ ++ * follows the symbol table. This seems like a poor assumption to \ ++ * make, but glibc has gotten by this long. \ + * \ + * We don't sanity check the ranges here as you aren't executing \ + * corrupt programs in the sandbox. \ + */ \ +- for (i = 0; i < (vstr - vsym) / ent_size; ++i) { \ ++ sym = (void *)(elf + symoff); \ ++ symend = vhash ? (sym + hashes[1]) : (void *)(elf + stroff); \ ++ while (sym < symend) { \ + char *symname = (void *)(elf + stroff + sym->st_name); \ + if (ELF##n##_ST_VISIBILITY(sym->st_other) == STV_DEFAULT && \ + sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE && \ +@@ -149,9 +154,8 @@ static bool sb_check_exec(const char *filename, char *const argv[]) + /* Minor optimization to avoid strcmp. */ \ + symname[0] == '_' && symname[1] == '_') { \ + /* Blacklist internal C library symbols. */ \ +- size_t j; \ +- for (j = 0; j < ARRAY_SIZE(libc_alloc_syms); ++j) \ +- if (!strcmp(symname, libc_alloc_syms[j])) { \ ++ for (i = 0; i < ARRAY_SIZE(libc_alloc_syms); ++i) \ ++ if (!strcmp(symname, libc_alloc_syms[i])) { \ + run_in_process = false; \ + goto use_trace; \ + } \ +-- +2.7.4 + diff --git a/sys-apps/sandbox/sandbox-2.11-r1.ebuild b/sys-apps/sandbox/sandbox-2.11-r1.ebuild new file mode 100644 index 00000000000..80013163c5f --- /dev/null +++ b/sys-apps/sandbox/sandbox-2.11-r1.ebuild @@ -0,0 +1,82 @@ +# Copyright 1999-2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# +# don't monkey with this ebuild unless contacting portage devs. +# period. +# + +EAPI="5" + +inherit eutils flag-o-matic multilib-minimal multiprocessing pax-utils + +DESCRIPTION="sandbox'd LD_PRELOAD hack" +HOMEPAGE="https://www.gentoo.org/proj/en/portage/sandbox/" +SRC_URI="mirror://gentoo/${P}.tar.xz + https://dev.gentoo.org/~vapier/dist/${P}.tar.xz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~sparc-fbsd ~x86-fbsd" +IUSE="" + +DEPEND="app-arch/xz-utils + >=app-misc/pax-utils-0.1.19" #265376 +RDEPEND="" + +has sandbox_death_notice ${EBUILD_DEATH_HOOKS} || EBUILD_DEATH_HOOKS="${EBUILD_DEATH_HOOKS} sandbox_death_notice" + +sandbox_death_notice() { + ewarn "If configure failed with a 'cannot run C compiled programs' error, try this:" + ewarn "FEATURES=-sandbox emerge sandbox" +} + +src_prepare() { + epatch "${FILESDIR}"/${P}-exec-hash.patch #578524 + epatch_user +} + +multilib_src_configure() { + filter-lfs-flags #90228 + + local myconf=() + host-is-pax && myconf+=( --disable-pch ) #301299 #425524 #572092 + + ECONF_SOURCE="${S}" \ + econf "${myconf[@]}" +} + +multilib_src_test() { + # Default sandbox build will run with --jobs set to # cpus. + emake check TESTSUITEFLAGS="--jobs=$(makeopts_jobs)" +} + +multilib_src_install_all() { + doenvd "${FILESDIR}"/09sandbox + + keepdir /var/log/sandbox + fowners root:portage /var/log/sandbox + fperms 0770 /var/log/sandbox + + cd "${S}" + dodoc AUTHORS ChangeLog* NEWS README +} + +pkg_preinst() { + chown root:portage "${ED}"/var/log/sandbox + chmod 0770 "${ED}"/var/log/sandbox + + if [[ ${REPLACING_VERSIONS} == 1.* ]] ; then + local old=$(find "${EROOT}"/lib* -maxdepth 1 -name 'libsandbox*') + if [[ -n ${old} ]] ; then + elog "Removing old sandbox libraries for you:" + find "${EROOT}"/lib* -maxdepth 1 -name 'libsandbox*' -print -delete + fi + fi +} + +pkg_postinst() { + if [[ ${REPLACING_VERSIONS} == 1.* ]] ; then + chmod 0755 "${EROOT}"/etc/sandbox.d #265376 + fi +} diff --git a/sys-apps/sandbox/sandbox-2.11.ebuild b/sys-apps/sandbox/sandbox-2.11.ebuild deleted file mode 100644 index 0bbf588cd3d..00000000000 --- a/sys-apps/sandbox/sandbox-2.11.ebuild +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright 1999-2016 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 - -# -# don't monkey with this ebuild unless contacting portage devs. -# period. -# - -EAPI="5" - -inherit eutils flag-o-matic multilib-minimal multiprocessing pax-utils - -DESCRIPTION="sandbox'd LD_PRELOAD hack" -HOMEPAGE="https://www.gentoo.org/proj/en/portage/sandbox/" -SRC_URI="mirror://gentoo/${P}.tar.xz - https://dev.gentoo.org/~vapier/dist/${P}.tar.xz" - -LICENSE="GPL-2" -SLOT="0" -KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~sparc-fbsd ~x86-fbsd" -IUSE="" - -DEPEND="app-arch/xz-utils - >=app-misc/pax-utils-0.1.19" #265376 -RDEPEND="" - -has sandbox_death_notice ${EBUILD_DEATH_HOOKS} || EBUILD_DEATH_HOOKS="${EBUILD_DEATH_HOOKS} sandbox_death_notice" - -sandbox_death_notice() { - ewarn "If configure failed with a 'cannot run C compiled programs' error, try this:" - ewarn "FEATURES=-sandbox emerge sandbox" -} - -src_prepare() { - epatch_user -} - -multilib_src_configure() { - filter-lfs-flags #90228 - - local myconf=() - host-is-pax && myconf+=( --disable-pch ) #301299 #425524 #572092 - - ECONF_SOURCE="${S}" \ - econf "${myconf[@]}" -} - -multilib_src_test() { - # Default sandbox build will run with --jobs set to # cpus. - emake check TESTSUITEFLAGS="--jobs=$(makeopts_jobs)" -} - -multilib_src_install_all() { - doenvd "${FILESDIR}"/09sandbox - - keepdir /var/log/sandbox - fowners root:portage /var/log/sandbox - fperms 0770 /var/log/sandbox - - cd "${S}" - dodoc AUTHORS ChangeLog* NEWS README -} - -pkg_preinst() { - chown root:portage "${ED}"/var/log/sandbox - chmod 0770 "${ED}"/var/log/sandbox - - if [[ ${REPLACING_VERSIONS} == 1.* ]] ; then - local old=$(find "${EROOT}"/lib* -maxdepth 1 -name 'libsandbox*') - if [[ -n ${old} ]] ; then - elog "Removing old sandbox libraries for you:" - find "${EROOT}"/lib* -maxdepth 1 -name 'libsandbox*' -print -delete - fi - fi -} - -pkg_postinst() { - if [[ ${REPLACING_VERSIONS} == 1.* ]] ; then - chmod 0755 "${EROOT}"/etc/sandbox.d #265376 - fi -} -- cgit v1.2.1