Issue46977
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2022-03-10 17:22 by afeblot, last changed 2022-04-11 14:59 by admin.
Messages (1) | |||
---|---|---|---|
msg414871 - (view) | Author: Alexandre Feblot (afeblot) | Date: 2022-03-10 17:22 | |
```python #!/usr/bin/env python3 import os import tempfile def createUnremovableDir(workdir): print(workdir) os.mkdir(f'{workdir}/mydir') os.symlink('/bin/bash', f'{workdir}/mydir/mylink') # Symlink to a root owned file os.chmod(f'{workdir}/mydir', 0o555) with tempfile.TemporaryDirectory() as workdir: createUnremovableDir(workdir) ``` Fails because `tempfile.TemporaryDirectory._rmtree` tries to execute os.chmod(path, 0o700) on the symlink, which by default tries to change the root owned file symlink target instead of the symlink itself: ``` /tmp/tmp1_dy42ef Traceback (most recent call last): File "/usr/lib/python3.9/shutil.py", line 682, in _rmtree_safe_fd os.unlink(entry.name, dir_fd=topfd) PermissionError: [Errno 13] Permission denied: 'mylink' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "~/tempfile_demo_bug.py", line 13, in <module> createUnremovableDir(workdir) File "/usr/lib/python3.9/tempfile.py", line 969, in __exit__ self.cleanup() File "/usr/lib/python3.9/tempfile.py", line 973, in cleanup self._rmtree(self.name) File "/usr/lib/python3.9/tempfile.py", line 955, in _rmtree _rmtree(name, onerror=onerror) File "/usr/lib/python3.9/shutil.py", line 727, in rmtree _rmtree_safe_fd(fd, path, onerror) File "/usr/lib/python3.9/shutil.py", line 664, in _rmtree_safe_fd _rmtree_safe_fd(dirfd, fullname, onerror) File "/usr/lib/python3.9/shutil.py", line 684, in _rmtree_safe_fd onerror(os.unlink, fullname, sys.exc_info()) File "/usr/lib/python3.9/tempfile.py", line 941, in onerror resetperms(path) File "/usr/lib/python3.9/tempfile.py", line 936, in resetperms _os.chmod(path, 0o700) PermissionError: [Errno 1] Operation not permitted: '/tmp/tmp1_dy42ef/mydir/mylink' ``` and leaves: ``` (.venv python 3.9.9) $ find /tmp/tmp1_dy42ef -ls 148228 4 drwx------ 3 myuser myuser 4096 Mar 10 16:54 /tmp/tmp1_dy42ef 148229 4 drwx------ 2 myuser myuser 4096 Mar 10 16:54 /tmp/tmp1_dy42ef/mydir 148230 0 lrwxrwxrwx 1 myuser myuser 9 Mar 10 16:54 /tmp/tmp1_dy42ef/mydir/mylink -> /bin/bash ``` This fixes it: ``` python #!/usr/bin/env python3 import os import tempfile def createUnremovableDir(workdir): print(workdir) os.mkdir(f'{workdir}/mydir') os.symlink('/bin/bash', f'{workdir}/mydir/mylink') # Symlink to a root owned file os.chmod(f'{workdir}/mydir', 0o555) def _rmtree(cls, name, ignore_errors=False): def onerror(func, path, exc_info): if issubclass(exc_info[0], PermissionError): def resetperms(path): try: if os.chflags in os.supports_follow_symlinks: # This is the patch os.chflags(path, 0, follow_symlinks=False) # This is the patch elif not os.path.islink(path): # This is the patch os.chflags(path, 0) except AttributeError: pass if os.chmod in os.supports_follow_symlinks: # This is the patch os.chmod(path, 0o700, follow_symlinks=False) # This is the patch elif not os.path.islink(path): # This is the patch os.chmod(path, 0o700) try: if path != name: resetperms(os.path.dirname(path)) resetperms(path) try: os.unlink(path) # PermissionError is raised on FreeBSD for directories except (IsADirectoryError, PermissionError): cls._rmtree(path, ignore_errors=ignore_errors) except FileNotFoundError: pass elif issubclass(exc_info[0], FileNotFoundError): pass else: if not ignore_errors: raise shutil.rmtree(name, onerror=onerror) # Monkey patch the class method tempfile.TemporaryDirectory._rmtree from types import MethodType import shutil tempfile.TemporaryDirectory._rmtree = MethodType(_rmtree, tempfile.TemporaryDirectory) with tempfile.TemporaryDirectory() as workdir: createUnremovableDir(workdir) |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:59:57 | admin | set | github: 91133 |
2022-03-10 17:25:32 | afeblot | set | type: crash |
2022-03-10 17:22:08 | afeblot | create |