Skip to content

Commit d983b33

Browse files
committed
unix: add slash to DT_NEEDED to force loading our libpython
indygreg/PyOxidizer#406 reported that presence of LD_LIBRARY_PATH can cause the loader to pull in a libpython from an unrelated Python install. This is because our DT_NEEDED values were relative paths (e.g. `libpython3.9.so.1.0`) and the Linux loader will use LD_LIBRARY_PATH over DT_RUNPATH unless the DT_NEEDED value contains contains a slash. See the ld.so man page for more. This commit adds a slash to our DT_NEEDED values to force the loader to load an explicit relative path, thus eliminating the potential for LD_LIBRARY_PATH to intefere with libpython resolution.
1 parent e40ebba commit d983b33

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

cpython-unix/build-cpython.sh

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -719,17 +719,24 @@ if [ "${PYBUILD_SHARED}" = "1" ]; then
719719
${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX}
720720
fi
721721
else
722-
LIBPYTHON_SHARED_LIBRARY=${ROOT}/out/python/install/lib/libpython${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX}.so.1.0
722+
LIBPYTHON_SHARED_LIBRARY_BASENAME=libpython${PYTHON_MAJMIN_VERSION}.so.1.0
723+
LIBPYTHON_SHARED_LIBRARY=${ROOT}/out/python/install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME}
723724

724-
patchelf --set-rpath '$ORIGIN/../lib' ${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}
725+
# If we simply set DT_RUNPATH via --set-rpath, LD_LIBRARY_PATH would be used before
726+
# DT_RUNPATH, which could result in confusion at run-time. But if DT_NEEDED
727+
# contains a slash, the explicit path is used.
728+
patchelf --replace-needed ${LIBPYTHON_SHARED_LIBRARY_BASENAME} "\$ORIGIN/../lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME}" \
729+
${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}
725730

726731
# libpython3.so isn't present in debug builds.
727732
if [ -z "${CPYTHON_DEBUG}" ]; then
728-
patchelf --set-rpath '$ORIGIN/../lib' ${ROOT}/out/python/install/lib/libpython3.so
733+
patchelf --replace-needed ${LIBPYTHON_SHARED_LIBRARY_BASENAME} "\$ORIGIN/../lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME}" \
734+
${ROOT}/out/python/install/lib/libpython3.so
729735
fi
730736

731737
if [ -n "${PYTHON_BINARY_SUFFIX}" ]; then
732-
patchelf --set-rpath '$ORIGIN/../lib' ${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX}
738+
patchelf --replace-needed ${LIBPYTHON_SHARED_LIBRARY_BASENAME} "\$ORIGIN/../lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME}" \
739+
${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX}
733740
fi
734741
fi
735742
fi

src/main.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,14 @@ fn validate_elf(
430430
allowed_libraries.extend(extra.iter().map(|x| x.to_string()));
431431
}
432432

433-
allowed_libraries.push(format!("libpython{}.so.1.0", python_major_minor));
434-
allowed_libraries.push(format!("libpython{}d.so.1.0", python_major_minor));
433+
allowed_libraries.push(format!(
434+
"$ORIGIN/../lib/libpython{}.so.1.0",
435+
python_major_minor
436+
));
437+
allowed_libraries.push(format!(
438+
"$ORIGIN/../lib/libpython{}d.so.1.0",
439+
python_major_minor
440+
));
435441

436442
for lib in &elf.libraries {
437443
if !allowed_libraries.contains(&lib.to_string()) {

0 commit comments

Comments
 (0)