From 70299e6c3def0b84520232c02b9071c9cbf8a851 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 15 Apr 2014 12:19:21 -0400 Subject: [PATCH] Windows: Fix AFSSetBasicInfo attribute processing The prior behavior of AFSSetBasicInfo() was to let the caller set whatever it wanted as the new file attributes regardless of the attributes that are supported by AFS. In doing so, reparse point and directory attributes could be cleared, and other values could be set even though they would be lost as soon as the DirectoryCB object was garbage collected. New behavior: 1. return STATUS_INVALID_PARAMETER if reparse point attribute would be altered 2. return STATUS_INVALID_PARAMETER if directory attribute would be altered. 3. successfully modify readonly attribute 4. ignore all other attribute values Change-Id: Ic678960101ef99cdad0c0e84b21c9d65c6831ca8 Reviewed-on: http://gerrit.openafs.org/11073 Tested-by: BuildBot Reviewed-by: Rod Widdowson Reviewed-by: Jeffrey Altman --- src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp | 102 ++++++++++++++++++++---- src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h | 3 +- 2 files changed, 87 insertions(+), 18 deletions(-) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp index fd7508a..43e895b 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp @@ -647,10 +647,9 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject, case FileBasicInformation: { - bUpdateFileInfo = TRUE; - ntStatus = AFSSetBasicInfo( Irp, - pCcb->DirectoryCB); + pCcb->DirectoryCB, + &bUpdateFileInfo); break; } @@ -1912,7 +1911,8 @@ AFSQueryPhysicalNameInfo( IN PIRP Irp, NTSTATUS AFSSetBasicInfo( IN PIRP Irp, - IN AFSDirectoryCB *DirectoryCB) + IN AFSDirectoryCB *DirectoryCB, + OUT BOOLEAN *bUpdateFileInfo) { NTSTATUS ntStatus = STATUS_SUCCESS; PFILE_BASIC_INFORMATION pBuffer; @@ -1932,26 +1932,92 @@ AFSSetBasicInfo( IN PIRP Irp, if( pBuffer->FileAttributes != (ULONGLONG)0) { - if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB && - BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)) - { + // + // Make sure that the reparse point attribute is not modified. + // Fail if the RP attribute is requested but it is not + // already a RP. Otherwise, ignore it. + // - try_return( ntStatus = STATUS_INVALID_PARAMETER); - } + if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, + FILE_ATTRIBUTE_REPARSE_POINT) && + BooleanFlagOn( pBuffer->FileAttributes, + FILE_ATTRIBUTE_REPARSE_POINT)) + { - if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB) - { + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } - pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY; - } + // + // Make sure that the directory attribute is not modified. + // Fail if the D attribute is requested but it is not + // already a directory. Otherwise, ignore it. + // + + if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, + FILE_ATTRIBUTE_DIRECTORY) && + BooleanFlagOn( pBuffer->FileAttributes, + FILE_ATTRIBUTE_DIRECTORY)) + { - pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes; + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } + + // + // Save the original value + // + + pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes; + + if( BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_READONLY)) + { - DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes; + // + // Set the readonly flag. + // - ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES; + if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, + FILE_ATTRIBUTE_READONLY)) + { + + if ( DirectoryCB->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL) + { - SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED); + DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_READONLY; + } + else + { + + DirectoryCB->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_READONLY; + } + + ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES; + + SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED); + } + } + else + { + // + // Reset the readonly flag. + // + + if ( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, + FILE_ATTRIBUTE_READONLY)) + { + + DirectoryCB->ObjectInformation->FileAttributes &= ~FILE_ATTRIBUTE_READONLY; + + if ( DirectoryCB->ObjectInformation->FileAttributes == 0) + { + + DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_NORMAL; + } + + ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES; + + SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED); + } + } } pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1; @@ -2017,6 +2083,8 @@ AFSSetBasicInfo( IN PIRP Irp, if( ulNotifyFilter > 0) { + *bUpdateFileInfo = TRUE; + if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID)) { diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h index 34bee1e..0725527 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h @@ -837,7 +837,8 @@ AFSSetFileInfo( IN PDEVICE_OBJECT DeviceObject, NTSTATUS AFSSetBasicInfo( IN PIRP Irp, - IN AFSDirectoryCB *DirectoryCB); + IN AFSDirectoryCB *DirectoryCB, + OUT BOOLEAN *bUpdateFileInfo); NTSTATUS AFSSetDispositionInfo( IN PIRP Irp, -- 1.9.4