Skip to content

Commit

Permalink
unix: remove linking of libcrypt on CPython < 3.11
Browse files Browse the repository at this point in the history
libcrypt.so again makes an unwanted appearance.

It turns out CPython's configure up until 3.11 exhibited arguably
buggy behavior where as part of searching for libcrypt it always added
`-lcrypt` to LIBS, which got picked up by all linker invocations.

Partially applying the upstream patch on CPython < 3.11 makes the
problem go away. See also python/cpython#28881.

Closes #197.
  • Loading branch information
indygreg committed Jan 7, 2024
1 parent d77df80 commit 80cd87f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
7 changes: 7 additions & 0 deletions cpython-unix/build-cpython.sh
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,13 @@ if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_12}" ]; then
patch -p1 -i ${ROOT}/patch-checksharedmods-disable.patch
fi

# CPython < 3.11 always linked against libcrypt. We backport part of
# upstream commit be21706f3760bec8bd11f85ce02ed6792b07f51f to avoid this
# behavior.
if [ -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_10}" ]; then
patch -p1 -i ${ROOT}/patch-configure-crypt-no-modify-libs.patch
fi

# We patched configure.ac above. Reflect those changes.
autoconf

Expand Down
21 changes: 21 additions & 0 deletions cpython-unix/patch-configure-crypt-no-modify-libs.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
diff --git a/configure.ac b/configure.ac
index ac3be3850a..b6e2144783 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4057,6 +4057,8 @@ AC_CHECK_FUNCS(setpgrp,

# We search for both crypt and crypt_r as one or the other may be defined
# This gets us our -lcrypt in LIBS when required on the target platform.
+# Save/restore LIBS to avoid linking libpython with libcrypt.
+LIBS_SAVE=$LIBS
AC_SEARCH_LIBS(crypt, crypt)
AC_SEARCH_LIBS(crypt_r, crypt)

@@ -4071,6 +4073,7 @@ char *r = crypt_r("", "", &d);
[AC_DEFINE(HAVE_CRYPT_R, 1, [Define if you have the crypt_r() function.])],
[])
)
+LIBS=$LIBS_SAVE

AC_CHECK_FUNCS(clock_gettime, [], [
AC_CHECK_LIB(rt, clock_gettime, [
9 changes: 8 additions & 1 deletion src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ const RECOGNIZED_TRIPLES: &[&str] = &[
const ELF_ALLOWED_LIBRARIES: &[&str] = &[
// LSB set.
"libc.so.6",
"libcrypt.so.1",
"libdl.so.2",
"libm.so.6",
"libpthread.so.0",
Expand Down Expand Up @@ -864,6 +863,14 @@ fn validate_elf<'data, Elf: FileHeader<Endian = Endianness>>(
python_major_minor
));

// Allow the _crypt extension module - and only it - to link against libcrypt,
// which is no longer universally present in Linux distros.
if let Some(filename) = path.file_name() {
if filename.to_string_lossy().starts_with("_crypt") {
allowed_libraries.push("libcrypt.so.1".to_string());
}
}

let wanted_glibc_max_version = GLIBC_MAX_VERSION_BY_TRIPLE
.get(target_triple)
.expect("max glibc version not defined for target triple");
Expand Down

0 comments on commit 80cd87f

Please sign in to comment.