-
-
Notifications
You must be signed in to change notification settings - Fork 29.3k
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
importlib: PermissionError during startup if working directory isn't readable #115911
Labels
type-bug
An unexpected behavior, bug, or error
Comments
moreati
changed the title
importlib: PermissionError during startup if working directory isn't readble
importlib: PermissionError during startup if working directory isn't readable
Feb 25, 2024
Streamlined reproducer, without #!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
PYTHON="${PYTHON:-python}"
P="issue115911"
if [ -d "$P" ]; then
rmdir "$P"
fi
mkdir "$P" # Create directory with permissive mode
cd "$P" # Make it our working directory, while the mode allows
chmod ugo-rx . # Remove read & execute from it, for everyone including us
"$PYTHON" -c "pass" # Try to execute python in it or as a shell oneliner (p="issue115911"; ([ -d "$p" ] && rmdir "$p"); mkdir "$p" && cd "$p" && chmod ugo-rx . && ~/src/cpython/python.exe -c "pass")
|
According to https://manpages.debian.org/buster/manpages-dev/getcwd.3.en.html#NOTES (Debian 10.x, released 2019, linux kernel 4.19, glibc 2.28) on Linux with glibc
In the later case glibc >= 2.27 returns |
moreati
added a commit
to moreati/mitogen
that referenced
this issue
Mar 4, 2024
…eadable On macOS when using a become plugin as an unprivileged user, to another unprivileged user it is likely that the current working directory can't be read. In this case os.cwd() raises PermissionError. On versions of Python currently in the wild (March 2024, CPython <= 3.13) if any non-builtin or non-frozen module (e.g. zlib, base64) is imported then `importlib._bootstrap_external.PathFinder._path_importer_cache()` attempts to call os.cwd() without catching PermissionError. The previous comment about needing an extra .encode() appears to be wrong, atleast for Python 3.x >= 3.6. Command size increased by 54 bytes, bootstrap by 804 bytes. Changed from codecs module to binascii & zlib because they're extensions, and importing them triggers fewer supporting imports (e.g. encodings module). Before ``` ✗ ./preamble_size.py SSH command size: 705 Bootstrap (mitogen.core) size: 17078 (16.68KiB) Original Minimized Compressed mitogen.parent 97884 95.6KiB 50515 49.3KiB 51.6% 12727 12.4KiB 13.0% mitogen.fork 8436 8.2KiB 4130 4.0KiB 49.0% 1648 1.6KiB 19.5% mitogen.ssh 10892 10.6KiB 6952 6.8KiB 63.8% 2113 2.1KiB 19.4% mitogen.sudo 12089 11.8KiB 5924 5.8KiB 49.0% 2249 2.2KiB 18.6% mitogen.select 12325 12.0KiB 2929 2.9KiB 23.8% 964 0.9KiB 7.8% mitogen.service 41699 40.7KiB 22477 22.0KiB 53.9% 5885 5.7KiB 14.1% mitogen.fakessh 15577 15.2KiB 7989 7.8KiB 51.3% 2623 2.6KiB 16.8% mitogen.master 51398 50.2KiB 25715 25.1KiB 50.0% 6886 6.7KiB 13.4% ``` After ``` ✗ ./preamble_size.py SSH command size: 759 Bootstrap (mitogen.core) size: 17882 (17.46KiB) Original Minimized Compressed mitogen.parent 98173 95.9KiB 50571 49.4KiB 51.5% 12747 12.4KiB 13.0% mitogen.fork 8436 8.2KiB 4130 4.0KiB 49.0% 1648 1.6KiB 19.5% mitogen.ssh 10892 10.6KiB 6952 6.8KiB 63.8% 2113 2.1KiB 19.4% mitogen.sudo 12089 11.8KiB 5924 5.8KiB 49.0% 2249 2.2KiB 18.6% mitogen.select 12325 12.0KiB 2929 2.9KiB 23.8% 964 0.9KiB 7.8% mitogen.service 41699 40.7KiB 22477 22.0KiB 53.9% 5885 5.7KiB 14.1% mitogen.fakessh 15577 15.2KiB 7989 7.8KiB 51.3% 2623 2.6KiB 16.8% mitogen.master 56116 54.8KiB 29427 28.7KiB 52.4% 7627 7.4KiB 13.6% ``` Fixes mitogen-hq#885 Refs python/cpython#115911
moreati
added a commit
to moreati/mitogen
that referenced
this issue
Mar 17, 2024
…eadable On macOS when using a become plugin as an unprivileged user, to another unprivileged user it is likely that the current working directory can't be read. In this case os.cwd() raises PermissionError. On versions of Python currently in the wild (March 2024, CPython <= 3.13) if any non-builtin or non-frozen module (e.g. zlib, base64) is imported then `importlib._bootstrap_external.PathFinder._path_importer_cache()` attempts to call os.cwd() without catching PermissionError. The previous comment about needing an extra .encode() appears to be wrong, atleast for Python 3.x >= 3.6. Command size increased by 54 bytes, bootstrap by 804 bytes. Changed from codecs module to binascii & zlib because they're extensions, and importing them triggers fewer supporting imports (e.g. encodings module). Before ``` ✗ ./preamble_size.py SSH command size: 705 Bootstrap (mitogen.core) size: 17078 (16.68KiB) Original Minimized Compressed mitogen.parent 97884 95.6KiB 50515 49.3KiB 51.6% 12727 12.4KiB 13.0% mitogen.fork 8436 8.2KiB 4130 4.0KiB 49.0% 1648 1.6KiB 19.5% mitogen.ssh 10892 10.6KiB 6952 6.8KiB 63.8% 2113 2.1KiB 19.4% mitogen.sudo 12089 11.8KiB 5924 5.8KiB 49.0% 2249 2.2KiB 18.6% mitogen.select 12325 12.0KiB 2929 2.9KiB 23.8% 964 0.9KiB 7.8% mitogen.service 41699 40.7KiB 22477 22.0KiB 53.9% 5885 5.7KiB 14.1% mitogen.fakessh 15577 15.2KiB 7989 7.8KiB 51.3% 2623 2.6KiB 16.8% mitogen.master 51398 50.2KiB 25715 25.1KiB 50.0% 6886 6.7KiB 13.4% ``` After ``` ✗ ./preamble_size.py SSH command size: 759 Bootstrap (mitogen.core) size: 17882 (17.46KiB) Original Minimized Compressed mitogen.parent 98173 95.9KiB 50571 49.4KiB 51.5% 12747 12.4KiB 13.0% mitogen.fork 8436 8.2KiB 4130 4.0KiB 49.0% 1648 1.6KiB 19.5% mitogen.ssh 10892 10.6KiB 6952 6.8KiB 63.8% 2113 2.1KiB 19.4% mitogen.sudo 12089 11.8KiB 5924 5.8KiB 49.0% 2249 2.2KiB 18.6% mitogen.select 12325 12.0KiB 2929 2.9KiB 23.8% 964 0.9KiB 7.8% mitogen.service 41699 40.7KiB 22477 22.0KiB 53.9% 5885 5.7KiB 14.1% mitogen.fakessh 15577 15.2KiB 7989 7.8KiB 51.3% 2623 2.6KiB 16.8% mitogen.master 56116 54.8KiB 29427 28.7KiB 52.4% 7627 7.4KiB 13.6% ``` Fixes mitogen-hq#885 Refs python/cpython#115911
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Bug report
Bug description:
On macOS
importlib._bootstrap_external.PathFinder._path_importer_cache()
raisesPermissionError
during interpreter startup if''
is included insys.path
and the current working directory is not readable.Reproduction
Given a CWD that is not readable by fred, the user fred cannot run Python
Workaround
Adding
-P
, prevents''
being added tosys.path
, so avoids the exceptionDiscussion
On macOS the libc function
getcwd()
can returnEACCES
. From the manpageWhen searching for importable modules
PathFinder._path_importer_cache()
attempts to determine the cwd by callingos.getcwd()
, it handles aFileNotFoundError
exception, but notPermissionError
. BecausePathFinder
is used during interpreter startup user code has no opportunity to catch the exception.Proposed fix
Ignore
PermissionError
inPathFinder._path_importer_cache()
, the same wayFileNotFoundError
is currently. This would result in imports succeeding, but without getting cached. E.g. applying the below change & rebuilding/reinstallingI'm happy to submit a PR with this, and unit tests as deemed suitable
Other Python Versions
In Python 3.10, 3.11 & 3.12 the same exception can occur when user code imports a non-builtin module (e.g.
base64
, zlib), but it does not occur during interpreter startup. I presume this is due to a change in which modules are required during interpreter initialisation.CPython versions tested on:
3.10, 3.11, 3.12, CPython main branch
Operating systems tested on:
macOS
Linked PRs
The text was updated successfully, but these errors were encountered: