r3133: - more consistent error checking in rename and setfileinfo
authorAndrew Tridgell <tridge@samba.org>
Fri, 22 Oct 2004 06:55:18 +0000 (06:55 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:02:25 +0000 (13:02 -0500)
- add paranoid checking of device/inode change during open to detect race conditions
(This used to be commit 043361fed487ed494fa497ffde1007b3f3bc0c29)

source4/ntvfs/posix/pvfs_rename.c
source4/ntvfs/posix/pvfs_resolve.c
source4/ntvfs/posix/pvfs_setfileinfo.c

index 51393c949924ebdbfa6a9e6967af82983c205559..80b6a510b01e00c47342482c23fb3da13d28de08 100644 (file)
@@ -62,7 +62,7 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs,
                return NT_STATUS_OBJECT_NAME_COLLISION;
        }
 
-       if (rename(name1->full_name, name2->full_name) != 0) {
+       if (rename(name1->full_name, name2->full_name) == -1) {
                return pvfs_map_errno(pvfs, errno);
        }
        
index 97068c3d0393e1704495bf452185869764b4bfea..5b86cd3a7311602ac1c385b3887e7caf60520943 100644 (file)
@@ -364,10 +364,29 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
 NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd,
                              struct pvfs_filename *name)
 {
+       dev_t device;
+       ino_t inode;
+
+       if (name->exists) {
+               device = name->st.st_dev;
+               inode = name->st.st_ino;
+       }
+
        if (fstat(fd, &name->st) == -1) {
                return NT_STATUS_INVALID_HANDLE;
        }
 
+       if (name->exists &&
+           (device != name->st.st_dev || inode != name->st.st_ino)) {
+               /* the file we are looking at has changed! this could
+                be someone trying to exploit a race
+                condition. Certainly we don't want to continue
+                operating on this file */
+               DEBUG(0,("pvfs: WARNING: file '%s' changed during resole - failing\n",
+                        name->full_name));
+               return NT_STATUS_UNEXPECTED_IO_ERROR;
+       }
+
        name->exists = True;
        
        return pvfs_fill_dos_info(pvfs, name);
index f1d5d14089cc523f4c66bf7323505866b4942ba2..8892c92c3ce5c1b9126c2c7ed2be59df5d000401 100644 (file)
@@ -43,7 +43,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
        case RAW_SFILEINFO_END_OF_FILE_INFO:
        case RAW_SFILEINFO_END_OF_FILE_INFORMATION:
                if (ftruncate(f->fd,
-                             info->end_of_file_info.in.size) != 0) {
+                             info->end_of_file_info.in.size) == -1) {
                        return pvfs_map_errno(pvfs, errno);
                }
                break;