Alexandre Julliard : server: Improve parameter checks when opening a directory.

Alexandre Julliard julliard at winehq.org
Tue Dec 8 11:10:35 CST 2009


Module: wine
Branch: master
Commit: 151446a2a60e4d5165873d3c183f926dd0edbd98
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=151446a2a60e4d5165873d3c183f926dd0edbd98

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Dec  8 12:18:44 2009 +0100

server: Improve parameter checks when opening a directory.

---

 server/fd.c |   24 +++++++++++++++++++-----
 1 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/server/fd.c b/server/fd.c
index 8f35812..e26ce04 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1732,7 +1732,8 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
     int root_fd = -1;
     int rw_mode;
 
-    if ((options & FILE_DELETE_ON_CLOSE) && !(access & DELETE))
+    if (((options & FILE_DELETE_ON_CLOSE) && !(access & DELETE)) ||
+        ((options & FILE_DIRECTORY_FILE) && (flags & O_TRUNC)))
     {
         set_error( STATUS_INVALID_PARAMETER );
         return NULL;
@@ -1785,9 +1786,13 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
     if ((fd->unix_fd = open( name, rw_mode | (flags & ~O_TRUNC), *mode )) == -1)
     {
         /* if we tried to open a directory for write access, retry read-only */
-        if (errno != EISDIR ||
-            !(access & FILE_UNIX_WRITE_ACCESS) ||
-            (fd->unix_fd = open( name, O_RDONLY | (flags & ~(O_TRUNC | O_CREAT | O_EXCL)), *mode )) == -1)
+        if (errno == EISDIR)
+        {
+            if ((access & FILE_UNIX_WRITE_ACCESS) || (flags & O_CREAT))
+                fd->unix_fd = open( name, O_RDONLY | (flags & ~(O_TRUNC | O_CREAT | O_EXCL)), *mode );
+        }
+
+        if (fd->unix_fd == -1)
         {
             file_set_error();
             goto error;
@@ -1836,7 +1841,16 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
             return NULL;
         }
         strcpy( closed_fd->unlink, unlink_name );
-        if (flags & O_TRUNC) ftruncate( fd->unix_fd, 0 );
+        if (flags & O_TRUNC)
+        {
+            if (S_ISDIR(st.st_mode))
+            {
+                release_object( fd );
+                set_error( STATUS_OBJECT_NAME_COLLISION );
+                return NULL;
+            }
+            ftruncate( fd->unix_fd, 0 );
+        }
     }
     else  /* special file */
     {




More information about the wine-cvs mailing list