-
Notifications
You must be signed in to change notification settings - Fork 225
Manylinux2 #152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Manylinux2 #152
Changes from all commits
93c1b75
e9493d5
8c3a3ec
b36cd13
c1e4795
59d0f78
8b61bcb
6962584
eb06bac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,23 +56,24 @@ 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should be switching to devtoolset-7. That could potentially be a followup PR though... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes! I think the change should be done in this PR, because upgrading to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Building Do you happen to know if any of the newer devtoolset releases target i686?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updating to devtoolset 7 will be nice. Do you anticipate a change to the C++ ABI version? To the best of my knowledge, devtoolset 7 is still forcing you to use the old C++ ABI and statically linking in part of libstdc++ so that CentOS 6 need not ship newer libstdc++. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @markrwilliams looks like the SCL repo is GPG-signed, should be OK: https://copr.fedorainfracloud.org/coprs/rhscl/centos-release-scl/repo/epel-6/rhscl-centos-release-scl-epel-6.repo%20sudo%20yum%20install%20centos-release-scl There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @njsmith It looks like it's not possible to build 32-bit artifacts on a 64-bit CentOS 6 image with devtoolset-7 either. What if we ship devtoolset-7 in the 64-bit image and leave the i686 image with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. devtoolset-2 also can't build all the things devtoolset-7 can – this is conda's issue, because they care about modern C++ support. If you look at the spreadsheet again, I don't think I'd say leptop has "popular 32-bit manylinux wheels" – yeah, it's almost 30% of their manylinux downloads in 2018, but in absolute terms it's 2 downloads :-). (Versus ~15k for cryptography, ~7k for numpy, ~20k for cffi, etc.) Anyway, I don't object to keeping 32-bit support around; it's just a question of whether the extra maintenance cost is worthwhile. I did just check and I don't see 32-bit builds for any of the newer devtoolset compilers either. If you want to do the work to set that up, and it's not too ugly to maintain, then go for it. Or an alternative would be to announce that we don't have the resources to maintain that, and see if anyone cares enough to step up... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's true that It's also true that none of the devtoolsets are built for i686 for some reason. I suspect that they're part of RHEL's paid offering. I think it may be easy (in terms of build scripts, not computing resources) to build an But the easiest thing I can think of is to leave the It's true that this would result in inconsistent build environments, but I don't think it will result in meaningfully inconsistent artifacts because of how the devtoolsets link stuff in. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cryptography is down to 0.4% in the last 30 days for i686 wheels btw. |
||
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 \ | ||
automake which file cmake28 \ | ||
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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 [<program> [<argument>...]] | ||
|
||
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) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs updating.