diff --git a/.travis.yml b/.travis.yml index 2b70c259..4cdb347d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ env: matrix: include: - - env: PLATFORM="i686" + # - env: PLATFORM="i686" - env: PLATFORM="x86_64" script: diff --git a/build.sh b/build.sh index 56b42ff8..d3f9fd0c 100755 --- a/build.sh +++ b/build.sh @@ -4,5 +4,9 @@ set -ex docker/build_scripts/prefetch.sh openssl curl -docker build --rm -t quay.io/pypa/manylinux1_$PLATFORM:$TRAVIS_COMMIT -f docker/Dockerfile-$PLATFORM docker/ +if [ $PLATFORM == x86_64 ]; then + echo "Building quay.io/pypa/manylinux2010_centos-6-no-vsyscall" + docker build --rm -t quay.io/pypa/manylinux2010_centos-6-no-vsyscall -f docker/glibc/Dockerfile docker/glibc/ > /dev/null +fi +docker build --rm -t quay.io/pypa/manylinux2010_$PLATFORM:$TRAVIS_COMMIT -f docker/Dockerfile-$PLATFORM docker/ docker system prune -f diff --git a/docker/Dockerfile-i686 b/docker/Dockerfile-i686 index 2d38d493..aecb3575 100644 --- a/docker/Dockerfile-i686 +++ b/docker/Dockerfile-i686 @@ -1,12 +1,17 @@ -FROM phusion/centos-5-32 -MAINTAINER The ManyLinux project -ENV LC_ALL=en_US.UTF-8 -ENV LANG=en_US.UTF-8 +FROM i386/centos:6 +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 PATH /opt/rh/devtoolset-7/root/usr/bin:$PATH +ENV LD_LIBRARY_PATH /opt/rh/devtoolset-7/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 ./build_scripts /build_scripts +COPY /build_scripts/linux32 /usr/bin/linux32 +RUN chmod +x /usr/bin/linux32 COPY build_scripts /build_scripts COPY sources / diff --git a/docker/Dockerfile-x86_64 b/docker/Dockerfile-x86_64 index b921c1aa..37a5ff5f 100644 --- a/docker/Dockerfile-x86_64 +++ b/docker/Dockerfile-x86_64 @@ -1,12 +1,17 @@ -FROM centos:5 -MAINTAINER The ManyLinux project +# See docker/glibc/ +FROM quay.io/pypa/manylinux2010_centos-6-no-vsyscall +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 PATH /opt/rh/devtoolset-7/root/usr/bin:$PATH +ENV LD_LIBRARY_PATH /opt/rh/devtoolset-7/root/usr/lib64:/opt/rh/devtoolset-7/root/usr/lib:/usr/local/lib64:/usr/local/lib +ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig + + + + COPY build_scripts /build_scripts COPY sources / @@ -14,4 +19,7 @@ RUN bash build_scripts/build.sh && rm -r build_scripts ENV SSL_CERT_FILE=/opt/_internal/certs.pem + + + CMD ["/bin/bash"] diff --git a/docker/build_scripts/build.sh b/docker/build_scripts/build.sh index 3a9fdfb8..faac022b 100755 --- a/docker/build_scripts/build.sh +++ b/docker/build_scripts/build.sh @@ -11,19 +11,10 @@ MY_DIR=$(dirname "${BASH_SOURCE[0]}") # 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 libffi-devel" +PYTHON_COMPILE_DEPS="zlib-devel bzip2-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-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 +# Libraries that are allowed as part of the manylinux2010 profile +MANYLINUX2010_DEPS="glibc-devel libstdc++-devel glib2-devel libX11-devel libXext-devel libXrender-devel mesa-libGL-devel libICE-devel libSM-devel ncurses-devel" # Get build utilities source $MY_DIR/build_utils.sh @@ -43,16 +34,14 @@ yum -y update # EPEL support yum -y install wget -# 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) -wget -q 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 +yum -y install centos-release-scl +rpm -Uvh --replacepkgs epel-release-6*.rpm +rm -f epel-release-6*.rpm # from now on, we shall only use curl to retrieve files yum -y erase wget @@ -63,10 +52,10 @@ yum -y install \ bison \ bzip2 \ cmake28 \ - devtoolset-2-binutils \ - devtoolset-2-gcc \ - devtoolset-2-gcc-c++ \ - devtoolset-2-gcc-gfortran \ + devtoolset-7-binutils \ + devtoolset-7-gcc \ + devtoolset-7-gcc-c++ \ + devtoolset-7-gcc-gfortran \ diffutils \ expat-devel \ gettext \ @@ -77,6 +66,7 @@ yum -y install \ unzip \ which \ yasm \ + gpg \ ${PYTHON_COMPILE_DEPS} # Build an OpenSSL for both curl and the Pythons. We'll delete this at the end. @@ -84,6 +74,7 @@ build_openssl $OPENSSL_ROOT $OPENSSL_HASH # Install curl so we can have TLS 1.2 in this ancient container. build_curl $CURL_ROOT $CURL_HASH +export PATH="/opt/curl/bin:$PATH" hash -r curl --version curl-config --features @@ -157,8 +148,10 @@ yum -y erase \ hicolor-icon-theme \ libX11 \ wireless-tools \ - ${PYTHON_COMPILE_DEPS} > /dev/null 2>&1 -yum -y install ${MANYLINUX1_DEPS} + ${PYTHON_COMPILE_DEPS/libffi-devel/} +# Not uninstalling libffi-devel since it's failing to uninstall https://bugs.centos.org/view.php?id=10828 + +yum -y install ${MANYLINUX2010_DEPS} yum -y clean all > /dev/null 2>&1 yum list installed @@ -180,7 +173,7 @@ find /opt/_internal -depth \ for PYTHON in /opt/python/*/bin/python; do # Smoke test to make sure that our Pythons work, and do indeed detect as # being manylinux compatible: - $PYTHON $MY_DIR/manylinux1-check.py + $PYTHON $MY_DIR/manylinux-check.py # Make sure that SSL cert checking works $PYTHON $MY_DIR/ssl-check.py done diff --git a/docker/build_scripts/build_env.sh b/docker/build_scripts/build_env.sh index ef297351..b0db7fe2 100644 --- a/docker/build_scripts/build_env.sh +++ b/docker/build_scripts/build_env.sh @@ -37,5 +37,5 @@ GIT_HASH=ba2fed9d02e424b735e035c4f2b0bdb168ef0df7e35156b5051d900dc7247787 GIT_DOWNLOAD_URL=https://github.com/git/git/archive GET_PIP_URL=https://bootstrap.pypa.io/get-pip.py -EPEL_RPM_HASH=0dcc89f9bf67a2a515bad64569b7a9615edc5e018f676a578d5fd0f17d3c81d4 +EPEL_RPM_HASH=e5ed9ecf22d0c4279e92075a64c757ad2b38049bcf5c16c4f2b75d5f6860dc0d DEVTOOLS_HASH=a8ebeb4bed624700f727179e6ef771dafe47651131a00a78b342251415646acc diff --git a/docker/build_scripts/build_utils.sh b/docker/build_scripts/build_utils.sh index 47003c06..ade5a792 100755 --- a/docker/build_scripts/build_utils.sh +++ b/docker/build_scripts/build_utils.sh @@ -54,10 +54,7 @@ function do_cpython_build { if [ -e ${prefix}/bin/python3 ]; then ln -s python3 ${prefix}/bin/python fi - # --force-reinstall is to work around: - # https://github.com/pypa/pip/issues/5220 - # https://github.com/pypa/get-pip/issues/19 - ${prefix}/bin/python get-pip.py --force-reinstall + ${prefix}/bin/python get-pip.py if [ -e ${prefix}/bin/pip3 ] && [ ! -e ${prefix}/bin/pip ]; then ln -s pip3 ${prefix}/bin/pip fi @@ -170,7 +167,7 @@ function build_git { fetch_source v${git_fname}.tar.gz ${GIT_DOWNLOAD_URL} check_sha256sum v${git_fname}.tar.gz ${git_sha256} tar -xzf v${git_fname}.tar.gz - (cd git-${git_fname} && make install prefix=/usr/local LDFLAGS="-L/usr/local/ssl/lib -ldl" CFLAGS="-I/usr/local/ssl/include" > /dev/null) + (cd git-${git_fname} && make install prefix=/usr/local LDFLAGS="-L/opt/curl/lib -L/usr/local/ssl/lib -ldl" CFLAGS="-I/opt/curl/include -I/usr/local/ssl/include" > /dev/null) rm -rf git-${git_fname} v${git_fname}.tar.gz } @@ -178,7 +175,7 @@ function build_git { function do_curl_build { # We do this shared to avoid obnoxious linker issues where git couldn't # link properly. If anyone wants to make this build statically go for it. - LIBS=-ldl CFLAGS=-Wl,--exclude-libs,ALL ./configure --with-ssl --disable-static > /dev/null + LIBS=-ldl CFLAGS=-Wl,--exclude-libs,ALL ./configure --with-ssl --disable-static --prefix=/opt/curl > /dev/null make > /dev/null make install > /dev/null } 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 a65162a8..00000000 Binary files a/docker/build_scripts/epel-release-5-4.noarch.rpm and /dev/null differ diff --git a/docker/build_scripts/epel-release-6-8.noarch.rpm b/docker/build_scripts/epel-release-6-8.noarch.rpm new file mode 100644 index 00000000..588a577e Binary files /dev/null and b/docker/build_scripts/epel-release-6-8.noarch.rpm differ diff --git a/docker/build_scripts/linux32 b/docker/build_scripts/linux32 new file mode 100755 index 00000000..db894a60 --- /dev/null +++ b/docker/build_scripts/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) diff --git a/docker/build_scripts/manylinux1-check.py b/docker/build_scripts/manylinux-check.py similarity index 82% rename from docker/build_scripts/manylinux1-check.py rename to docker/build_scripts/manylinux-check.py index fa77ef43..8c1031f9 100644 --- a/docker/build_scripts/manylinux1-check.py +++ b/docker/build_scripts/manylinux-check.py @@ -1,6 +1,6 @@ # Logic copied from PEP 513 -def is_manylinux1_compatible(): +def is_manylinux2010_compatible(): # Only Linux, and only x86-64 / i686 from distutils.util import get_platform if get_platform() not in ["linux-x86_64", "linux-i686"]: @@ -14,8 +14,8 @@ def is_manylinux1_compatible(): # Fall through to heuristic check below pass - # Check glibc version. CentOS 5 uses glibc 2.5. - return have_compatible_glibc(2, 5) + # Check glibc version. CentOS 6 uses glibc 2.12. + return have_compatible_glibc(2, 12) def have_compatible_glibc(major, minimum_minor): import ctypes @@ -45,9 +45,9 @@ def have_compatible_glibc(major, minimum_minor): return True import sys -if is_manylinux1_compatible(): - print("%s is manylinux1 compatible" % (sys.executable,)) +if is_manylinux2010_compatible(): + print("%s is manylinux2010 compatible" % (sys.executable,)) sys.exit(0) else: - print("%s is NOT manylinux1 compatible" % (sys.executable,)) + print("%s is NOT manylinux2010 compatible" % (sys.executable,)) sys.exit(1) diff --git a/docker/build_scripts/py36-requirements.txt b/docker/build_scripts/py36-requirements.txt index 27d93828..80e90c75 100644 --- a/docker/build_scripts/py36-requirements.txt +++ b/docker/build_scripts/py36-requirements.txt @@ -3,9 +3,9 @@ certifi==2018.10.15 \ --hash=sha256:339dc09518b07e2fa7eda5450740925974815557727d6bd35d319c1524a04a4c \ --hash=sha256:6d58c986d22b038c8c0df30d639f23a3e6d172a05c3583e766f4c0b785c0986a -auditwheel==1.10.0 \ - --hash=sha256:185365e972342f9d6ecb412a21eb05c42fd0fff24031c4fb917ad0ac588c389d \ - --hash=sha256:2f9c89782757099b85593513f0cfc46da038cb4a238829caca29d5372f83c339 +auditwheel==2.0rc1 \ + --hash=sha256:372f691463c7bec3803a43e2f1fccf048ba5752e12b5a0bbf93e2d0fa0f4a9f5 \ + --hash=sha256:d07d0907d282168a0468e6cf7b17cefb79115369052b6ced0982c95538592ee8 # this package required for auditwheel pyelftools==0.25 \ --hash=sha256:89c6da6f56280c37a5ff33468591ba9a124e17d71fe42de971818cbff46c1b24 @@ -13,4 +13,4 @@ pyelftools==0.25 \ typing==3.6.6 \ --hash=sha256:a4c8473ce11a65999c8f59cb093e70686b6c84c98df58c1dae9b3b196089858a \ --hash=sha256:57dcf675a99b74d64dacf6fba08fb17cf7e3d5fdff53d4a30ea2a5e7e52543d4 \ - --hash=sha256:4027c5f6127a6267a435201981ba156de91ad0d1d98e9ddc2aa173453453492d + --hash=sha256:4027c5f6127a6267a435201981ba156de91ad0d1d98e9ddc2aa173453453492d \ No newline at end of file diff --git a/docker/deploy.sh b/docker/deploy.sh index 471f160a..34791d0a 100755 --- a/docker/deploy.sh +++ b/docker/deploy.sh @@ -1,5 +1,5 @@ #!/bin/bash docker login -u $QUAY_USERNAME -p $QUAY_PASSWORD quay.io -tag="quay.io/pypa/manylinux1_$PLATFORM" +tag="quay.io/pypa/manylinux2010_$PLATFORM" docker tag ${tag}:${TRAVIS_COMMIT} ${tag}:latest docker push ${tag}:latest diff --git a/docker/glibc/Dockerfile b/docker/glibc/Dockerfile new file mode 100644 index 00000000..25bf468b --- /dev/null +++ b/docker/glibc/Dockerfile @@ -0,0 +1,11 @@ +FROM centos:6 as centos-with-vsyscall + +COPY ./build_scripts /build_scripts +RUN bash /build_scripts/rebuild-glibc-without-vsyscall.sh + +FROM centos:6 +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..6175d3f4 --- /dev/null +++ b/docker/glibc/README.rst @@ -0,0 +1,79 @@ +centos-6-no-vsyscall +====================== + +*Summary*: Because of +https://mail.python.org/pipermail/wheel-builders/2016-December/000239.html, +this a CentOS 6 Docker image that rebuilds ``glibc`` without +*vsyscall* is necessary to reliably run ``manylinux2010`` 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 +``manylinux2010`` 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/glibc/build_scripts/CentOS-source.repo b/docker/glibc/build_scripts/CentOS-source.repo new file mode 100644 index 00000000..c7ccc32b --- /dev/null +++ b/docker/glibc/build_scripts/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/glibc/build_scripts/glibc.spec.patch b/docker/glibc/build_scripts/glibc.spec.patch new file mode 100644 index 00000000..032ae5b7 --- /dev/null +++ b/docker/glibc/build_scripts/glibc.spec.patch @@ -0,0 +1,29 @@ +diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec +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. + %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 + 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/glibc/build_scripts/remove-vsyscall.patch b/docker/glibc/build_scripts/remove-vsyscall.patch new file mode 100644 index 00000000..15f4fdcc --- /dev/null +++ b/docker/glibc/build_scripts/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)