New submission from Eryk Sun:

The implementation of nt._getfinalpathname leaks a File handle if calling 
GetFinalPathNameByHandle fails. The latter function is practically guaranteed 
to fail when resolving the path for a non-file-system device. It also fails 
when VOLUME_NAME_DOS is requested for a volume GUID path that isn't currently 
mounted as either a DOS drive letter or an NTFS junction. In this case 
requesting VOLUME_NAME_GUID should work.

For example, when I try calling _getfinalpathname to resolve the device paths 
\\?\MAILSLOT, \\?\PIPE, \\?\UNC, \\?\C:, \\?\PhysicalDrive0, \\?\NUL, 
\\?\CONIN$, and \\?\COM1, I get the following list of leaked handles:

      0x168 File                  \Device\Mailslot
      0x16c File                  \Device\NamedPipe
      0x178 File                  \Device\Mup
      0x17c File                  \Device\HarddiskVolume2
      0x180 File                  \Device\Harddisk0\DR0
      0x18c File                  \Device\Null
      0x194 File                  \Device\ConDrv
      0x198 File                  \Device\Serial0

(The above is from a context manager that checks for leaked handles using 
ctypes to call the PssCaptureSnapshot API, which was introduced in Windows 8.1. 
I think Process Snapshotting is the only Windows API that uses the kernel's 
ability to fork a clone of a process.) 

The reason that GetFinalPathNameByHandle fails in these cases is that the 
information classes it queries are typically only serviced by file systems. 
Other I/O devices (e.g. disk and volume devices) will fail these I/O requests. 
It happens that GetFinalPathNameByHandle starts with an NtQueryObject request 
that succeeds in these cases (it's the source of the above native NT device 
names), but it doesn't stop there. It continues requesting information from the 
device and the mount-point manager until it either has everything or a request 
fails.

Also, in os__getfinalpathname_impl, I notice that it's switching from 
VOLUME_NAME_NT in the first call that's used to get the buffer size to 
VOLUME_NAME_DOS in the second call. It should use VOLUME_NAME_DOS in both 
cases, or better yet, add a keyword-only argument to select a different 
volume-name style (i.e. None, DOS, GUID, or NT).

----------
components: Extension Modules, Windows
messages: 289095
nosy: eryksun, paul.moore, steve.dower, tim.golden, zach.ware
priority: normal
severity: normal
status: open
title: nt._getfinalpathname  handle leak
type: behavior
versions: Python 3.5, Python 3.6, Python 3.7

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue29734>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to