[issue46478] DirEntry.stat() of os.scandir() has no dir_fd parameter

2022-01-22 Thread STINNER Victor


STINNER Victor  added the comment:

Oh, I didn't test os.scandir() properly. If you pass a file descriptor to 
os.scandir(), it yields DirEntry entries with contains the directory FD. Ignore 
my request, Python works as expected :-D

--
resolution:  -> not a bug
stage:  -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46478] DirEntry.stat() of os.scandir() has no dir_fd parameter

2022-01-22 Thread Dong-hee Na


Change by Dong-hee Na :


--
nosy: +corona10

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46478] DirEntry.stat() of os.scandir() has no dir_fd parameter

2022-01-22 Thread STINNER Victor


New submission from STINNER Victor :

I read the Rust CVE-2022-21658 vulnerability of std::fs::remove_dir_all:
https://blog.rust-lang.org/2022/01/20/cve-2022-21658.html

It's a race condition if an attacker replaces a directory with a symlink while 
Rust is removing the parent directory, Rust follows the symlink rather than 
just removing the symlink.

shutil._rmtree_safe_fd() uses os.scandir(). If 
entry.is_dir(follow_symlinks=False) is true, it calls 
entry.stat(follow_symlinks=False). It opens the directory as a file to remove 
the directory. It checks os.path.samestat(orig_st, os.fstat(dirfd)): if it's 
false, it raises an exception:

try:
# This can only happen if someone replaces
# a directory with a symlink after the call to
# os.scandir or stat.S_ISDIR above.
raise OSError("Cannot call rmtree on a symbolic "
  "link")
except OSError:
onerror(os.path.islink, fullname, sys.exc_info())

I understand that this check is in place to detect the Rust CVE-2022-21658 
vulnerability.

I noticed that the first entry.is_dir(follow_symlinks=False) call does a stat() 
syscall, but it doesn't pass the directory file descriptor. It would be even 
safer to pass it, just in case if the parent directory has been modified in the 
meanwhile as well.

--
components: Library (Lib)
messages: 411338
nosy: serhiy.storchaka, vstinner
priority: normal
severity: normal
status: open
title: DirEntry.stat() of os.scandir() has no dir_fd parameter
versions: Python 3.11

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com