Skip to content

Commit 32efcd1

Browse files
authored
bpo-33016: Fix potential use of uninitialized memory in nt._getfinalpathname (GH-6032)
1 parent 2f3ba27 commit 32efcd1

File tree

2 files changed

+33
-22
lines changed

2 files changed

+33
-22
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix potential use of uninitialized memory in nt._getfinalpathname

‎Modules/posixmodule.c‎

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,6 @@ extern int lstat(const char *, struct stat *);
306306
#ifdef HAVE_PROCESS_H
307307
#include <process.h>
308308
#endif
309-
#ifndef VOLUME_NAME_DOS
310-
#define VOLUME_NAME_DOS 0x0
311-
#endif
312-
#ifndef VOLUME_NAME_NT
313-
#define VOLUME_NAME_NT 0x2
314-
#endif
315309
#ifndef IO_REPARSE_TAG_SYMLINK
316310
#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
317311
#endif
@@ -3672,8 +3666,8 @@ os__getfinalpathname_impl(PyObject *module, PyObject *path)
36723666
/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
36733667
{
36743668
HANDLE hFile;
3675-
int buf_size;
3676-
wchar_t *target_path;
3669+
wchar_t buf[MAXPATHLEN], *target_path = buf;
3670+
int buf_size = Py_ARRAY_LENGTH(buf);
36773671
int result_length;
36783672
PyObject *result;
36793673
const wchar_t *path_wchar;
@@ -3682,6 +3676,7 @@ os__getfinalpathname_impl(PyObject *module, PyObject *path)
36823676
if (path_wchar == NULL)
36833677
return NULL;
36843678

3679+
Py_BEGIN_ALLOW_THREADS
36853680
hFile = CreateFileW(
36863681
path_wchar,
36873682
0, /* desired access */
@@ -3691,32 +3686,47 @@ os__getfinalpathname_impl(PyObject *module, PyObject *path)
36913686
/* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
36923687
FILE_FLAG_BACKUP_SEMANTICS,
36933688
NULL);
3689+
Py_END_ALLOW_THREADS
36943690

36953691
if(hFile == INVALID_HANDLE_VALUE)
36963692
return win32_error_object("CreateFileW", path);
36973693

36983694
/* We have a good handle to the target, use it to determine the
36993695
target path name. */
3700-
buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
3696+
while (1) {
3697+
Py_BEGIN_ALLOW_THREADS
3698+
result_length = GetFinalPathNameByHandleW(hFile, target_path,
3699+
buf_size, VOLUME_NAME_DOS);
3700+
Py_END_ALLOW_THREADS
37013701

3702-
if(!buf_size)
3703-
return win32_error_object("GetFinalPathNameByHandle", path);
3702+
if (!result_length) {
3703+
result = win32_error_object("GetFinalPathNameByHandleW", path);
3704+
goto cleanup;
3705+
}
37043706

3705-
target_path = PyMem_New(wchar_t, buf_size+1);
3706-
if(!target_path)
3707-
return PyErr_NoMemory();
3707+
if (result_length < buf_size) {
3708+
break;
3709+
}
37083710

3709-
result_length = GetFinalPathNameByHandleW(hFile, target_path,
3710-
buf_size, VOLUME_NAME_DOS);
3711-
if(!result_length)
3712-
return win32_error_object("GetFinalPathNamyByHandle", path);
3711+
wchar_t *tmp;
3712+
tmp = PyMem_Realloc(target_path != buf ? target_path : NULL,
3713+
result_length * sizeof(*tmp));
3714+
if (!tmp) {
3715+
result = PyErr_NoMemory();
3716+
goto cleanup;
3717+
}
37133718

3714-
if(!CloseHandle(hFile))
3715-
return win32_error_object("CloseHandle", path);
3719+
buf_size = result_length;
3720+
target_path = tmp;
3721+
}
37163722

3717-
target_path[result_length] = 0;
37183723
result = PyUnicode_FromWideChar(target_path, result_length);
3719-
PyMem_Free(target_path);
3724+
3725+
cleanup:
3726+
if (target_path != buf) {
3727+
PyMem_Free(target_path);
3728+
}
3729+
CloseHandle(hFile);
37203730
return result;
37213731
}
37223732

0 commit comments

Comments
 (0)