From 93c1b75fa77f34cc146506a091f68842da6ef4ea Mon Sep 17 00:00:00 2001 From: Mark Williams Date: Fri, 26 Jan 2018 16:53:19 -0800 Subject: [PATCH 1/8] Move to CentOS 6.9 CentOS 6.9 includes a new enough OpenSSL (1.0.1e) to allow curl to connect to HTTPS URLs. The official 32-bit Docker image does not include the utils-linux-ng package that contains linux32. Without setting a 32-bit personality, yum will download packages for the the host's architecture. Python 2.6 is included, however, so include a Python implementation of setarch(8) to enable bootstrapping. --- docker/Dockerfile-i686 | 5 +- docker/Dockerfile-x86_64 | 2 +- docker/build_scripts/build.sh | 32 +++++------ docker/build_scripts/build_utils.sh | 11 +--- .../build_scripts/epel-release-5-4.noarch.rpm | Bin 12232 -> 0 bytes .../build_scripts/epel-release-6-8.noarch.rpm | Bin 0 -> 14540 bytes docker/prep/linux32 | 50 ++++++++++++++++++ 7 files changed, 69 insertions(+), 31 deletions(-) delete mode 100644 docker/build_scripts/epel-release-5-4.noarch.rpm create mode 100644 docker/build_scripts/epel-release-6-8.noarch.rpm create mode 100755 docker/prep/linux32 diff --git a/docker/Dockerfile-i686 b/docker/Dockerfile-i686 index b408ca31..dc74ab62 100644 --- a/docker/Dockerfile-i686 +++ b/docker/Dockerfile-i686 @@ -1,4 +1,4 @@ -FROM phusion/centos-5-32 +FROM i386/centos:6 MAINTAINER The ManyLinux project ENV LC_ALL=en_US.UTF-8 @@ -8,6 +8,9 @@ ENV PATH /opt/rh/devtoolset-2/root/usr/bin:$PATH ENV LD_LIBRARY_PATH /opt/rh/devtoolset-2/root/usr/lib64:/opt/rh/devtoolset-2/root/usr/lib:/usr/local/lib64:/usr/local/lib ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig +COPY ./prep/linux32 /usr/bin/linux32 +RUN chmod +x /usr/bin/linux32 + COPY ./build_scripts /build_scripts RUN linux32 bash build_scripts/build.sh && rm -r build_scripts diff --git a/docker/Dockerfile-x86_64 b/docker/Dockerfile-x86_64 index abcfcb13..cd80921b 100644 --- a/docker/Dockerfile-x86_64 +++ b/docker/Dockerfile-x86_64 @@ -1,4 +1,4 @@ -FROM centos:5.11 +FROM centos:6.9 MAINTAINER The ManyLinux project ENV LC_ALL en_US.UTF-8 diff --git a/docker/build_scripts/build.sh b/docker/build_scripts/build.sh index bb77314d..b65a5b79 100644 --- a/docker/build_scripts/build.sh +++ b/docker/build_scripts/build.sh @@ -13,15 +13,15 @@ OPENSSL_ROOT=openssl-1.0.2n # Hash from https://www.openssl.org/source/openssl-1.0.2n.tar.gz.sha256 # Matches hash at https://github.com/Homebrew/homebrew-core/blob/99b8ea3594d1f1f78b0fff1fd8ca7d782aa07e13/Formula/openssl.rb#L11 OPENSSL_HASH=370babb75f278c39e0c50e8c4e7493bc0f18db6867478341a832a982fd15a8fe -EPEL_RPM_HASH=0dcc89f9bf67a2a515bad64569b7a9615edc5e018f676a578d5fd0f17d3c81d4 +EPEL_RPM_HASH=e5ed9ecf22d0c4279e92075a64c757ad2b38049bcf5c16c4f2b75d5f6860dc0d DEVTOOLS_HASH=a8ebeb4bed624700f727179e6ef771dafe47651131a00a78b342251415646acc # Update to slightly newer, verified Git commit: # https://github.com/NixOS/patchelf/commit/2a9cefd7d637d160d12dc7946393778fa8abbc58 PATCHELF_VERSION=2a9cefd7d637d160d12dc7946393778fa8abbc58 PATCHELF_HASH=12da4727f09be42ae0b54878e1b8e86d85cb7a5b595731cdc1a0a170c4873c6d -CURL_ROOT=curl-7.57.0 -# https://github.com/Homebrew/homebrew-core/blob/e3a8622111ecefe444194cade5cca3c69165e26c/Formula/curl.rb#L6 -CURL_HASH=c92fe31a348eae079121b73884065e600c533493eb50f1f6cee9c48a3f454826 +CURL_ROOT=curl-7.58.0 +# https://github.com/Homebrew/homebrew-core/blob/b44c24272efdef9a3b2a54d8d8ab72dacfcd580f/Formula/curl.rb#L6 +CURL_HASH=1cb081f97807c01e3ed747b6e1c9fee7a01cb10048f1cd0b5f56cfe0209de731 AUTOCONF_ROOT=autoconf-2.69 AUTOCONF_HASH=954bd69b391edc12d6a4a51a2dd1476543da5c6bbf05a95b59dc0dd6fd4c2969 AUTOMAKE_ROOT=automake-1.15 @@ -35,20 +35,11 @@ SQLITE_AUTOCONF_HASH=d7dd516775005ad87a57f428b6f86afd206cb341722927f104d3f0cf65f # Dependencies for compiling Python that we want to remove from # the final image after compiling Python # GPG installed to verify signatures on Python source tarballs. -PYTHON_COMPILE_DEPS="zlib-devel bzip2-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel gpg" +PYTHON_COMPILE_DEPS="zlib-devel bzip2-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel" # Libraries that are allowed as part of the manylinux1 profile MANYLINUX1_DEPS="glibc-devel libstdc++-devel glib2-devel libX11-devel libXext-devel libXrender-devel mesa-libGL-devel libICE-devel libSM-devel ncurses-devel" -# Centos 5 is EOL and is no longer available from the usual mirrors, so switch -# to http://vault.centos.org -# From: https://github.com/rust-lang/rust/pull/41045 -# The location for version 5 was also removed, so now only the specific release -# (5.11) can be referenced. -sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf -sed -i 's/mirrorlist/#mirrorlist/' /etc/yum.repos.d/*.repo -sed -i 's/#\(baseurl.*\)mirror.centos.org\/centos\/$releasever/\1vault.centos.org\/5.11/' /etc/yum.repos.d/*.repo - # Get build utilities MY_DIR=$(dirname "${BASH_SOURCE[0]}") source $MY_DIR/build_utils.sh @@ -65,16 +56,16 @@ yum -y update # EPEL support yum -y install wget curl -# https://dl.fedoraproject.org/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm -cp $MY_DIR/epel-release-5-4.noarch.rpm . -check_sha256sum epel-release-5-4.noarch.rpm $EPEL_RPM_HASH +# https://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm +cp $MY_DIR/epel-release-6-8.noarch.rpm . +check_sha256sum epel-release-6-8.noarch.rpm $EPEL_RPM_HASH # Dev toolset (for LLVM and other projects requiring C++11 support) curl -fsSLO http://people.centos.org/tru/devtools-2/devtools-2.repo check_sha256sum devtools-2.repo $DEVTOOLS_HASH mv devtools-2.repo /etc/yum.repos.d/devtools-2.repo -rpm -Uvh --replacepkgs epel-release-5*.rpm -rm -f epel-release-5*.rpm +rpm -Uvh --replacepkgs epel-release-6*.rpm +rm -f epel-release-6*.rpm # Development tools and libraries yum -y install bzip2 make git patch unzip bison yasm diffutils \ @@ -82,6 +73,7 @@ yum -y install bzip2 make git patch unzip bison yasm diffutils \ kernel-devel-`uname -r` \ devtoolset-2-binutils devtoolset-2-gcc \ devtoolset-2-gcc-c++ devtoolset-2-gcc-gfortran \ + gpg \ ${PYTHON_COMPILE_DEPS} # Install newest autoconf @@ -152,7 +144,7 @@ ln -s $PY36_BIN/auditwheel /usr/local/bin/auditwheel # final image yum -y erase wireless-tools gtk2 libX11 hicolor-icon-theme \ avahi freetype bitstream-vera-fonts \ - ${PYTHON_COMPILE_DEPS} > /dev/null 2>&1 + ${PYTHON_COMPILE_DEPS} #> /dev/null 2>&1 yum -y install ${MANYLINUX1_DEPS} yum -y clean all > /dev/null 2>&1 yum list installed diff --git a/docker/build_scripts/build_utils.sh b/docker/build_scripts/build_utils.sh index aa06831b..50349f92 100755 --- a/docker/build_scripts/build_utils.sh +++ b/docker/build_scripts/build_utils.sh @@ -2,15 +2,8 @@ # Helper utilities for build PYTHON_DOWNLOAD_URL=https://www.python.org/ftp/python -# XXX: the official https server at www.openssl.org cannot be reached -# with the old versions of openssl and curl in Centos 5.11 hence the fallback -# to the ftp mirror: -OPENSSL_DOWNLOAD_URL=ftp://ftp.openssl.org/source -# Ditto the curl sources -# FIXME: This is about the only mirror that supports bootstrapping over a -# broken version of curl. Unfortunately, we are hardcoding the directory used -# to download the new version of curl. -CURL_DOWNLOAD_URL=https://github.com/curl/curl/releases/download/curl-7_57_0 +OPENSSL_DOWNLOAD_URL=https://www.openssl.org/source +CURL_DOWNLOAD_URL=https://curl.haxx.se/download GET_PIP_URL=https://bootstrap.pypa.io/get-pip.py diff --git a/docker/build_scripts/epel-release-5-4.noarch.rpm b/docker/build_scripts/epel-release-5-4.noarch.rpm deleted file mode 100644 index a65162a8e651f6935607aa7e0407661a6add0f4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12232 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

