From 13a506d4f57edbafbdcc946e270b9d9664d454ce Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Wed, 16 Dec 2020 22:11:24 +0100 Subject: OvmfPkg/VirtioFsDxe: add helper for determining file mode bits update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the VirtioFsGetFuseModeUpdate() function, for determining whether an EFI_FILE_PROTOCOL.SetInfo() invocation requests an update to the file mode bits. Cc: Ard Biesheuvel Cc: Jordan Justen Cc: Philippe Mathieu-Daudé Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3097 Signed-off-by: Laszlo Ersek Message-Id: <20201216211125.19496-48-lersek@redhat.com> Acked-by: Ard Biesheuvel --- OvmfPkg/VirtioFsDxe/Helpers.c | 95 +++++++++++++++++++++++++++++++++++++++ OvmfPkg/VirtioFsDxe/VirtioFsDxe.h | 8 ++++ 2 files changed, 103 insertions(+) (limited to 'OvmfPkg/VirtioFsDxe') diff --git a/OvmfPkg/VirtioFsDxe/Helpers.c b/OvmfPkg/VirtioFsDxe/Helpers.c index c56c60640a..443bbdc616 100644 --- a/OvmfPkg/VirtioFsDxe/Helpers.c +++ b/OvmfPkg/VirtioFsDxe/Helpers.c @@ -2319,3 +2319,98 @@ VirtioFsGetFuseTimeUpdates ( 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; +} diff --git a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h index 4331cabbd4..3c3eb1ac93 100644 --- a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h +++ b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h @@ -300,6 +300,14 @@ VirtioFsGetFuseTimeUpdates ( 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). // -- cgit v1.2.3