Environment
Description
After a pip install with umask set to 027, files in the environment have incorrect permissions.
I expected the files to have permissions 640, but they ended up as 637. This is both too restrictive at the group level and too permissive at the world level.
Expected behavior
Correct file permissions.
I think the cause is this fix:
https://github.com/pypa/pip/pull/8144/files#diff-81eaeaa2196a8c5382958f2d9f22b593R570
generated_file_mode = 0o666 - current_umask()
>>> oct(0o666 - 0o027)
'0637'
I'd have expected a bitwise AND so the result would be 0640.
How to Reproduce
virtualenv ./env
source env/bin/activate
umask 027
pip install six
ls -lR env/lib/python3.8/site-packages/six-1.14.0.dist-info/
Output
root@674aabd90334:~# virtualenv ./env
Using base prefix '/opt/Python/3.8.1'
New python executable in /root/env/bin/python3.8
copying /opt/Python/3.8.1/bin/python3.8 => /root/env/bin/python3.8
Also creating executable in /root/env/bin/python
Installing setuptools, pip, wheel...
done.
root@674aabd90334:~# source env/bin/activate
(env) root@674aabd90334:~# umask 027
(env) root@674aabd90334:~# pip install six
Collecting six
Using cached six-1.14.0-py2.py3-none-any.whl (10 kB)
Installing collected packages: six
Successfully installed six-1.14.0
(env) root@674aabd90334:~# ls -lR env/lib/python3.8/site-packages/six-1.14.0.dist-info/
env/lib/python3.8/site-packages/six-1.14.0.dist-info/:
total 24
-rw--wxrwx 1 root root 4 Apr 28 21:13 INSTALLER
-rw-r----- 1 root root 1066 Apr 28 21:13 LICENSE
-rw-r----- 1 root root 1795 Apr 28 21:13 METADATA
-rw--wxrwx 1 root root 560 Apr 28 21:13 RECORD
-rw-r----- 1 root root 110 Apr 28 21:13 WHEEL
-rw-r----- 1 root root 4 Apr 28 21:13 top_level.txt
Indeed 0o666 & ~current_umask()
should be better.
We also use -
instead of &~
at
and
Do we need to fix those as well?
@deveshks these were the source of bad inspiration that led to this bug indeed.
These work because we subtract to 0o777, but I'd change them yes. In a separate PR though, because that change would be for 20.2, not for a 20.1 bugfix release.
>>> oct(0o777 - 0o027 | 0o111)
'0o751'
>>> oct(0o666 & ~0o027)
'0o640'
IIUC, the 0o777 - ... | 0o111
form would be the better form, to ensure everyone can read. It'd likely make sense to move this chmod call into a helper, and use it everywhere (to avoid such issues in the future).
Oh wait, I don't understand correctly. The order of the bits is rwx, not xwr. Those other locations are for setting permissions on executable scripts, and don't actually do the right things as OP (and @sbidoul) have pointed out. Hah.
It'd likely make sense to move this chmod call into a helper, and use it everywhere (to avoid such issues in the future).
So do we only move these two os.chmod
calls in pip/src/pip/_internal/utils/unpacking.py
into a helper function in another PR right, along with changing it to os.chmod(path, (0o777 & ~current_umask() | 0o111))
as per @sbidoul right?
Nah, not now -- let's get the specific bugfix merged and then think about the broader fixes. :)
Nah, not now -- let's get the specific bugfix merged and then think about the broader fixes. :)
Agreed, I will create another issue about fixing them and we can discuss there. BTW I have addressed the review comments, and I think that PR is ready to be approved/merged 馃槉
Filed https://github.com/pypa/pip/issues/8179 for fixing file permission in utils/unpacking.py
Most helpful comment
@deveshks these were the source of bad inspiration that led to this bug indeed.
These work because we subtract to 0o777, but I'd change them yes. In a separate PR though, because that change would be for 20.2, not for a 20.1 bugfix release.