diff --git a/README.md b/README.md index 930c9efd..8d3b3990 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Wine. All those differences are also documented on the Included bug fixes and improvements ----------------------------------- -**Bug fixes and features included in the next upcoming release [12]:** +**Bug fixes and features included in the next upcoming release [13]:** * Add IDragSourceHelper stub interface ([Wine Bug #24699](https://bugs.winehq.org/show_bug.cgi?id=24699)) * Catch invalid memory accesses in imagehlp.CheckSumMappedFile @@ -52,6 +52,7 @@ Included bug fixes and improvements * Only set SFGAO_HASSUBFOLDER when there are really subfolders ([Wine Bug #24851](https://bugs.winehq.org/show_bug.cgi?id=24851)) * Properly implement imagehlp.ImageLoad and ImageUnload * Report correct ObjectName for NamedPipe wineserver objects +* Set EOF on file which has a memory mapping should fail * Use helper function for NtWaitForMultipleObjects and NtWaitForSingleObject ([Wine Bug #39127](https://bugs.winehq.org/show_bug.cgi?id=39127)) diff --git a/debian/changelog b/debian/changelog index 6e2f0216..5c162722 100644 --- a/debian/changelog +++ b/debian/changelog @@ -22,6 +22,8 @@ wine-staging (1.7.50) UNRELEASED; urgency=low NtWaitForSingleObject. * Added patch to block deallocation of thread stack for current thread (fixes Wine Staging Bug #241). + * Added patch to reject setting EOF on memory mapped files (fixes Wine Staging + Bug #471). * Removed patch to move security cookie initialization from memory management to loader (accepted upstream). * Removed patches for stub of D3DCompileFromFile and D3DCompile2 (accepted diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 45b66d7b..aeb84060 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -208,6 +208,7 @@ patch_enable_all () enable_server_ClipCursor="$1" enable_server_CreateProcess_ACLs="$1" enable_server_Delete_On_Close="$1" + enable_server_FileEndOfFileInformation="$1" enable_server_File_Permissions="$1" enable_server_Inherited_ACLs="$1" enable_server_Key_State="$1" @@ -710,6 +711,9 @@ patch_enable () server-Delete_On_Close) enable_server_Delete_On_Close="$2" ;; + server-FileEndOfFileInformation) + enable_server_FileEndOfFileInformation="$2" + ;; server-File_Permissions) enable_server_File_Permissions="$2" ;; @@ -4359,6 +4363,18 @@ if test "$enable_server_Delete_On_Close" -eq 1; then ) >> "$patchlist" fi +# Patchset server-FileEndOfFileInformation +# | +# | Modified files: +# | * dlls/ntdll/file.c, server/fd.c, server/protocol.def +# | +if test "$enable_server_FileEndOfFileInformation" -eq 1; then + patch_apply server-FileEndOfFileInformation/0001-ntdll-Set-EOF-on-file-which-has-a-memory-mapping-sho.patch + ( + echo '+ { "Qian Hong", "ntdll: Set EOF on file which has a memory mapping should fail.", 1 },'; + ) >> "$patchlist" +fi + # Patchset server-Stored_ACLs # | # | This patchset has the following (direct or indirect) dependencies: diff --git a/patches/server-FileEndOfFileInformation/0001-ntdll-Set-EOF-on-file-which-has-a-memory-mapping-sho.patch b/patches/server-FileEndOfFileInformation/0001-ntdll-Set-EOF-on-file-which-has-a-memory-mapping-sho.patch new file mode 100644 index 00000000..a243e034 --- /dev/null +++ b/patches/server-FileEndOfFileInformation/0001-ntdll-Set-EOF-on-file-which-has-a-memory-mapping-sho.patch @@ -0,0 +1,144 @@ +From 3b5ea5ff15907d1d8f1902a08451b0a03eb11dc9 Mon Sep 17 00:00:00 2001 +From: Qian Hong +Date: Fri, 21 Aug 2015 21:58:51 +0800 +Subject: ntdll: Set EOF on file which has a memory mapping should fail. + +--- + dlls/ntdll/file.c | 27 +++++++------------------- + server/fd.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + server/protocol.def | 7 +++++++ + 3 files changed, 69 insertions(+), 20 deletions(-) + +diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c +index be6b591..8c9b076 100644 +--- a/dlls/ntdll/file.c ++++ b/dlls/ntdll/file.c +@@ -2650,30 +2650,17 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, + case FileEndOfFileInformation: + if (len >= sizeof(FILE_END_OF_FILE_INFORMATION)) + { +- struct stat st; + const FILE_END_OF_FILE_INFORMATION *info = ptr; + +- if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ))) +- return io->u.Status; +- +- /* first try normal truncate */ +- if (ftruncate( fd, (off_t)info->EndOfFile.QuadPart ) != -1) break; +- +- /* now check for the need to extend the file */ +- if (fstat( fd, &st ) != -1 && (off_t)info->EndOfFile.QuadPart > st.st_size) ++ SERVER_START_REQ( set_fd_eof_info ) + { +- static const char zero; +- +- /* extend the file one byte beyond the requested size and then truncate it */ +- /* this should work around ftruncate implementations that can't extend files */ +- if (pwrite( fd, &zero, 1, (off_t)info->EndOfFile.QuadPart ) != -1 && +- ftruncate( fd, (off_t)info->EndOfFile.QuadPart ) != -1) break; ++ req->handle = wine_server_obj_handle( handle ); ++ req->eof = info->EndOfFile.QuadPart; ++ io->u.Status = wine_server_call( req ); + } +- io->u.Status = FILE_GetNtStatus(); +- +- if (needs_close) close( fd ); +- } +- else io->u.Status = STATUS_INVALID_PARAMETER_3; ++ SERVER_END_REQ; ++ } else ++ io->u.Status = STATUS_INVALID_PARAMETER_3; + break; + + case FilePipeInformation: +diff --git a/server/fd.c b/server/fd.c +index fef4827..62373d8 100644 +--- a/server/fd.c ++++ b/server/fd.c +@@ -2353,6 +2353,50 @@ failed: + free( name ); + } + ++static void set_fd_eof( struct fd *fd, file_pos_t eof ) ++{ ++ static const char zero; ++ struct stat st; ++ struct list *ptr; ++ ++ if (!fd->inode) ++ { ++ set_error( STATUS_OBJECT_TYPE_MISMATCH ); ++ return; ++ } ++ ++ if (fd->unix_fd == -1) ++ { ++ set_error( fd->no_fd_status ); ++ return; ++ } ++ ++ /* can't set eof of files which are mapped to memory */ ++ LIST_FOR_EACH( ptr, &fd->inode->open ) ++ { ++ struct fd *fd_ptr = LIST_ENTRY( ptr, struct fd, inode_entry ); ++ if (fd_ptr != fd && (fd_ptr->access & FILE_MAPPING_ACCESS)) ++ { ++ set_error( STATUS_USER_MAPPED_FILE ); ++ return; ++ } ++ } ++ ++ /* first try normal truncate */ ++ if (ftruncate( fd->unix_fd, eof ) != -1) return; ++ ++ /* now check for the need to extend the file */ ++ if (fstat( fd->unix_fd, &st ) != -1 && eof > st.st_size) ++ { ++ /* extend the file one byte beyond the requested size and then truncate it */ ++ /* this should work around ftruncate implementations that can't extend files */ ++ if (pwrite( fd->unix_fd, &zero, 1, eof ) != -1 && ++ ftruncate( fd->unix_fd, eof) != -1) return; ++ } ++ ++ file_set_error(); ++} ++ + struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key ) + { + *p_key = fd->comp_key; +@@ -2593,3 +2637,14 @@ DECL_HANDLER(set_fd_name_info) + } + if (root_fd) release_object( root_fd ); + } ++ ++/* set fd eof information */ ++DECL_HANDLER(set_fd_eof_info) ++{ ++ struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 ); ++ if (fd) ++ { ++ set_fd_eof( fd, req->eof ); ++ release_object( fd ); ++ } ++} +diff --git a/server/protocol.def b/server/protocol.def +index c313006..8d197f0 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -3541,6 +3541,13 @@ enum coords_relative + @END + + ++/* set fd eof information */ ++@REQ(set_fd_eof_info) ++ obj_handle_t handle; /* handle to a file or directory */ ++ file_pos_t eof; /* offset of eof of file */ ++@END ++ ++ + /* Retrieve layered info for a window */ + @REQ(get_window_layered_info) + user_handle_t handle; /* handle to the window */ +-- +2.5.0 + diff --git a/patches/server-FileEndOfFileInformation/definition b/patches/server-FileEndOfFileInformation/definition new file mode 100644 index 00000000..72b8b943 --- /dev/null +++ b/patches/server-FileEndOfFileInformation/definition @@ -0,0 +1 @@ +Fixes: Set EOF on file which has a memory mapping should fail