OvmfPkg/VirtioFsDxe: add helper for determining file mode bits update

Add the VirtioFsGetFuseModeUpdate() function, for determining whether an
EFI_FILE_PROTOCOL.SetInfo() invocation requests an update to the file mode
bits.

Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3097
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20201216211125.19496-48-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
This commit is contained in:
Laszlo Ersek 2020-12-16 22:11:24 +01:00 committed by mergify[bot]
parent 3cbd54b92f
commit 13a506d4f5
3 changed files with 106 additions and 0 deletions

View File

@ -95,12 +95,15 @@ typedef struct {
#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

View File

@ -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;
}

View File

@ -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).
//