From: Jeffrey Altman Date: Fri, 4 Apr 2014 20:42:36 +0000 (-0400) Subject: Windows: Deny writes/truncation to files w RO attr X-Git-Tag: openafs-stable-1_8_0pre1~723 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=dd8d2aa871fc5841c281d1292c39ffb8edf1ebd1 Windows: Deny writes/truncation to files w RO attr 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 Reviewed-by: Jeffrey Altman --- diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp index 4254a7e..5055482 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp @@ -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 // diff --git a/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp b/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp index eb3adaf..1376d06 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp @@ -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); } // diff --git a/src/WINNT/afsrdr/user/RDRFunction.c b/src/WINNT/afsrdr/user/RDRFunction.c index 01a334e..e1193d2 100644 --- a/src/WINNT/afsrdr/user/RDRFunction.c +++ b/src/WINNT/afsrdr/user/RDRFunction.c @@ -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,