4#gFY{Hifuu@N@Uq2 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 literal 0 HcmV?d00001 diff --git a/docker/prep/linux32 b/docker/prep/linux32 new file mode 100755 index 00000000..db894a60 --- /dev/null +++ b/docker/prep/linux32 @@ -0,0 +1,50 @@ +#!/usr/bin/python +""" +Emulate linux32, i.e. setarch(8). +""" +import os +import ctypes +import sys + +# Retrieved from a 32-bit CentOS 6.9 installation's +# /usr/include/sys/personality.h header. +LINUX_32 = 0x0008 + +# Grab libc from our process +process_namespace = ctypes.CDLL(None, use_errno=True) +# int personality(unsigned long persona); +__syscall_personality = process_namespace.personality +__syscall_personality.argtypes = [ctypes.c_ulong] +__syscall_personality.restype = ctypes.c_int + + +def personality(persona): + """ + Wrap behavior of personality(2). + """ + set_persona = __syscall_personality(persona) + if set_persona == -1: + errno = ctypes.get_errno() + OSError(errno, os.strerror(errno)) + + return set_persona + + +personality(LINUX_32) + +argv = sys.argv[1:] +if not argv: + os.execlp("/bin/sh", "-sh") +elif argv[0] in ('-h', '--h', '-help', '--help'): + print("""Usage: +linux32 [ [...]] + +Change the reported architecture to 32 bits. +THIS IS JUST A STUB FOR BOOTSTRAPPING! +Please install utils-linux-ng for the real executable. +""") +elif argv[0].startswith('-'): + print("linux32: Unknown option") + print("linux32: Try `linux32 --help' for more information.") +else: + os.execvp(argv[0], argv) From e9493d55471d153089df3aafca8cfbcb50fa8093 Mon Sep 17 00:00:00 2001 From: Mark Williams Date: Fri, 26 Jan 2018 22:36:58 -0800 Subject: [PATCH 2/8] Recompile glibc without vsyscall. --- docker/Dockerfile-x86_64 | 3 + docker/prep/CentOS-source.repo | 7 + docker/prep/glibc.spec.patch | 20 + docker/prep/rebuild-glibc-without-vsyscall.sh | 121 ++++++ docker/prep/remove-vsyscall.patch | 401 ++++++++++++++++++ 5 files changed, 552 insertions(+) create mode 100644 docker/prep/CentOS-source.repo create mode 100644 docker/prep/glibc.spec.patch create mode 100644 docker/prep/rebuild-glibc-without-vsyscall.sh create mode 100644 docker/prep/remove-vsyscall.patch diff --git a/docker/Dockerfile-x86_64 b/docker/Dockerfile-x86_64 index cd80921b..93570352 100644 --- a/docker/Dockerfile-x86_64 +++ b/docker/Dockerfile-x86_64 @@ -8,6 +8,9 @@ ENV PATH /opt/rh/devtoolset-2/root/usr/bin:$PATH ENV LD_LIBRARY_PATH /opt/rh/devtoolset-2/root/usr/lib64:/opt/rh/devtoolset-2/root/usr/lib:/usr/local/lib64:/usr/local/lib ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig +COPY prep /prep +RUN bash prep/rebuild-glibc-without-vsyscall.sh && rm -r /prep + COPY build_scripts /build_scripts RUN bash build_scripts/build.sh && rm -r build_scripts diff --git a/docker/prep/CentOS-source.repo b/docker/prep/CentOS-source.repo new file mode 100644 index 00000000..c7ccc32b --- /dev/null +++ b/docker/prep/CentOS-source.repo @@ -0,0 +1,7 @@ +[base-source] +name=CentOS-6.9 - Base SRPMS +baseurl=http://vault.centos.org/6.9/os/Source/ +gpgcheck=1 +gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-6 +priority=1 +enabled=1 diff --git a/docker/prep/glibc.spec.patch b/docker/prep/glibc.spec.patch new file mode 100644 index 00000000..1f9a5fc5 --- /dev/null +++ b/docker/prep/glibc.spec.patch @@ -0,0 +1,20 @@ +diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec +index 9bd07c9..eb601a4 100644 +--- a/SPECS/glibc.spec ++++ b/SPECS/glibc.spec +@@ -273,6 +273,7 @@ Patch240: glibc-rh1384281.patch + Patch241: glibc-rh1338673.patch + Patch242: glibc-rh1358015.patch + Patch243: glibc-rh1012343.patch ++Patch244: remove-vsyscall.patch + + Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + Obsoletes: glibc-profile < 2.4 +@@ -719,6 +720,7 @@ package or when debugging this package. + %patch241 -p1 + %patch242 -p1 + %patch243 -p1 ++%patch244 -E -p3 + + # A lot of programs still misuse memcpy when they have to use + # memmove. The memcpy implementation below is not tolerant at \ No newline at end of file diff --git a/docker/prep/rebuild-glibc-without-vsyscall.sh b/docker/prep/rebuild-glibc-without-vsyscall.sh new file mode 100644 index 00000000..1515d964 --- /dev/null +++ b/docker/prep/rebuild-glibc-without-vsyscall.sh @@ -0,0 +1,121 @@ +#!/bin/sh +# Prep script for x86_64 that recompiles glibc without vsyscalls. +# +# tl;dr: Because of +# https://mail.python.org/pipermail/wheel-builders/2016-December/000239.html, +# this removes vsyscall code from glibc. This requires building the +# image on a system with vsyscall=emulate but allows the resulting +# container to run on systems with vsyscall=none or vsyscall=emulate. +# +# "vsyscall" is an antiquated optimization for a small number of +# frequently-used system calls. A vsyscall-enabeld Linux kernel would +# map a read-only page of data and system calls into a process' memory +# at a fixed address. These system calls could be invoked by +# dereferencing a function pointers to fixed offsets in that page, +# saving a relatively expensive context switch. [1] +# +# Unfortunately, because the code and its location in memory were +# fixed and well-known, the vsyscall mechanism became a source of +# gadgets for ROP attacks (specifically, Sigreturn-Oriented Programs) +# [2]. Linux 3.1 introduced vsyscall emulation that prevented +# attackers from jumping into the middle of the system calls' code at +# the expense of speed, as well as the ability to disable it entirely. +# [3][4] The vsyscall mechanism could not be eliminated at the time +# because glibc versions earlier than 2.14 contained hard-coded +# references to the fixed memory address, specifically in time(2). [5] +# These segfault when attempting to issue a vsyscall against a kernel +# that has disabled vsyscalls. +# +# Linux introduced a "virtual dynamic shared object" (vDSO) that +# achieves the same high-speed, in-process system call mechanism via +# shared objects sometime before the kernel's migration to git. While +# old itself, vDSO's presentation as a shared library allows it to +# benefit from ASLR on modern systems, making it no more amenable to +# ROP gadgets than any other shared library. glibc only switched over +# completely to vDSO as of glibc 2.25, so until recently vsyscall +# emulation has remained on for most kernels. [6] Furthermore, i686 +# does not use vsyscall at all, so it requires no patching. +# +# At the same time, vsyscall emulation still exposed values useful to +# ROP attacks, so Linux 4.4 added a compilation option to disable +# it. [7][8] Distributions are beginning to ship kernels configured +# without vsyscall, and running CentOS 5 (glibc 2.5) or 6 (glibc 2.12) +# Docker containers on these distributions indeed causes segfaults +# without vsyscall=emulate [9][10]. CentOS 6, however, is supported +# until 2020, and it's likely that more and more distributions will +# ship with CONFIG_LEGACY_VSYSCALL_NONE. If managed CI services like +# Travis make this switch, developers will be unable to build +# manylinux2 wheels with our Docker image. +# +# Fortunately, vsyscall is merely an optimization, and patches that +# remove it can be backported to glibc 2.12 and the library +# recompiled. The result is a Docker image that can be run on kernels +# regardless of their vsyscall configuration because executable and +# libraries on CentOS are dynamically linked against glibc. Libraries +# built on this image are unaffected because: +# +# a) the kernel only maps vsyscall pages into processes; +# b) only glibc used the vsyscall interface directly, and it's +# included in manylinux2's whitelist policy. +# +# Developers who build the manylinux2 Docker image itself, however, +# must do so on a system with vsyscall=emulate. +# +# References: +# [1] https://lwn.net/Articles/446528/ +# [2] http://www.cs.vu.nl/~herbertb/papers/srop_sp14.pdf +# [3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5cec93c216db77c45f7ce970d46283bcb1933884 +# [4] https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.1 +# [5] https://sourceware.org/git/?p=glibc.git;a=blob;f=ChangeLog;h=3a6abda7d07fdaa367c48a9274cc1c08498964dc;hb=356f8bc660a154a07b03da7c536831da5c8f74fe +# [6] https://sourceware.org/git/?p=glibc.git;a=blob;f=ChangeLog;h=6037fef737f0338a84c6fb564b3b8dc1b1221087;hb=58557c229319a3b8d2eefdb62e7df95089eabe37 +# [7] https://googleprojectzero.blogspot.fr/2015/08/three-bypasses-and-fix-for-one-of.html +# [8] https://outflux.net/blog/archives/2016/09/27/security-things-in-linux-v4-4/ +# [9] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=852620#20 +# [10] https://github.com/CentOS/sig-cloud-instance-images/issues/62 + +# Stop at any error, show all commands +set -ex + +# Locate the prep directory +MY_DIR=/$(dirname "${BASH_SOURCE[0]}") + +# glibc version +GLIBC_VERSION=glibc-2.12-1.209 + +# Source RPM topdir +SRPM_TOPDIR=/root/rpmbuild + +# Source RPM download directory +DOWNLOADED_SRPMS=/root/srpms + +# Include the CentOS source RPM repository. +# https://bugs.centos.org/view.php?id=1646 +cp $MY_DIR/CentOS-source.repo /etc/yum.repos.d/CentOS-source.repo + +# Extract and prepare the source +# https://blog.packagecloud.io/eng/2015/04/20/working-with-source-rpms/ +yum -y update +yum -y install yum-utils rpm-build +yum-builddep -y glibc +mkdir $DOWNLOADED_SRPMS +# The glibc RPM's contents are owned by mockbuild +adduser mockbuild +# yumdownloader assumes the current working directory +(cd $DOWNLOADED_SRPMS && yumdownloader --source glibc) +rpm -ivh $DOWNLOADED_SRPMS/$GLIBC_VERSION.el6.src.rpm +# Prepare the source by applying Red Hat and CentOS patches +rpmbuild -bp $SRPM_TOPDIR/SPECS/glibc.spec + +# Copy the vsyscall removal patch into place +cp $MY_DIR/remove-vsyscall.patch $SRPM_TOPDIR/SOURCES +# Patch the RPM spec file so that it uses the vsyscall removal patch +(cd $SRPM_TOPDIR/SPECS && patch -p2 < $MY_DIR/glibc.spec.patch) + +# Build the RPMS +rpmbuild -ba $SRPM_TOPDIR/SPECS/glibc.spec + +# Install the replacement glibc +rpm --install --force --nodeps $SRPM_TOPDIR/RPMS/x86_64/$GLIBC_VERSION.el6.x86_64.rpm + +# XXX: Remove all unneeded dependencies +yum -y erase yum-utils rpm-build diff --git a/docker/prep/remove-vsyscall.patch b/docker/prep/remove-vsyscall.patch new file mode 100644 index 00000000..15f4fdcc --- /dev/null +++ b/docker/prep/remove-vsyscall.patch @@ -0,0 +1,401 @@ +diff --git a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S +index 22beaec..d1e29da 100644 +--- a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S ++++ b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S +@@ -68,10 +68,6 @@ + #endif + + +-/* For the calculation see asm/vsyscall.h. */ +-#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 +- +- + .globl __lll_lock_wait_private + .type __lll_lock_wait_private,@function + .hidden __lll_lock_wait_private +@@ -250,10 +246,9 @@ __lll_timedlock_wait: + /* Get current time. */ + movq %rsp, %rdi + xorl %esi, %esi +- movq $VSYSCALL_ADDR_vgettimeofday, %rax +- /* This is a regular function call, all caller-save registers +- might be clobbered. */ +- callq *%rax ++ /* This call works because we directly jump to a system call entry ++ which preserves all the registers. */ ++ call JUMPTARGET(__gettimeofday) + + /* Compute relative timeout. */ + movq 8(%rsp), %rax +@@ -402,8 +397,9 @@ __lll_timedwait_tid: + /* Get current time. */ + 2: movq %rsp, %rdi + xorl %esi, %esi +- movq $VSYSCALL_ADDR_vgettimeofday, %rax +- callq *%rax ++ /* This call works because we directly jump to a system call entry ++ which preserves all the registers. */ ++ call JUMPTARGET(__gettimeofday) + + /* Compute relative timeout. */ + movq 8(%rsp), %rax +diff --git a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S +index b6537f9..cf9121d 100644 +--- a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S ++++ b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S +@@ -51,9 +51,6 @@ + orl $FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, reg + #endif + +-/* For the calculation see asm/vsyscall.h. */ +-#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 +- + + .globl __lll_robust_lock_wait + .type __lll_robust_lock_wait,@function +@@ -220,10 +217,9 @@ __lll_robust_timedlock_wait: + /* Get current time. */ + movq %rsp, %rdi + xorl %esi, %esi +- movq $VSYSCALL_ADDR_vgettimeofday, %rax +- /* This is a regular function call, all caller-save registers +- might be clobbered. */ +- callq *%rax ++ /* This call works because we directly jump to a system call entry ++ which preserves all the registers. */ ++ call JUMPTARGET(__gettimeofday) + + /* Compute relative timeout. */ + movq 8(%rsp), %rax +diff --git a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S +index fecaa50..9ea8353 100644 +--- a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S ++++ b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S +@@ -26,9 +26,6 @@ + + #include + +-/* For the calculation see asm/vsyscall.h. */ +-#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 +- + + .text + +@@ -490,13 +487,11 @@ __pthread_cond_timedwait: + movq __vdso_clock_gettime@GOTPCREL(%rip), %rax + movq (%rax), %rax + PTR_DEMANGLE (%rax) +- jz 26f + call *%rax +- jmp 27f +-# endif +-26: movl $__NR_clock_gettime, %eax ++# else ++ movl $__NR_clock_gettime, %eax + syscall +-27: ++# endif + # ifndef __ASSUME_POSIX_TIMERS + cmpq $-ENOSYS, %rax + je 19f +@@ -510,8 +505,9 @@ __pthread_cond_timedwait: + # else + leaq 24(%rsp), %rdi + xorl %esi, %esi +- movq $VSYSCALL_ADDR_vgettimeofday, %rax +- callq *%rax ++ /* This call works because we directly jump to a system call entry ++ which preserves all the registers. */ ++ call JUMPTARGET(__gettimeofday) + + /* Compute relative timeout. */ + movq 40(%rsp), %rax +@@ -648,8 +644,9 @@ __pthread_cond_timedwait: + /* clock_gettime not available. */ + 19: leaq 32(%rsp), %rdi + xorl %esi, %esi +- movq $VSYSCALL_ADDR_vgettimeofday, %rax +- callq *%rax ++ /* This call works because we directly jump to a system call entry ++ which preserves all the registers. */ ++ call JUMPTARGET(__gettimeofday) + + /* Compute relative timeout. */ + movq 40(%rsp), %rax +diff --git a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S +index 22a4744..f65d976 100644 +--- a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S ++++ b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S +@@ -23,10 +23,6 @@ + #include + #include + +- +-/* For the calculation see asm/vsyscall.h. */ +-#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 +- + .text + + .globl pthread_rwlock_timedrdlock +@@ -123,8 +119,9 @@ pthread_rwlock_timedrdlock: + /* Get current time. */ + movq %rsp, %rdi + xorl %esi, %esi +- movq $VSYSCALL_ADDR_vgettimeofday, %rax +- callq *%rax ++ /* This call works because we directly jump to a system call entry ++ which preserves all the registers. */ ++ call JUMPTARGET(__gettimeofday) + + /* Compute relative timeout. */ + movq 8(%rsp), %rax +diff --git a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S +index 20a9c00..4338e02 100644 +--- a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S ++++ b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S +@@ -23,10 +23,6 @@ + #include + #include + +- +-/* For the calculation see asm/vsyscall.h. */ +-#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 +- + .text + + .globl pthread_rwlock_timedwrlock +@@ -120,8 +116,9 @@ pthread_rwlock_timedwrlock: + /* Get current time. */ + movq %rsp, %rdi + xorl %esi, %esi +- movq $VSYSCALL_ADDR_vgettimeofday, %rax +- callq *%rax ++ /* This call works because we directly jump to a system call entry ++ which preserves all the registers. */ ++ call JUMPTARGET(__gettimeofday) + + /* Compute relative timeout. */ + movq 8(%rsp), %rax +diff --git a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S +index c339494..30e67e2 100644 +--- a/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S ++++ b/BUILD/glibc-2.12-2-gc4ccff1/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S +@@ -24,10 +24,6 @@ + #include + #include + +- +-/* For the calculation see asm/vsyscall.h. */ +-#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 +- + .text + + .globl sem_timedwait +@@ -212,9 +208,10 @@ sem_timedwait: + addq $1, NWAITERS(%r12) + + 7: xorl %esi, %esi +- movq %rsp, %rdi +- movq $VSYSCALL_ADDR_vgettimeofday, %rax +- callq *%rax ++ movq %rsp,%rdi ++ /* This call works because we directly jump to a system call entry ++ which preserves all the registers. */ ++ call JUMPTARGET(__gettimeofday) + + /* Compute relative timeout. */ + movq 8(%rsp), %rax +diff --git a/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S b/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S +deleted file mode 100644 +index 18ec6db..0000000 +--- a/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S ++++ /dev/null +@@ -1,50 +0,0 @@ +-/* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, write to the Free +- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +- 02111-1307 USA. */ +- +-#include +-#define _ERRNO_H 1 +-#include +- +-/* For the calculation see asm/vsyscall.h. */ +-#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 +- +- +-ENTRY (__gettimeofday) +- /* Align stack. */ +- sub $0x8, %rsp +- cfi_adjust_cfa_offset(8) +-#ifdef SHARED +- movq __vdso_gettimeofday(%rip), %rax +- PTR_DEMANGLE (%rax) +-#else +- movq $VSYSCALL_ADDR_vgettimeofday, %rax +-#endif +- callq *%rax +- /* Check error return. */ +- cmpl $-4095, %eax +- jae SYSCALL_ERROR_LABEL +- +-L(pseudo_end): +- add $0x8, %rsp +- cfi_adjust_cfa_offset(-8) +- ret +-PSEUDO_END(__gettimeofday) +- +-libc_hidden_def (__gettimeofday) +-weak_alias (__gettimeofday, gettimeofday) +-libc_hidden_weak (gettimeofday) +diff --git a/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/init-first.c b/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/init-first.c +index ead7dbc..08c1ef7 100644 +--- a/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/init-first.c ++++ b/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/init-first.c +@@ -17,6 +17,7 @@ + 02111-1307 USA. */ + + #ifdef SHARED ++# include + # include + # include + +@@ -26,6 +27,8 @@ long int (*__vdso_clock_gettime) (clockid_t, struct timespec *) + __attribute__ ((nocommon)); + strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden) + ++extern int __gettimeofday (struct timeval *__tv, struct timezone *__tz); ++ + + static inline void + _libc_vdso_platform_setup (void) +@@ -33,10 +36,9 @@ _libc_vdso_platform_setup (void) + PREPARE_VERSION (linux26, "LINUX_2.6", 61765110); + + void *p = _dl_vdso_vsym ("gettimeofday", &linux26); +- /* If the vDSO is not available we fall back on the old vsyscall. */ +-#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul ++ /* If the vDSO is not available we fall back on the syscall. */ + if (p == NULL) +- p = (void *) VSYSCALL_ADDR_vgettimeofday; ++ p = __gettimeofday; + PTR_MANGLE (p); + __vdso_gettimeofday = p; + +diff --git a/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S b/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S +deleted file mode 100644 +index a950990..0000000 +--- a/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S ++++ /dev/null +@@ -1,50 +0,0 @@ +-/* Copyright (C) 2007 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, write to the Free +- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +- 02111-1307 USA. */ +- +-#include +-#include +-#define _ERRNO_H 1 +-#include +- +-/* For the calculation see asm/vsyscall.h. */ +-#define VSYSCALL_ADDR_vgetcpu 0xffffffffff600800 +- +- +-ENTRY (sched_getcpu) +- /* Align stack and create local variable for result. */ +- sub $0x8, %rsp +- cfi_adjust_cfa_offset(8) +- +- movq %rsp, %rdi +- xorl %esi, %esi +- movl $VGETCPU_CACHE_OFFSET, %edx +- addq %fs:0, %rdx +- +- movq $VSYSCALL_ADDR_vgetcpu, %rax +- callq *%rax +- +- cmpq $-4095, %rax +- jae SYSCALL_ERROR_LABEL +- +- movl (%rsp), %eax +- +-L(pseudo_end): +- add $0x8, %rsp +- cfi_adjust_cfa_offset(-8) +- ret +-PSEUDO_END(sched_getcpu) +diff --git a/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/time.S b/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/time.S +deleted file mode 100644 +index e3f3268..0000000 +--- a/BUILD/glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/x86_64/time.S ++++ /dev/null +@@ -1,42 +0,0 @@ +-/* Copyright (C) 2001,02, 2003 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, write to the Free +- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +- 02111-1307 USA. */ +- +-#include +-#define _ERRNO_H 1 +-#include +- +-/* For the calculation see asm/vsyscall.h. */ +-#define VSYSCALL_ADDR_vtime 0xffffffffff600400 +- +- +-/* Return the current time as a `time_t' and also put it in *T if T is +- not NULL. Time is represented as seconds from Jan 1 00:00:00 1970. */ +- +-ENTRY (time) +- /* Align stack. */ +- sub $0x8, %rsp +- cfi_adjust_cfa_offset(8) +- +- movq $VSYSCALL_ADDR_vtime, %rax +- callq *%rax +- +- add $0x8, %rsp +- cfi_adjust_cfa_offset(-8) +- ret +-PSEUDO_END_NOERRNO(time) +-libc_hidden_def (time) From 8c3a3ec5d0da95002a65a10f2b797207aa9d64f4 Mon Sep 17 00:00:00 2001 From: Mark Williams Date: Wed, 31 Jan 2018 15:26:13 -0800 Subject: [PATCH 3/8] Bump version so we can use yum install to replace glibc. --- docker/prep/glibc.spec.patch | 17 ++++++++++---- docker/prep/rebuild-glibc-without-vsyscall.sh | 23 +++++++++++++++---- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/docker/prep/glibc.spec.patch b/docker/prep/glibc.spec.patch index 1f9a5fc5..032ae5b7 100644 --- a/docker/prep/glibc.spec.patch +++ b/docker/prep/glibc.spec.patch @@ -1,13 +1,21 @@ diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec -index 9bd07c9..eb601a4 100644 +index 9bd07c9..c389711 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec +@@ -1,6 +1,6 @@ + %define glibcsrcdir glibc-2.12-2-gc4ccff1 + %define glibcversion 2.12 +-%define glibcrelease 1.209%{?dist} ++%define glibcrelease 1.209.1%{?dist} + %define run_glibc_tests 1 + %define auxarches athlon sparcv9v sparc64v alphaev6 + %define xenarches i686 athlon @@ -273,6 +273,7 @@ Patch240: glibc-rh1384281.patch Patch241: glibc-rh1338673.patch Patch242: glibc-rh1358015.patch Patch243: glibc-rh1012343.patch +Patch244: remove-vsyscall.patch - + Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Obsoletes: glibc-profile < 2.4 @@ -719,6 +720,7 @@ package or when debugging this package. @@ -15,6 +23,7 @@ index 9bd07c9..eb601a4 100644 %patch242 -p1 %patch243 -p1 +%patch244 -E -p3 - + # A lot of programs still misuse memcpy when they have to use - # memmove. The memcpy implementation below is not tolerant at \ No newline at end of file + # memmove. The memcpy implementation below is not tolerant at + diff --git a/docker/prep/rebuild-glibc-without-vsyscall.sh b/docker/prep/rebuild-glibc-without-vsyscall.sh index 1515d964..db065830 100644 --- a/docker/prep/rebuild-glibc-without-vsyscall.sh +++ b/docker/prep/rebuild-glibc-without-vsyscall.sh @@ -79,8 +79,9 @@ set -ex # Locate the prep directory MY_DIR=/$(dirname "${BASH_SOURCE[0]}") -# glibc version -GLIBC_VERSION=glibc-2.12-1.209 +# glibc versions +ORIGINAL_GLIBC_VERSION=2.12-1.209 +PATCHED_GLIBC_VERSION=2.12-1.209.1 # Source RPM topdir SRPM_TOPDIR=/root/rpmbuild @@ -102,7 +103,7 @@ mkdir $DOWNLOADED_SRPMS adduser mockbuild # yumdownloader assumes the current working directory (cd $DOWNLOADED_SRPMS && yumdownloader --source glibc) -rpm -ivh $DOWNLOADED_SRPMS/$GLIBC_VERSION.el6.src.rpm +rpm -ivh $DOWNLOADED_SRPMS/glibc-$ORIGINAL_GLIBC_VERSION.el6.src.rpm # Prepare the source by applying Red Hat and CentOS patches rpmbuild -bp $SRPM_TOPDIR/SPECS/glibc.spec @@ -115,7 +116,19 @@ cp $MY_DIR/remove-vsyscall.patch $SRPM_TOPDIR/SOURCES rpmbuild -ba $SRPM_TOPDIR/SPECS/glibc.spec # Install the replacement glibc -rpm --install --force --nodeps $SRPM_TOPDIR/RPMS/x86_64/$GLIBC_VERSION.el6.x86_64.rpm +yum -y install \ + $SRPM_TOPDIR/RPMS/x86_64/glibc-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ + $SRPM_TOPDIR/RPMS/x86_64/glibc-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ + $SRPM_TOPDIR/RPMS/x86_64/glibc-debuginfo-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ + $SRPM_TOPDIR/RPMS/x86_64/glibc-devel-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ + $SRPM_TOPDIR/RPMS/x86_64/glibc-static-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ + $SRPM_TOPDIR/RPMS/x86_64/nscd-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ + $SRPM_TOPDIR/RPMS/x86_64/glibc-common-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ + $SRPM_TOPDIR/RPMS/x86_64/glibc-debuginfo-common-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ + $SRPM_TOPDIR/RPMS/x86_64/glibc-headers-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ + $SRPM_TOPDIR/RPMS/x86_64/glibc-utils-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm -# XXX: Remove all unneeded dependencies +## XXX: Remove all unneeded dependencies yum -y erase yum-utils rpm-build +rm -rf $DOWNLOADED_SRPMS +rm -rf $SRPM_TOPDIR From b36cd13f7eca82f9386650ef107d97fd6a203f50 Mon Sep 17 00:00:00 2001 From: Mark Williams Date: Sun, 4 Feb 2018 00:26:43 -0800 Subject: [PATCH 4/8] Restore yum installation log suppression. --- docker/build_scripts/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/build_scripts/build.sh b/docker/build_scripts/build.sh index b65a5b79..9c931d4b 100644 --- a/docker/build_scripts/build.sh +++ b/docker/build_scripts/build.sh @@ -144,7 +144,7 @@ ln -s $PY36_BIN/auditwheel /usr/local/bin/auditwheel # final image yum -y erase wireless-tools gtk2 libX11 hicolor-icon-theme \ avahi freetype bitstream-vera-fonts \ - ${PYTHON_COMPILE_DEPS} #> /dev/null 2>&1 + ${PYTHON_COMPILE_DEPS} > /dev/null 2>&1 yum -y install ${MANYLINUX1_DEPS} yum -y clean all > /dev/null 2>&1 yum list installed From c1e47953dc3adfe2c5c1d89383b961bc9003c5fd Mon Sep 17 00:00:00 2001 From: Mark Williams Date: Sun, 4 Feb 2018 00:37:02 -0800 Subject: [PATCH 5/8] Mute glibc build logs; use a multistage build to reduce size. MAINTAINER is also deprecated, so that's replaced with LABEL. --- docker/Dockerfile-x86_64 | 13 ++++++++---- docker/prep/rebuild-glibc-without-vsyscall.sh | 20 +------------------ 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/docker/Dockerfile-x86_64 b/docker/Dockerfile-x86_64 index 93570352..a1e6936c 100644 --- a/docker/Dockerfile-x86_64 +++ b/docker/Dockerfile-x86_64 @@ -1,15 +1,20 @@ +FROM centos:6.9 as build_glibc + +COPY prep /prep +RUN bash prep/rebuild-glibc-without-vsyscall.sh + FROM centos:6.9 -MAINTAINER The ManyLinux project +LABEL maintainer="The ManyLinux project" ENV LC_ALL en_US.UTF-8 ENV LANG en_US.UTF-8 ENV LANGUAGE en_US.UTF-8 ENV PATH /opt/rh/devtoolset-2/root/usr/bin:$PATH ENV LD_LIBRARY_PATH /opt/rh/devtoolset-2/root/usr/lib64:/opt/rh/devtoolset-2/root/usr/lib:/usr/local/lib64:/usr/local/lib -ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig +ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig -COPY prep /prep -RUN bash prep/rebuild-glibc-without-vsyscall.sh && rm -r /prep +COPY --from=build_glibc /root/rpmbuild/RPMS /RPMS +RUN yum -y install /RPMS/x86_64/*.rpm && rm -r /RPMS COPY build_scripts /build_scripts RUN bash build_scripts/build.sh && rm -r build_scripts diff --git a/docker/prep/rebuild-glibc-without-vsyscall.sh b/docker/prep/rebuild-glibc-without-vsyscall.sh index db065830..2cc4ebd1 100644 --- a/docker/prep/rebuild-glibc-without-vsyscall.sh +++ b/docker/prep/rebuild-glibc-without-vsyscall.sh @@ -113,22 +113,4 @@ cp $MY_DIR/remove-vsyscall.patch $SRPM_TOPDIR/SOURCES (cd $SRPM_TOPDIR/SPECS && patch -p2 < $MY_DIR/glibc.spec.patch) # Build the RPMS -rpmbuild -ba $SRPM_TOPDIR/SPECS/glibc.spec - -# Install the replacement glibc -yum -y install \ - $SRPM_TOPDIR/RPMS/x86_64/glibc-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ - $SRPM_TOPDIR/RPMS/x86_64/glibc-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ - $SRPM_TOPDIR/RPMS/x86_64/glibc-debuginfo-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ - $SRPM_TOPDIR/RPMS/x86_64/glibc-devel-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ - $SRPM_TOPDIR/RPMS/x86_64/glibc-static-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ - $SRPM_TOPDIR/RPMS/x86_64/nscd-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ - $SRPM_TOPDIR/RPMS/x86_64/glibc-common-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ - $SRPM_TOPDIR/RPMS/x86_64/glibc-debuginfo-common-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ - $SRPM_TOPDIR/RPMS/x86_64/glibc-headers-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm \ - $SRPM_TOPDIR/RPMS/x86_64/glibc-utils-$PATCHED_GLIBC_VERSION.el6.x86_64.rpm - -## XXX: Remove all unneeded dependencies -yum -y erase yum-utils rpm-build -rm -rf $DOWNLOADED_SRPMS -rm -rf $SRPM_TOPDIR +rpmbuild -ba $SRPM_TOPDIR/SPECS/glibc.spec >/dev/null 2>&1 From 59d0f78ec7eb484a369e6f9b51c34b9f9d1e4b0f Mon Sep 17 00:00:00 2001 From: Mark Williams Date: Sun, 4 Feb 2018 20:09:29 -0800 Subject: [PATCH 6/8] vsyscall-less glibc lives in its own base image. The Dockerfile and supporting scripts for this live in docker/glibc/. This cannot be built on Travis because it takes too long and emits too many log messages. Later patches should address reproducibility. --- docker/Dockerfile-x86_64 | 11 +- docker/{prep => build_scripts}/linux32 | 0 docker/glibc/Dockerfile | 11 ++ docker/glibc/README.rst | 79 ++++++++++++ .../build_scripts}/CentOS-source.repo | 0 .../build_scripts}/glibc.spec.patch | 0 .../rebuild-glibc-without-vsyscall.sh | 46 +++++++ .../build_scripts}/remove-vsyscall.patch | 0 docker/prep/rebuild-glibc-without-vsyscall.sh | 116 ------------------ 9 files changed, 138 insertions(+), 125 deletions(-) rename docker/{prep => build_scripts}/linux32 (100%) create mode 100644 docker/glibc/Dockerfile create mode 100644 docker/glibc/README.rst rename docker/{prep => glibc/build_scripts}/CentOS-source.repo (100%) rename docker/{prep => glibc/build_scripts}/glibc.spec.patch (100%) create mode 100644 docker/glibc/build_scripts/rebuild-glibc-without-vsyscall.sh rename docker/{prep => glibc/build_scripts}/remove-vsyscall.patch (100%) delete mode 100644 docker/prep/rebuild-glibc-without-vsyscall.sh diff --git a/docker/Dockerfile-x86_64 b/docker/Dockerfile-x86_64 index a1e6936c..84535b02 100644 --- a/docker/Dockerfile-x86_64 +++ b/docker/Dockerfile-x86_64 @@ -1,9 +1,5 @@ -FROM centos:6.9 as build_glibc - -COPY prep /prep -RUN bash prep/rebuild-glibc-without-vsyscall.sh - -FROM centos:6.9 +# See docker/glibc/ +FROM markrwilliams/manylinux2:centos-6.9-no-vsyscall LABEL maintainer="The ManyLinux project" ENV LC_ALL en_US.UTF-8 @@ -13,9 +9,6 @@ ENV PATH /opt/rh/devtoolset-2/root/usr/bin:$PATH ENV LD_LIBRARY_PATH /opt/rh/devtoolset-2/root/usr/lib64:/opt/rh/devtoolset-2/root/usr/lib:/usr/local/lib64:/usr/local/lib ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig -COPY --from=build_glibc /root/rpmbuild/RPMS /RPMS -RUN yum -y install /RPMS/x86_64/*.rpm && rm -r /RPMS - COPY build_scripts /build_scripts RUN bash build_scripts/build.sh && rm -r build_scripts diff --git a/docker/prep/linux32 b/docker/build_scripts/linux32 similarity index 100% rename from docker/prep/linux32 rename to docker/build_scripts/linux32 diff --git a/docker/glibc/Dockerfile b/docker/glibc/Dockerfile new file mode 100644 index 00000000..7cbb4490 --- /dev/null +++ b/docker/glibc/Dockerfile @@ -0,0 +1,11 @@ +FROM centos:6.9 as centos-with-vsyscall + +COPY ./build_scripts /build_scripts +RUN bash /build_scripts/rebuild-glibc-without-vsyscall.sh + +FROM centos:6.9 +LABEL maintainer="The Manylinux project" + +COPY --from=centos-with-vsyscall /rpms /rpms + +RUN yum -y install /rpms/* && rm -rf /rpms diff --git a/docker/glibc/README.rst b/docker/glibc/README.rst new file mode 100644 index 00000000..24d3d2ed --- /dev/null +++ b/docker/glibc/README.rst @@ -0,0 +1,79 @@ +centos-6.9-no-vsyscall +====================== + +*Summary*: Because of +https://mail.python.org/pipermail/wheel-builders/2016-December/000239.html, +this a CentOS 6.9 Docker image that rebuilds ``glibc`` without +*vsyscall* is necessary to reliably run ``manylinux2`` on 64-bit +hosts. This requires building the image on a system with +``vsyscall=emulate`` but allows the resulting container to run on +systems with ``vsyscall=none`` or ``vsyscall=emulate``. + +*vsyscall* is an antiquated optimization for a small number of +frequently-used system calls. A vsyscall-enabled Linux kernel maps a +read-only page of data and system calls into a process' memory at a +fixed address. These system calls can then be invoked by +dereferencing a function pointers to fixed offsets in that page, +saving a relatively expensive context switch. [1]_ + +Unfortunately, because the code and its location in memory are fixed +and well-known, the vsyscall mechanism has become a source of gadgets +for ROP attacks (specifically, Sigreturn-Oriented Programs). [2]_ +Linux 3.1 introduced vsyscall emulation that prevents attackers from +jumping into the middle of the system calls' code at the expense of +speed, as well as the ability to disable it entirely. [3]_ [4]_ The +vsyscall mechanism could not be eliminated at the time because +``glibc`` versions earlier than 2.14 contained hard-coded references +to the fixed memory address, specifically in ``time(2)``. [5]_ These +segfault when attempting to issue a vsyscall-optimized system call +against a kernel that has disabled it. + +Linux introduced a "virtual dynamic shared object" (vDSO) that +achieves the same high-speed, in-process system call mechanism via +shared objects sometime before the kernel's migration to git. While +old itself, vDSO 's presentation as a shared library allows it to +benefit from ASLR on modern systems, making it no more amenable to ROP +gadgets than any other shared library. ``glibc`` only switched over +completely to vDSO as of glibc 2.25, so until recently vsyscall +emulation has remained on for most kernels. [6]_ Furthermore, i686 +does not use vsyscall at all, so no version of ``glibc`` requires +patching on that architecture. + +At the same time, vsyscall emulation still exposed values useful to +ROP attacks, so Linux 4.4 added a compilation option to disable +it. [7]_ [8]_ Distributions are beginning to ship kernels configured +without vsyscall, and running CentOS 5 (``glibc`` 2.5) or 6 (``glibc`` +2.12) Docker containers on these distributions indeed causes segfaults +without ``vsyscall=emulate`` [9]_ [10]_. CentOS 6, however, is +supported until 2020. It is likely that more and more distributions +will ship with ``CONFIG_LEGACY_VSYSCALL_NONE``; if managed CI services +like Travis make this switch, developers will be unable to build +``manylinux2`` wheels with our Docker image. + +Fortunately, vsyscall is merely an optimization, and patches that +remove it can be backported to glibc 2.12 and the library recompiled. +The result is this Docker image. It can be run on kernels regardless +of their vsyscall configuration because executable and libraries on +CentOS are dynamically linked against glibc. Libraries built on this +image are unaffected because: + +a) the kernel only maps vsyscall pages into processes; +b) only glibc used the vsyscall interface directly, and it's + included in manylinux2's whitelist policy. + +Developers who build this vsyscall-less Docker image itself, however, +must do so on a system with ``vsyscall=emulate``. + +References: +=========== + +.. [1] https://lwn.net/Articles/446528/ +.. [2] http://www.cs.vu.nl/~herbertb/papers/srop_sp14.pdf +.. [3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5cec93c216db77c45f7ce970d46283bcb1933884 +.. [4] https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.1 +.. [5] https://sourceware.org/git/?p=glibc.git;a=blob;f=ChangeLog;h=3a6abda7d07fdaa367c48a9274cc1c08498964dc;hb=356f8bc660a154a07b03da7c536831da5c8f74fe +.. [6] https://sourceware.org/git/?p=glibc.git;a=blob;f=ChangeLog;h=6037fef737f0338a84c6fb564b3b8dc1b1221087;hb=58557c229319a3b8d2eefdb62e7df95089eabe37 +.. [7] https://googleprojectzero.blogspot.fr/2015/08/three-bypasses-and-fix-for-one-of.html +.. [8] https://outflux.net/blog/archives/2016/09/27/security-things-in-linux-v4-4/ +.. [9] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=852620#20 +.. [10] https://github.com/CentOS/sig-cloud-instance-images/issues/62 diff --git a/docker/prep/CentOS-source.repo b/docker/glibc/build_scripts/CentOS-source.repo similarity index 100% rename from docker/prep/CentOS-source.repo rename to docker/glibc/build_scripts/CentOS-source.repo diff --git a/docker/prep/glibc.spec.patch b/docker/glibc/build_scripts/glibc.spec.patch similarity index 100% rename from docker/prep/glibc.spec.patch rename to docker/glibc/build_scripts/glibc.spec.patch diff --git a/docker/glibc/build_scripts/rebuild-glibc-without-vsyscall.sh b/docker/glibc/build_scripts/rebuild-glibc-without-vsyscall.sh new file mode 100644 index 00000000..1cebae15 --- /dev/null +++ b/docker/glibc/build_scripts/rebuild-glibc-without-vsyscall.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# Prep script for x86_64 that recompiles glibc without vsyscalls. + +# Stop at any error, show all commands +set -ex + +# Locate the prep directory +MY_DIR=/$(dirname "${BASH_SOURCE[0]}") + +# glibc versions +ORIGINAL_GLIBC_VERSION=2.12-1.209 +PATCHED_GLIBC_VERSION=2.12-1.209.1 + +# Source RPM topdir +SRPM_TOPDIR=/root/rpmbuild + +# Source RPM download directory +DOWNLOADED_SRPMS=/root/srpms + +# Include the CentOS source RPM repository. +# https://bugs.centos.org/view.php?id=1646 +cp $MY_DIR/CentOS-source.repo /etc/yum.repos.d/CentOS-source.repo + +# Extract and prepare the source +# https://blog.packagecloud.io/eng/2015/04/20/working-with-source-rpms/ +yum -y update +yum -y install yum-utils rpm-build +yum-builddep -y glibc +mkdir $DOWNLOADED_SRPMS +# The glibc RPM's contents are owned by mockbuild +adduser mockbuild +# yumdownloader assumes the current working directory +(cd $DOWNLOADED_SRPMS && yumdownloader --source glibc) +rpm -ivh $DOWNLOADED_SRPMS/glibc-$ORIGINAL_GLIBC_VERSION.el6.src.rpm +# Prepare the source by applying Red Hat and CentOS patches +rpmbuild -bp $SRPM_TOPDIR/SPECS/glibc.spec + +# Copy the vsyscall removal patch into place +cp $MY_DIR/remove-vsyscall.patch $SRPM_TOPDIR/SOURCES +# Patch the RPM spec file so that it uses the vsyscall removal patch +(cd $SRPM_TOPDIR/SPECS && patch -p2 < $MY_DIR/glibc.spec.patch) + +# Build the RPMS +rpmbuild -ba $SRPM_TOPDIR/SPECS/glibc.spec + +mv $SRPM_TOPDIR/RPMS/* /rpms/ diff --git a/docker/prep/remove-vsyscall.patch b/docker/glibc/build_scripts/remove-vsyscall.patch similarity index 100% rename from docker/prep/remove-vsyscall.patch rename to docker/glibc/build_scripts/remove-vsyscall.patch diff --git a/docker/prep/rebuild-glibc-without-vsyscall.sh b/docker/prep/rebuild-glibc-without-vsyscall.sh deleted file mode 100644 index 2cc4ebd1..00000000 --- a/docker/prep/rebuild-glibc-without-vsyscall.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/sh -# Prep script for x86_64 that recompiles glibc without vsyscalls. -# -# tl;dr: Because of -# https://mail.python.org/pipermail/wheel-builders/2016-December/000239.html, -# this removes vsyscall code from glibc. This requires building the -# image on a system with vsyscall=emulate but allows the resulting -# container to run on systems with vsyscall=none or vsyscall=emulate. -# -# "vsyscall" is an antiquated optimization for a small number of -# frequently-used system calls. A vsyscall-enabeld Linux kernel would -# map a read-only page of data and system calls into a process' memory -# at a fixed address. These system calls could be invoked by -# dereferencing a function pointers to fixed offsets in that page, -# saving a relatively expensive context switch. [1] -# -# Unfortunately, because the code and its location in memory were -# fixed and well-known, the vsyscall mechanism became a source of -# gadgets for ROP attacks (specifically, Sigreturn-Oriented Programs) -# [2]. Linux 3.1 introduced vsyscall emulation that prevented -# attackers from jumping into the middle of the system calls' code at -# the expense of speed, as well as the ability to disable it entirely. -# [3][4] The vsyscall mechanism could not be eliminated at the time -# because glibc versions earlier than 2.14 contained hard-coded -# references to the fixed memory address, specifically in time(2). [5] -# These segfault when attempting to issue a vsyscall against a kernel -# that has disabled vsyscalls. -# -# Linux introduced a "virtual dynamic shared object" (vDSO) that -# achieves the same high-speed, in-process system call mechanism via -# shared objects sometime before the kernel's migration to git. While -# old itself, vDSO's presentation as a shared library allows it to -# benefit from ASLR on modern systems, making it no more amenable to -# ROP gadgets than any other shared library. glibc only switched over -# completely to vDSO as of glibc 2.25, so until recently vsyscall -# emulation has remained on for most kernels. [6] Furthermore, i686 -# does not use vsyscall at all, so it requires no patching. -# -# At the same time, vsyscall emulation still exposed values useful to -# ROP attacks, so Linux 4.4 added a compilation option to disable -# it. [7][8] Distributions are beginning to ship kernels configured -# without vsyscall, and running CentOS 5 (glibc 2.5) or 6 (glibc 2.12) -# Docker containers on these distributions indeed causes segfaults -# without vsyscall=emulate [9][10]. CentOS 6, however, is supported -# until 2020, and it's likely that more and more distributions will -# ship with CONFIG_LEGACY_VSYSCALL_NONE. If managed CI services like -# Travis make this switch, developers will be unable to build -# manylinux2 wheels with our Docker image. -# -# Fortunately, vsyscall is merely an optimization, and patches that -# remove it can be backported to glibc 2.12 and the library -# recompiled. The result is a Docker image that can be run on kernels -# regardless of their vsyscall configuration because executable and -# libraries on CentOS are dynamically linked against glibc. Libraries -# built on this image are unaffected because: -# -# a) the kernel only maps vsyscall pages into processes; -# b) only glibc used the vsyscall interface directly, and it's -# included in manylinux2's whitelist policy. -# -# Developers who build the manylinux2 Docker image itself, however, -# must do so on a system with vsyscall=emulate. -# -# References: -# [1] https://lwn.net/Articles/446528/ -# [2] http://www.cs.vu.nl/~herbertb/papers/srop_sp14.pdf -# [3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5cec93c216db77c45f7ce970d46283bcb1933884 -# [4] https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.1 -# [5] https://sourceware.org/git/?p=glibc.git;a=blob;f=ChangeLog;h=3a6abda7d07fdaa367c48a9274cc1c08498964dc;hb=356f8bc660a154a07b03da7c536831da5c8f74fe -# [6] https://sourceware.org/git/?p=glibc.git;a=blob;f=ChangeLog;h=6037fef737f0338a84c6fb564b3b8dc1b1221087;hb=58557c229319a3b8d2eefdb62e7df95089eabe37 -# [7] https://googleprojectzero.blogspot.fr/2015/08/three-bypasses-and-fix-for-one-of.html -# [8] https://outflux.net/blog/archives/2016/09/27/security-things-in-linux-v4-4/ -# [9] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=852620#20 -# [10] https://github.com/CentOS/sig-cloud-instance-images/issues/62 - -# Stop at any error, show all commands -set -ex - -# Locate the prep directory -MY_DIR=/$(dirname "${BASH_SOURCE[0]}") - -# glibc versions -ORIGINAL_GLIBC_VERSION=2.12-1.209 -PATCHED_GLIBC_VERSION=2.12-1.209.1 - -# Source RPM topdir -SRPM_TOPDIR=/root/rpmbuild - -# Source RPM download directory -DOWNLOADED_SRPMS=/root/srpms - -# Include the CentOS source RPM repository. -# https://bugs.centos.org/view.php?id=1646 -cp $MY_DIR/CentOS-source.repo /etc/yum.repos.d/CentOS-source.repo - -# Extract and prepare the source -# https://blog.packagecloud.io/eng/2015/04/20/working-with-source-rpms/ -yum -y update -yum -y install yum-utils rpm-build -yum-builddep -y glibc -mkdir $DOWNLOADED_SRPMS -# The glibc RPM's contents are owned by mockbuild -adduser mockbuild -# yumdownloader assumes the current working directory -(cd $DOWNLOADED_SRPMS && yumdownloader --source glibc) -rpm -ivh $DOWNLOADED_SRPMS/glibc-$ORIGINAL_GLIBC_VERSION.el6.src.rpm -# Prepare the source by applying Red Hat and CentOS patches -rpmbuild -bp $SRPM_TOPDIR/SPECS/glibc.spec - -# Copy the vsyscall removal patch into place -cp $MY_DIR/remove-vsyscall.patch $SRPM_TOPDIR/SOURCES -# Patch the RPM spec file so that it uses the vsyscall removal patch -(cd $SRPM_TOPDIR/SPECS && patch -p2 < $MY_DIR/glibc.spec.patch) - -# Build the RPMS -rpmbuild -ba $SRPM_TOPDIR/SPECS/glibc.spec >/dev/null 2>&1 From 8b61bcb999bd064f0f0fd0cf9d279a69ddb8a2be Mon Sep 17 00:00:00 2001 From: Mark Williams Date: Sun, 4 Feb 2018 20:11:21 -0800 Subject: [PATCH 7/8] Use LABEL instead of deprecated MAINTAINER. --- docker/Dockerfile-i686 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docker/Dockerfile-i686 b/docker/Dockerfile-i686 index dc74ab62..3f458a74 100644 --- a/docker/Dockerfile-i686 +++ b/docker/Dockerfile-i686 @@ -1,5 +1,5 @@ FROM i386/centos:6 -MAINTAINER The ManyLinux project +LABEL maintainer="The ManyLinux project" ENV LC_ALL=en_US.UTF-8 ENV LANG=en_US.UTF-8 @@ -8,10 +8,9 @@ ENV PATH /opt/rh/devtoolset-2/root/usr/bin:$PATH ENV LD_LIBRARY_PATH /opt/rh/devtoolset-2/root/usr/lib64:/opt/rh/devtoolset-2/root/usr/lib:/usr/local/lib64:/usr/local/lib ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig -COPY ./prep/linux32 /usr/bin/linux32 -RUN chmod +x /usr/bin/linux32 - COPY ./build_scripts /build_scripts +COPY /build_scripts/linux32 /usr/bin/linux32 +RUN chmod +x /usr/bin/linux32 RUN linux32 bash build_scripts/build.sh && rm -r build_scripts ENV SSL_CERT_FILE=/opt/_internal/certs.pem From 6962584cbbe69c59ae7c33ed152e477d385e7b7a Mon Sep 17 00:00:00 2001 From: Jakub Kaczmarzyk Date: Wed, 21 Feb 2018 11:04:11 -0500 Subject: [PATCH 8/8] fix: allow `docker build` to take up to 40 minutes Travis-CI will kill a job if it does not produce output for 10 minutes. `travis_wait N` will allow a job to run without producing output for up to `N` minutes. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 09c865a4..2f6153cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ matrix: - env: PLATFORM="x86_64" script: - - docker build --rm -t quay.io/pypa/manylinux1_$PLATFORM:$TRAVIS_COMMIT -f docker/Dockerfile-$PLATFORM docker/ + - travis_wait 40 docker build --rm -t quay.io/pypa/manylinux1_$PLATFORM:$TRAVIS_COMMIT -f docker/Dockerfile-$PLATFORM docker/ deploy: