Add the VirtioFsGetFuseModeUpdate() function, for determining whether an EFI_FILE_PROTOCOL.SetInfo() invocation requests an update to the file mode bits.
Cc: Ard Biesheuvel <[email protected]> Cc: Jordan Justen <[email protected]> Cc: Philippe Mathieu-Daudé <[email protected]> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3097 Signed-off-by: Laszlo Ersek <[email protected]> --- OvmfPkg/Include/IndustryStandard/VirtioFs.h | 3 + OvmfPkg/VirtioFsDxe/VirtioFsDxe.h | 8 ++ OvmfPkg/VirtioFsDxe/Helpers.c | 95 ++++++++++++++++++++ 3 files changed, 106 insertions(+) diff --git a/OvmfPkg/Include/IndustryStandard/VirtioFs.h b/OvmfPkg/Include/IndustryStandard/VirtioFs.h index 15fb28f95a28..dee437ec0d39 100644 --- a/OvmfPkg/Include/IndustryStandard/VirtioFs.h +++ b/OvmfPkg/Include/IndustryStandard/VirtioFs.h @@ -90,22 +90,25 @@ typedef struct { // File mode bitmasks. // #define VIRTIO_FS_FUSE_MODE_TYPE_MASK 0170000u #define VIRTIO_FS_FUSE_MODE_TYPE_REG 0100000u #define VIRTIO_FS_FUSE_MODE_TYPE_DIR 0040000u #define VIRTIO_FS_FUSE_MODE_PERM_RWXU 0000700u #define VIRTIO_FS_FUSE_MODE_PERM_RUSR 0000400u #define VIRTIO_FS_FUSE_MODE_PERM_WUSR 0000200u +#define VIRTIO_FS_FUSE_MODE_PERM_XUSR 0000100u #define VIRTIO_FS_FUSE_MODE_PERM_RWXG 0000070u #define VIRTIO_FS_FUSE_MODE_PERM_RGRP 0000040u #define VIRTIO_FS_FUSE_MODE_PERM_WGRP 0000020u +#define VIRTIO_FS_FUSE_MODE_PERM_XGRP 0000010u #define VIRTIO_FS_FUSE_MODE_PERM_RWXO 0000007u #define VIRTIO_FS_FUSE_MODE_PERM_ROTH 0000004u #define VIRTIO_FS_FUSE_MODE_PERM_WOTH 0000002u +#define VIRTIO_FS_FUSE_MODE_PERM_XOTH 0000001u // // Flags for VirtioFsFuseOpSetAttr, in the VIRTIO_FS_FUSE_SETATTR_REQUEST.Valid // field. // #define VIRTIO_FS_FUSE_SETATTR_REQ_F_MODE BIT0 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_SIZE BIT3 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_ATIME BIT4 diff --git a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h index 4331cabbd40e..3c3eb1ac9338 100644 --- a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h +++ b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h @@ -295,16 +295,24 @@ VirtioFsGetFuseTimeUpdates ( IN EFI_FILE_INFO *Info, IN EFI_FILE_INFO *NewInfo, OUT BOOLEAN *UpdateAtime, OUT BOOLEAN *UpdateMtime, OUT UINT64 *Atime, OUT UINT64 *Mtime ); +EFI_STATUS +VirtioFsGetFuseModeUpdate ( + IN EFI_FILE_INFO *Info, + IN EFI_FILE_INFO *NewInfo, + OUT BOOLEAN *Update, + OUT UINT32 *Mode + ); + // // Wrapper functions for FUSE commands (primitives). // EFI_STATUS VirtioFsFuseLookup ( IN OUT VIRTIO_FS *VirtioFs, IN UINT64 DirNodeId, diff --git a/OvmfPkg/VirtioFsDxe/Helpers.c b/OvmfPkg/VirtioFsDxe/Helpers.c index c85c7400f2be..b669842a23bd 100644 --- a/OvmfPkg/VirtioFsDxe/Helpers.c +++ b/OvmfPkg/VirtioFsDxe/Helpers.c @@ -2314,8 +2314,103 @@ VirtioFsGetFuseTimeUpdates ( } if (Change[2]) { *UpdateMtime = TRUE; *Mtime = Seconds[2]; } return EFI_SUCCESS; } + +/** + Given an EFI_FILE_INFO object received in an EFI_FILE_PROTOCOL.SetInfo() + call, determine whether updating the file mode bits of the file is necessary, + relative to an EFI_FILE_INFO object describing the current state of the file. + + @param[in] Info The EFI_FILE_INFO describing the current state of the + file. The caller is responsible for populating Info on + input with VirtioFsFuseAttrToEfiFileInfo(), from the + current FUSE attributes of the file. The Info->Size and + Info->FileName members are ignored. + + @param[in] NewInfo The EFI_FILE_INFO object received in the + EFI_FILE_PROTOCOL.SetInfo() call. + + @param[out] Update Set to TRUE on output if the file mode bits need to be + updated. Set to FALSE otherwise. + + @param[out] Mode If Update is set to TRUE, then Mode provides the file + mode bits to set. Otherwise, Mode is not written to. + + @retval EFI_SUCCESS Output parameters have been set successfully. + + @retval EFI_ACCESS_DENIED NewInfo requests toggling an unknown bit in the + Attribute bitmask. + + @retval EFI_ACCESS_DENIED NewInfo requests toggling EFI_FILE_DIRECTORY in + the Attribute bitmask. +**/ +EFI_STATUS +VirtioFsGetFuseModeUpdate ( + IN EFI_FILE_INFO *Info, + IN EFI_FILE_INFO *NewInfo, + OUT BOOLEAN *Update, + OUT UINT32 *Mode + ) +{ + UINT64 Toggle; + BOOLEAN IsDirectory; + BOOLEAN IsWriteable; + BOOLEAN WillBeWriteable; + + Toggle = Info->Attribute ^ NewInfo->Attribute; + if ((Toggle & ~EFI_FILE_VALID_ATTR) != 0) { + // + // Unknown attribute requested. + // + return EFI_ACCESS_DENIED; + } + if ((Toggle & EFI_FILE_DIRECTORY) != 0) { + // + // EFI_FILE_DIRECTORY cannot be toggled. + // + return EFI_ACCESS_DENIED; + } + + IsDirectory = (BOOLEAN)((Info->Attribute & EFI_FILE_DIRECTORY) != 0); + IsWriteable = (BOOLEAN)((Info->Attribute & EFI_FILE_READ_ONLY) == 0); + WillBeWriteable = (BOOLEAN)((NewInfo->Attribute & EFI_FILE_READ_ONLY) == 0); + + if (IsWriteable == WillBeWriteable) { + *Update = FALSE; + return EFI_SUCCESS; + } + + if (IsDirectory) { + if (WillBeWriteable) { + *Mode = (VIRTIO_FS_FUSE_MODE_PERM_RWXU | + VIRTIO_FS_FUSE_MODE_PERM_RWXG | + VIRTIO_FS_FUSE_MODE_PERM_RWXO); + } else { + *Mode = (VIRTIO_FS_FUSE_MODE_PERM_RUSR | + VIRTIO_FS_FUSE_MODE_PERM_XUSR | + VIRTIO_FS_FUSE_MODE_PERM_RGRP | + VIRTIO_FS_FUSE_MODE_PERM_XGRP | + VIRTIO_FS_FUSE_MODE_PERM_ROTH | + VIRTIO_FS_FUSE_MODE_PERM_XOTH); + } + } else { + if (WillBeWriteable) { + *Mode = (VIRTIO_FS_FUSE_MODE_PERM_RUSR | + VIRTIO_FS_FUSE_MODE_PERM_WUSR | + VIRTIO_FS_FUSE_MODE_PERM_RGRP | + VIRTIO_FS_FUSE_MODE_PERM_WGRP | + VIRTIO_FS_FUSE_MODE_PERM_ROTH | + VIRTIO_FS_FUSE_MODE_PERM_WOTH); + } else { + *Mode = (VIRTIO_FS_FUSE_MODE_PERM_RUSR | + VIRTIO_FS_FUSE_MODE_PERM_RGRP | + VIRTIO_FS_FUSE_MODE_PERM_ROTH); + } + } + *Update = TRUE; + return EFI_SUCCESS; +} -- 2.19.1.3.g30247aa5d201 _______________________________________________ Virtio-fs mailing list [email protected] https://www.redhat.com/mailman/listinfo/virtio-fs
