Two small bugs in find_file_in_dir/lookup_unix_name cause creation of new files on FAT file systems to fail.
If the VFAT_IOCTL_READDIR_BOTH logic in find_file_in_dir does not yield any result, the NUL terminator of "unix_name" must be restored. Else the following opendir() call will read past the end of "unix_name".
Since at the beginning of find_file_in_dir, the full file name was written to "unix_name" for the stat() shortcut logic, there is no out-of-bounds read and the opendir() call will reliably fail. But commit 688799b1f7b2750b938f8da771480d2c16d1ae1d changed the return code for this case from STATUS_OBJECT_PATH_NOT_FOUND to STATUS_OBJECT_NAME_NOT_FOUND, so lookup_unix_name needs to check for that as well.
Signed-off-by: Joachim Priesner joachim.priesner@web.de --- dlls/ntdll/unix/file.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index afb552be098..a443ff61282 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -2550,6 +2550,8 @@ static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, i goto not_found; } } + /* if that did not work, restore previous state of unix_name */ + unix_name[pos - 1] = 0; } close( fd ); } @@ -3133,6 +3135,9 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer if (status == STATUS_OBJECT_PATH_NOT_FOUND) { status = STATUS_OBJECT_NAME_NOT_FOUND; + } + if (status == STATUS_OBJECT_NAME_NOT_FOUND) + { if (disposition != FILE_OPEN && disposition != FILE_OVERWRITE) { ret = ntdll_wcstoumbs( name, end - name, unix_name + pos + 1, MAX_DIR_ENTRY_LEN + 1, TRUE ); -- 2.28.0