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
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".
This currently causes CreateFile(... CREATE_NEW ...) for non-existing files on FAT32 drives to fail.
Signed-off-by: Joachim Priesner joachim.priesner@web.de --- v2: Simplified and added test program to increase chances of approval (v1 title was: ntdll: Fix CreateFile for non-existing files on FAT file systems)
Test: The following test program will currently succeed when given a non-existing path on a non-FAT32 drive and fail on a FAT32 drive. With this patch, it succeeds on both FAT32 and non-FAT32 drives.
#include <windows.h> int main(int argc, char** argv) { return SUCCEEDED(CreateFile(argv[1], GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL)) ? 0 : 1; }
--- dlls/ntdll/unix/file.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index afb552be098..d12a3ffb119 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 ); } -- 2.28.0