You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cv2 import appends a trailing ":" to LD_LIBRARY_PATH — empty entry resolves to CWD and breaks child processes #1268
before import: None
cv2 5.0.0 after import: '/…/site-packages/cv2/../../lib64:'
child sees: '/…/site-packages/cv2/../../lib64:'
cv2/__init__.py (POSIX branch, cv2/__init__.py:146-147 in current wheels):
# amending of LD_LIBRARY_PATH works for sub-processes onlyos.environ['LD_LIBRARY_PATH'] =':'.join(l_vars['BINARIES_PATHS']) +':'+os.environ.get('LD_LIBRARY_PATH', '')
Three problems in one line:
Unconditional trailing : — when LD_LIBRARY_PATH was previously unset the
variable is created with a dangling separator. Per ld.so(8) semantics an empty
entry resolves to the current working directory of every child process.
Global environment mutation — the comment itself notes this "works for
sub-processes only", yet the write persists in os.environ for the whole
process lifetime, so everysubprocess/os.system/webbrowser call made by
the host application inherits the modified path. This is invisible side-channel
state an importer cannot reasonably expect from import cv2.
The injected directory typically does not exist — with standard manylinux
wheel layouts the bundled libraries live in opencv_python.libs/ (located via $ORIGIN RPATH), and <site-packages>/cv2/../../lib64 is absent in venv,
project, and standalone-packaged layouts, so the write buys nothing while
adding the hazard.
Real-world impact
We ship a Nuitka-standalone application whose launcher cds into the release
folder. With cv2 imported, LD_LIBRARY_PATH ends with : → the release folder
(the CWD) enters the child loader path → children that load system OpenSSL
(xdg-open → kde-open, i.e. "open a URL in the default browser") resolve the
bundled, older libssl.so.3/libcrypto.so.3 instead of the system ones and die
with:
kde-open: libssl.so.3: version `OPENSSL_3.2.0' not found (required by /usr/lib/libcurl.so.4)
Any application that imports cv2 and then spawns helper processes from a
directory containing same-named libraries is affected the same way.
Suggested fix
Do not append a dangling separator; only write the variable when there is
something to add and prepend/append with proper joining:
Longer term, prefer not mutating the global environment at all: the bundled
libraries are already found through $ORIGIN RPATH; if an env-based fallback
is really needed, consider documenting it and cleaning up after import, or
exposing an opt-in.
Happy to send a PR to opencv-python/opencv-python (the loader __init__.py)
if you agree with the direction.
Reactions are currently unavailable
Activity
jennifferweslowski-design commented on Sep 9, 2026
The loader line lives in opencv/opencv (modules/python/package/cv2/__init__.py on 5.x), not in this repo’s empty placeholder.
Proposed join fix (no trailing empty LD_LIBRARY_PATH/PATH entry; keeps the default prepend): opencv/opencv#29905
Credits the reproduction and suggested join from this issue. Distinct from opencv/opencv#28994, which gates the mutation on an env flag and still uses the dangling separator.
Activity
jennifferweslowski-design commentedon Sep 9, 2026
The loader line lives in opencv/opencv (
modules/python/package/cv2/__init__.pyon 5.x), not in this repo’s empty placeholder.Proposed join fix (no trailing empty
LD_LIBRARY_PATH/PATHentry; keeps the default prepend): opencv/opencv#29905Credits the reproduction and suggested join from this issue. Distinct from opencv/opencv#28994, which gates the mutation on an env flag and still uses the dangling separator.
python: avoid empty LD_LIBRARY_PATH/PATH entries on import (4.x backp…