2020-12-16 22:10:38 +01:00
|
|
|
## @file
|
|
|
|
# Provide EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instances on virtio-fs devices.
|
|
|
|
#
|
|
|
|
# Copyright (C) 2020, Red Hat, Inc.
|
|
|
|
#
|
|
|
|
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
#
|
|
|
|
#
|
|
|
|
# Permission Model of this driver:
|
|
|
|
#
|
|
|
|
# Regardless of the UID and GID values this driver send in the FUSE request
|
|
|
|
# header, the daemon (that is, the Virtio Filesystem device) always acts with
|
|
|
|
# root privileges on the host side. The only time the daemon considers said UID
|
|
|
|
# and GID fields is when creating a new file or directory. Thus, the guest
|
|
|
|
# driver cannot rely on the host for enforcing any file mode permissions,
|
|
|
|
# regardless of the "personality" that the guest driver poses as, because
|
|
|
|
# "root" on the host side ignores all file mode bits.
|
|
|
|
#
|
|
|
|
# Therefore the guest driver has to do its own permission checking, and use the
|
|
|
|
# host-side file mode bits only as a kind of "metadata storage" or "reminder"
|
|
|
|
# -- hopefully in a way that makes some sense on the host side too.
|
|
|
|
#
|
|
|
|
# The complete mapping between the EFI_FILE_PROTOCOL and the host-side file
|
|
|
|
# mode bits is described below.
|
|
|
|
#
|
|
|
|
# - The guest driver poses as UID 0, GID 0, PID 1.
|
|
|
|
#
|
|
|
|
# - If and only if all "w" bits are missing from a file on the host side, then
|
|
|
|
# the file or directory is reported as EFI_FILE_READ_ONLY in the guest. When
|
|
|
|
# setting EFI_FILE_READ_ONLY in the guest, all "w" bits (0222) are cleared on
|
|
|
|
# the host; when clearing EFI_FILE_READ_ONLY in the guest, all "w" bits are
|
|
|
|
# set on the host. Viewed from the host side, this sort of reflects that an
|
|
|
|
# EFI_FILE_READ_ONLY file should not be written by anyone.
|
|
|
|
#
|
|
|
|
# - The attributes EFI_FILE_HIDDEN, EFI_FILE_SYSTEM, EFI_FILE_RESERVED, and
|
|
|
|
# EFI_FILE_ARCHIVE are never reported in the guest, and they are silently
|
|
|
|
# ignored when a SetInfo() call or a file-creating Open() call requests them.
|
|
|
|
#
|
|
|
|
# - On the host, files are created with 0666 file mode bits, directories are
|
|
|
|
# created with 0777 file mode bits.
|
|
|
|
#
|
|
|
|
# - In the guest, the EFI_FILE_READ_ONLY attribute only controls the permitted
|
|
|
|
# open mode. In particular, on directories, the EFI_FILE_READ_ONLY attribute
|
|
|
|
# does not prevent the creation or deletion of entries inside the directory;
|
|
|
|
# EFI_FILE_READ_ONLY only prevents the renaming, deleting, flushing (syncing)
|
|
|
|
# and touching of the directory itself (with "touching" meaning updating the
|
|
|
|
# timestamps). The fact that EFI_FILE_READ_ONLY being set on a directory is
|
|
|
|
# irrelevant in the guest with regard to entry creation/deletion, is
|
|
|
|
# well-mirrored by the fact that virtiofsd -- which runs as root, regardless
|
|
|
|
# of guest driver personality -- ignores the absence of "w" permissions on a
|
|
|
|
# host-side directory, when creating or removing entries in it.
|
|
|
|
#
|
|
|
|
# - When an EFI_FILE_PROTOCOL is opened read-only, then the Delete(), Write()
|
|
|
|
# and Flush() member functions are disabled for it. Additionally, SetInfo()
|
|
|
|
# is restricted to flipping the EFI_FILE_READ_ONLY bit (which takes effect at
|
|
|
|
# the next Open()).
|
|
|
|
#
|
|
|
|
# - As a consequence of the above, for deleting a directory, it must be
|
|
|
|
# presented in the guest as openable for writing.
|
|
|
|
#
|
|
|
|
# - We diverge from the UEFI spec, and permit Flush() on a directory that has
|
|
|
|
# been opened read-write; otherwise the only way to invoke FUSE_FSYNCDIR on a
|
|
|
|
# directory would be to Close() it.
|
|
|
|
#
|
|
|
|
# - OpenVolume() opens the root directory for read-only access. The Open()
|
|
|
|
# member function may open it for read-write access. While the root directory
|
|
|
|
# cannot be renamed or deleted, opening it for read-write access is useful
|
|
|
|
# for calling Flush(), according to the previous paragraph, or for updating
|
|
|
|
# the root directory's timestamps with SetInfo().
|
|
|
|
##
|
|
|
|
|
|
|
|
[Defines]
|
|
|
|
INF_VERSION = 1.29
|
|
|
|
BASE_NAME = VirtioFsDxe
|
|
|
|
FILE_GUID = 7BD9DDF7-8B83-488E-AEC9-24C78610289C
|
|
|
|
MODULE_TYPE = UEFI_DRIVER
|
|
|
|
ENTRY_POINT = VirtioFsEntryPoint
|
|
|
|
|
|
|
|
[Packages]
|
2020-12-16 22:10:58 +01:00
|
|
|
EmbeddedPkg/EmbeddedPkg.dec
|
2020-12-16 22:10:38 +01:00
|
|
|
MdePkg/MdePkg.dec
|
OvmfPkg/VirtioFsDxe: DriverBinding: open VirtioDevice, install SimpleFs
Complete the Supported, Start, and Stop member functions of
EFI_DRIVER_BINDING_PROTOCOL sufficiently for exercising the UEFI driver
model:
- bind virtio-fs devices,
- produce placeholder EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instances on them.
On the "TO_START" (= Virtio) side, the VirtioFsBindingSupported() function
verifies the Virtio subsystem ID for the virtio-fs device (decimal 26 --
see
<https://github.com/oasis-tcs/virtio-spec/blob/87fa6b5d8155/virtio-fs.tex>).
Beyond that, no actual Virtio setup is performed for now. Those bits are
going to be implemented later in this series.
On the "BY_START" (= UEFI filesystem) side, the VirtioFsOpenVolume()
function -- which is the sole EFI_SIMPLE_FILE_SYSTEM_PROTOCOL member
function -- is a stub; it always returns EFI_NO_MEDIA, for now.
The "CONNECT", "DISCONNECT", and "MAP -R" UEFI Shell commands can be used
to test this patch.
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-4-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
2020-12-16 22:10:40 +01:00
|
|
|
OvmfPkg/OvmfPkg.dec
|
2020-12-16 22:10:38 +01:00
|
|
|
|
|
|
|
[Sources]
|
|
|
|
DriverBinding.c
|
2020-12-16 22:10:51 +01:00
|
|
|
FuseFlush.c
|
2020-12-16 22:10:49 +01:00
|
|
|
FuseForget.c
|
2020-12-16 22:10:50 +01:00
|
|
|
FuseFsync.c
|
2020-12-16 22:11:02 +01:00
|
|
|
FuseGetAttr.c
|
2020-12-16 22:10:45 +01:00
|
|
|
FuseInit.c
|
2020-12-16 22:10:59 +01:00
|
|
|
FuseLookup.c
|
2020-12-16 22:10:56 +01:00
|
|
|
FuseMkDir.c
|
2020-12-16 22:10:55 +01:00
|
|
|
FuseOpen.c
|
2020-12-16 22:10:46 +01:00
|
|
|
FuseOpenDir.c
|
2020-12-16 22:10:57 +01:00
|
|
|
FuseOpenOrCreate.c
|
2020-12-16 22:11:09 +01:00
|
|
|
FuseRead.c
|
2020-12-16 22:10:47 +01:00
|
|
|
FuseRelease.c
|
2020-12-16 22:11:18 +01:00
|
|
|
FuseRename.c
|
2020-12-16 22:11:21 +01:00
|
|
|
FuseSetAttr.c
|
2020-12-16 22:11:05 +01:00
|
|
|
FuseStatFs.c
|
2020-12-16 22:11:01 +01:00
|
|
|
FuseUnlink.c
|
2020-12-16 22:11:15 +01:00
|
|
|
FuseWrite.c
|
2020-12-16 22:10:41 +01:00
|
|
|
Helpers.c
|
OvmfPkg/VirtioFsDxe: implement EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume()
With the help of the VirtioFsFuseOpenDir() and
VirtioFsFuseReleaseFileOrDir() functions introduced previously, we can now
open and close the root directory. So let's implement
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume().
OpenVolume() creates a new EFI_FILE_PROTOCOL object -- a reference to the
root directory of the filesystem. Thus, we have to start tracking
references to EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, lest we unbind the
virtio-fs device while files are open.
There are two methods that release an EFI_FILE_PROTOCOL object: the
Close() and the Delete() member functions. In particular, they are not
allowed to fail with regard to resource management -- they must release
resources unconditionally. Thus, for rolling back the resource accounting
that we do in EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume(), we have to
implement the first versions of EFI_FILE_PROTOCOL.Close() and
EFI_FILE_PROTOCOL.Delete() in this patch as well.
With this patch applied, the UEFI shell can enter the root directory of
the Virtio Filesystem (such as with the "FS3:" shell command), and the
"DIR" shell command exercises FUSE_OPENDIR and FUSE_RELEASEDIR, according
to the virtiofsd log. The "DIR" command reports the root directory as if
it were empty; probably because at this time, we only allow the shell to
open and to close the root directory, but not to read it.
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-12-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
2020-12-16 22:10:48 +01:00
|
|
|
SimpleFsClose.c
|
|
|
|
SimpleFsDelete.c
|
|
|
|
SimpleFsFlush.c
|
|
|
|
SimpleFsGetInfo.c
|
|
|
|
SimpleFsGetPosition.c
|
|
|
|
SimpleFsOpen.c
|
OvmfPkg/VirtioFsDxe: DriverBinding: open VirtioDevice, install SimpleFs
Complete the Supported, Start, and Stop member functions of
EFI_DRIVER_BINDING_PROTOCOL sufficiently for exercising the UEFI driver
model:
- bind virtio-fs devices,
- produce placeholder EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instances on them.
On the "TO_START" (= Virtio) side, the VirtioFsBindingSupported() function
verifies the Virtio subsystem ID for the virtio-fs device (decimal 26 --
see
<https://github.com/oasis-tcs/virtio-spec/blob/87fa6b5d8155/virtio-fs.tex>).
Beyond that, no actual Virtio setup is performed for now. Those bits are
going to be implemented later in this series.
On the "BY_START" (= UEFI filesystem) side, the VirtioFsOpenVolume()
function -- which is the sole EFI_SIMPLE_FILE_SYSTEM_PROTOCOL member
function -- is a stub; it always returns EFI_NO_MEDIA, for now.
The "CONNECT", "DISCONNECT", and "MAP -R" UEFI Shell commands can be used
to test this patch.
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-4-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
2020-12-16 22:10:40 +01:00
|
|
|
SimpleFsOpenVolume.c
|
OvmfPkg/VirtioFsDxe: implement EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume()
With the help of the VirtioFsFuseOpenDir() and
VirtioFsFuseReleaseFileOrDir() functions introduced previously, we can now
open and close the root directory. So let's implement
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume().
OpenVolume() creates a new EFI_FILE_PROTOCOL object -- a reference to the
root directory of the filesystem. Thus, we have to start tracking
references to EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, lest we unbind the
virtio-fs device while files are open.
There are two methods that release an EFI_FILE_PROTOCOL object: the
Close() and the Delete() member functions. In particular, they are not
allowed to fail with regard to resource management -- they must release
resources unconditionally. Thus, for rolling back the resource accounting
that we do in EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume(), we have to
implement the first versions of EFI_FILE_PROTOCOL.Close() and
EFI_FILE_PROTOCOL.Delete() in this patch as well.
With this patch applied, the UEFI shell can enter the root directory of
the Virtio Filesystem (such as with the "FS3:" shell command), and the
"DIR" shell command exercises FUSE_OPENDIR and FUSE_RELEASEDIR, according
to the virtiofsd log. The "DIR" command reports the root directory as if
it were empty; probably because at this time, we only allow the shell to
open and to close the root directory, but not to read it.
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-12-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
2020-12-16 22:10:48 +01:00
|
|
|
SimpleFsRead.c
|
|
|
|
SimpleFsSetInfo.c
|
|
|
|
SimpleFsSetPosition.c
|
|
|
|
SimpleFsWrite.c
|
OvmfPkg/VirtioFsDxe: DriverBinding: open VirtioDevice, install SimpleFs
Complete the Supported, Start, and Stop member functions of
EFI_DRIVER_BINDING_PROTOCOL sufficiently for exercising the UEFI driver
model:
- bind virtio-fs devices,
- produce placeholder EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instances on them.
On the "TO_START" (= Virtio) side, the VirtioFsBindingSupported() function
verifies the Virtio subsystem ID for the virtio-fs device (decimal 26 --
see
<https://github.com/oasis-tcs/virtio-spec/blob/87fa6b5d8155/virtio-fs.tex>).
Beyond that, no actual Virtio setup is performed for now. Those bits are
going to be implemented later in this series.
On the "BY_START" (= UEFI filesystem) side, the VirtioFsOpenVolume()
function -- which is the sole EFI_SIMPLE_FILE_SYSTEM_PROTOCOL member
function -- is a stub; it always returns EFI_NO_MEDIA, for now.
The "CONNECT", "DISCONNECT", and "MAP -R" UEFI Shell commands can be used
to test this patch.
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-4-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
2020-12-16 22:10:40 +01:00
|
|
|
VirtioFsDxe.h
|
2020-12-16 22:10:38 +01:00
|
|
|
|
|
|
|
[LibraryClasses]
|
|
|
|
BaseLib
|
OvmfPkg/VirtioFsDxe: add helper for appending and sanitizing paths
EFI_FILE_PROTOCOL.Open() -- for opening files -- and
EFI_FILE_PROTOCOL.SetInfo() -- for renaming files -- will require us to
append a relative UEFI pathname to an absolute base pathname. In turn,
components of the resultant pathnames will have to be sent to virtiofsd,
which does not consume UEFI-style pathnames.
We're going to maintain the base pathnames in canonical POSIX format:
- absolute (starts with "/"),
- dot (.) and dot-dot (..) components resolved/removed,
- uses forward slashes,
- sequences of slashes collapsed,
- printable ASCII character set,
- CHAR8 encoding,
- no trailing slash except for the root directory itself,
- length at most VIRTIO_FS_MAX_PATHNAME_LENGTH.
Add a helper function that can append a UEFI pathname to such a base
pathname, and produce the result in conformance with the same invariants.
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-17-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
2020-12-16 22:10:53 +01:00
|
|
|
BaseMemoryLib
|
OvmfPkg/VirtioFsDxe: DriverBinding: open VirtioDevice, install SimpleFs
Complete the Supported, Start, and Stop member functions of
EFI_DRIVER_BINDING_PROTOCOL sufficiently for exercising the UEFI driver
model:
- bind virtio-fs devices,
- produce placeholder EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instances on them.
On the "TO_START" (= Virtio) side, the VirtioFsBindingSupported() function
verifies the Virtio subsystem ID for the virtio-fs device (decimal 26 --
see
<https://github.com/oasis-tcs/virtio-spec/blob/87fa6b5d8155/virtio-fs.tex>).
Beyond that, no actual Virtio setup is performed for now. Those bits are
going to be implemented later in this series.
On the "BY_START" (= UEFI filesystem) side, the VirtioFsOpenVolume()
function -- which is the sole EFI_SIMPLE_FILE_SYSTEM_PROTOCOL member
function -- is a stub; it always returns EFI_NO_MEDIA, for now.
The "CONNECT", "DISCONNECT", and "MAP -R" UEFI Shell commands can be used
to test this patch.
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-4-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
2020-12-16 22:10:40 +01:00
|
|
|
DebugLib
|
|
|
|
MemoryAllocationLib
|
2020-12-16 22:10:58 +01:00
|
|
|
TimeBaseLib
|
2020-12-16 22:10:38 +01:00
|
|
|
UefiBootServicesTableLib
|
|
|
|
UefiDriverEntryPoint
|
2020-12-16 22:10:41 +01:00
|
|
|
VirtioLib
|
2020-12-16 22:10:38 +01:00
|
|
|
|
|
|
|
[Protocols]
|
|
|
|
gEfiComponentName2ProtocolGuid ## PRODUCES
|
|
|
|
gEfiDriverBindingProtocolGuid ## PRODUCES
|
OvmfPkg/VirtioFsDxe: DriverBinding: open VirtioDevice, install SimpleFs
Complete the Supported, Start, and Stop member functions of
EFI_DRIVER_BINDING_PROTOCOL sufficiently for exercising the UEFI driver
model:
- bind virtio-fs devices,
- produce placeholder EFI_SIMPLE_FILE_SYSTEM_PROTOCOL instances on them.
On the "TO_START" (= Virtio) side, the VirtioFsBindingSupported() function
verifies the Virtio subsystem ID for the virtio-fs device (decimal 26 --
see
<https://github.com/oasis-tcs/virtio-spec/blob/87fa6b5d8155/virtio-fs.tex>).
Beyond that, no actual Virtio setup is performed for now. Those bits are
going to be implemented later in this series.
On the "BY_START" (= UEFI filesystem) side, the VirtioFsOpenVolume()
function -- which is the sole EFI_SIMPLE_FILE_SYSTEM_PROTOCOL member
function -- is a stub; it always returns EFI_NO_MEDIA, for now.
The "CONNECT", "DISCONNECT", and "MAP -R" UEFI Shell commands can be used
to test this patch.
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-4-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
2020-12-16 22:10:40 +01:00
|
|
|
gEfiSimpleFileSystemProtocolGuid ## BY_START
|
|
|
|
gVirtioDeviceProtocolGuid ## TO_START
|
2020-12-16 22:11:07 +01:00
|
|
|
|
|
|
|
[Guids]
|
|
|
|
gEfiFileInfoGuid
|
|
|
|
gEfiFileSystemInfoGuid
|
|
|
|
gEfiFileSystemVolumeLabelInfoIdGuid
|