Windows: Deny writes/truncation to files w RO attr
authorJeffrey Altman <jaltman@your-file-system.com>
Fri, 4 Apr 2014 20:42:36 +0000 (16:42 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Thu, 17 Apr 2014 04:10:14 +0000 (21:10 -0700)
If the readonly file attribute is set on a file, refuse to process
writes, truncations or overwrites.   The afsd_service will do so
and this can lead to data corruption.

At the same time, writes from the redirector to afsd_service must
not be denied because of the readonly attribute.  That check was
performed during the CreateFile.   Otherwise, a new file can be
created with the readonly attribute and then not be writable.

Change-Id: I921a11eb8c1a3e642d60c23fc905b3febc0f0761
Reviewed-on: http://gerrit.openafs.org/10985
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp
src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp
src/WINNT/afsrdr/user/RDRFunction.c

index 4254a7e..5055482 100644 (file)
@@ -3453,6 +3453,18 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
             try_return( ntStatus);
         }
 
+       if ( BooleanFlagOn( pObjectInfo->FileAttributes, FILE_ATTRIBUTE_READONLY))
+       {
+
+           AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                         AFS_TRACE_LEVEL_WARNING,
+                         "AFSProcessOverwriteSupersede Request failed on %wZ due to read only file attribute\n",
+                         Irp,
+                         &DirectoryCB->NameInformation.FileName));
+
+           try_return( ntStatus = STATUS_ACCESS_DENIED);
+       }
+
         //
         // Be sure we have an Fcb for the object block
         //
index eb3adaf..1376d06 100644 (file)
@@ -260,7 +260,7 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
                           "AFSCommonWrite (%p) Request failed due to read only volume\n",
                           Irp));
 
-            try_return( ntStatus = STATUS_ACCESS_DENIED);
+            try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
         }
 
         //
index 01a334e..e1193d2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008 Secure Endpoints, Inc.
- * Copyright (c) 2009-2013 Your File System, Inc.
+ * Copyright (c) 2009-2014 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -6860,7 +6860,14 @@ RDR_WriteFile( IN cm_user_t     *userp,
 
     /* Ensure that the caller can access this file */
     lock_ObtainWrite(&scp->rw);
-    code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_WRITE,
+    /*
+     * Request PRSFS_WRITE | PRSFS_LOCK in order to bypass the unix mode
+     * check in cm_HaveAccessRights().   By the time RDR_WriteFile is called
+     * it is already too late to deny the write due to the readonly attribute.
+     * The Windows cache may have already accepted the data.  Only if the
+     * user does not have real write permission should the write be denied.
+     */
+    code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_WRITE | PRSFS_LOCK,
                       CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
     if (code == CM_ERROR_NOACCESS && scp->creator == userp) {
         code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_INSERT,