All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: devel@edk2.groups.io, virtio-fs@redhat.com, lersek@redhat.com
Cc: "Jordan Justen" <jordan.l.justen@intel.com>,
	"Philippe Mathieu-Daudé" <philmd@redhat.com>,
	"Ard Biesheuvel" <ard.biesheuvel@arm.com>
Subject: [Virtio-fs] [edk2 PATCH 16/48] OvmfPkg/VirtioFsDxe: add helper for appending and sanitizing paths
Date: Wed, 16 Dec 2020 22:10:53 +0100	[thread overview]
Message-ID: <20201216211125.19496-17-lersek@redhat.com> (raw)
In-Reply-To: <20201216211125.19496-1-lersek@redhat.com>

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>
---
 OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf |   1 +
 OvmfPkg/VirtioFsDxe/VirtioFsDxe.h   |  32 ++
 OvmfPkg/VirtioFsDxe/Helpers.c       | 474 ++++++++++++++++++++
 3 files changed, 507 insertions(+)

diff --git a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
index 15e21772c8ac..0c92bccdac86 100644
--- a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
+++ b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
@@ -99,16 +99,17 @@ [Sources]
   SimpleFsRead.c
   SimpleFsSetInfo.c
   SimpleFsSetPosition.c
   SimpleFsWrite.c
   VirtioFsDxe.h
 
 [LibraryClasses]
   BaseLib
+  BaseMemoryLib
   DebugLib
   MemoryAllocationLib
   UefiBootServicesTableLib
   UefiDriverEntryPoint
   VirtioLib
 
 [Protocols]
   gEfiComponentName2ProtocolGuid        ## PRODUCES
diff --git a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
index 1cbd27d8fb52..f4fed64c7217 100644
--- a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
+++ b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
@@ -17,16 +17,40 @@
 #include <Protocol/VirtioDevice.h>     // VIRTIO_DEVICE_PROTOCOL
 #include <Uefi/UefiBaseType.h>         // EFI_EVENT
 
 #define VIRTIO_FS_SIG SIGNATURE_64 ('V', 'I', 'R', 'T', 'I', 'O', 'F', 'S')
 
 #define VIRTIO_FS_FILE_SIG \
   SIGNATURE_64 ('V', 'I', 'O', 'F', 'S', 'F', 'I', 'L')
 
+//
+// The following limit applies to two kinds of pathnames.
+//
+// - The length of a POSIX-style, canonical pathname *at rest* never exceeds
+//   VIRTIO_FS_MAX_PATHNAME_LENGTH. (Length is defined as the number of CHAR8
+//   elements in the canonical pathname, excluding the terminating '\0'.) This
+//   is an invariant that is ensured for canonical pathnames created, and that
+//   is assumed about canonical pathname inputs (which all originate
+//   internally).
+//
+// - If the length of a UEFI-style pathname *argument*, originating directly or
+//   indirectly from the EFI_FILE_PROTOCOL caller, exceeds
+//   VIRTIO_FS_MAX_PATHNAME_LENGTH, then the argument is rejected. (Length is
+//   defined as the number of CHAR16 elements in the UEFI-style pathname,
+//   excluding the terminating L'\0'.) This is a restriction that's checked on
+//   external UEFI-style pathname inputs.
+//
+// The limit is not expected to be a practical limitation; it's only supposed
+// to prevent attempts at overflowing size calculations. For both kinds of
+// pathnames, separate limits could be used; a common limit is used purely for
+// simplicity.
+//
+#define VIRTIO_FS_MAX_PATHNAME_LENGTH ((UINTN)65535)
+
 //
 // Filesystem label encoded in UCS-2, transformed from the UTF-8 representation
 // in "VIRTIO_FS_CONFIG.Tag", and NUL-terminated. Only the printable ASCII code
 // points (U+0020 through U+007E) are supported.
 //
 typedef CHAR16 VIRTIO_FS_LABEL[VIRTIO_FS_TAG_BYTES + 1];
 
 //
@@ -187,16 +211,24 @@ VirtioFsFuseCheckResponse (
   OUT UINTN                         *TailBufferFill
   );
 
 EFI_STATUS
 VirtioFsErrnoToEfiStatus (
   IN INT32 Errno
   );
 
+EFI_STATUS
+VirtioFsAppendPath (
+  IN     CHAR8   *LhsPath8,
+  IN     CHAR16  *RhsPath16,
+     OUT CHAR8   **ResultPath8,
+     OUT BOOLEAN *RootEscape
+  );
+
 //
 // Wrapper functions for FUSE commands (primitives).
 //
 
 EFI_STATUS
 VirtioFsFuseForget (
   IN OUT VIRTIO_FS *VirtioFs,
   IN     UINT64    NodeId
diff --git a/OvmfPkg/VirtioFsDxe/Helpers.c b/OvmfPkg/VirtioFsDxe/Helpers.c
index 00f762142746..4a7b59332ca9 100644
--- a/OvmfPkg/VirtioFsDxe/Helpers.c
+++ b/OvmfPkg/VirtioFsDxe/Helpers.c
@@ -1,16 +1,19 @@
 /** @file
   Initialization and helper routines for the Virtio Filesystem device.
 
   Copyright (C) 2020, Red Hat, Inc.
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
+#include <Library/BaseLib.h>             // StrLen()
+#include <Library/BaseMemoryLib.h>       // CopyMem()
+#include <Library/MemoryAllocationLib.h> // AllocatePool()
 #include <Library/VirtioLib.h>           // Virtio10WriteFeatures()
 
 #include "VirtioFsDxe.h"
 
 /**
   Read the Virtio Filesystem device configuration structure in full.
 
   @param[in] Virtio   The Virtio protocol underlying the VIRTIO_FS object.
@@ -1110,8 +1113,479 @@ VirtioFsErrnoToEfiStatus (
     return EFI_NOT_STARTED;
 
   default:
     break;
   }
 
   return EFI_DEVICE_ERROR;
 }
+
+//
+// Parser states for canonicalizing a POSIX pathname.
+//
+typedef enum {
+  ParserInit,   // just starting
+  ParserEnd,    // finished
+  ParserSlash,  // slash(es) seen
+  ParserDot,    // one dot seen since last slash
+  ParserDotDot, // two dots seen since last slash
+  ParserNormal, // a different sequence seen
+} PARSER_STATE;
+
+/**
+  Strip the trailing slash from the parser's output buffer, unless the trailing
+  slash stands for the root directory.
+
+  @param[in] Buffer        The parser's output buffer. Only used for
+                           sanity-checking.
+
+  @param[in,out] Position  On entry, points at the next character to produce
+                           (i.e., right past the end of the output written by
+                           the parser thus far). The last character in the
+                           parser's output buffer is a slash. On return, the
+                           slash is stripped, by decrementing Position by one.
+                           If this action would remove the slash character
+                           standing for the root directory, then the function
+                           has no effect.
+**/
+STATIC
+VOID
+ParserStripSlash (
+  IN     CHAR8 *Buffer,
+  IN OUT UINTN *Position
+  )
+{
+  ASSERT (*Position >= 1);
+  ASSERT (Buffer[*Position - 1] == '/');
+  if (*Position == 1) {
+    return;
+  }
+  (*Position)--;
+}
+
+/**
+  Produce one character in the parser's output buffer.
+
+  @param[out] Buffer       The parser's output buffer. On return, Char8 will
+                           have been written.
+
+  @param[in,out] Position  On entry, points at the next character to produce
+                           (i.e., right past the end of the output written by
+                           the parser thus far). On return, Position is
+                           incremented by one.
+
+  @param[in] Size          Total allocated size of the parser's output buffer.
+                           Used for sanity-checking.
+
+  @param[in] Char8         The character to place in the output buffer.
+**/
+STATIC
+VOID
+ParserCopy (
+     OUT CHAR8 *Buffer,
+  IN OUT UINTN *Position,
+  IN     UINTN Size,
+  IN     CHAR8 Char8
+  )
+{
+  ASSERT (*Position < Size);
+  Buffer[(*Position)++] = Char8;
+}
+
+/**
+  Rewind the last single-dot in the parser's output buffer.
+
+  @param[in] Buffer        The parser's output buffer. Only used for
+                           sanity-checking.
+
+  @param[in,out] Position  On entry, points at the next character to produce
+                           (i.e., right past the end of the output written by
+                           the parser thus far); the parser's output buffer
+                           ends with the characters ('/', '.'). On return, the
+                           dot is rewound by decrementing Position by one; a
+                           slash character will reside at the new end of the
+                           parser's output buffer.
+**/
+STATIC
+VOID
+ParserRewindDot (
+  IN     CHAR8 *Buffer,
+  IN OUT UINTN *Position
+  )
+{
+  ASSERT (*Position >= 2);
+  ASSERT (Buffer[*Position - 1] == '.');
+  ASSERT (Buffer[*Position - 2] == '/');
+  (*Position)--;
+}
+
+/**
+  Rewind the last dot-dot in the parser's output buffer.
+
+  @param[in] Buffer        The parser's output buffer. Only used for
+                           sanity-checking.
+
+  @param[in,out] Position  On entry, points at the next character to produce
+                           (i.e., right past the end of the output written by
+                           the parser thus far); the parser's output buffer
+                           ends with the characters ('/', '.', '.'). On return,
+                           the ('.', '.') pair is rewound unconditionally, by
+                           decrementing Position by two; a slash character
+                           resides at the new end of the parser's output
+                           buffer.
+
+                           If this slash character stands for the root
+                           directory, then RootEscape is set to TRUE.
+
+                           Otherwise (i.e., if this slash character is not the
+                           one standing for the root directory), then the slash
+                           character, and the pathname component preceding it,
+                           are removed by decrementing Position further. In
+                           this case, the slash character preceding the removed
+                           pathname component will reside at the new end of the
+                           parser's output buffer.
+
+  @param[out] RootEscape   Set to TRUE on output if the dot-dot component tries
+                           to escape the root directory, as described above.
+                           Otherwise, RootEscape is not modified.
+**/
+STATIC
+VOID
+ParserRewindDotDot (
+  IN     CHAR8   *Buffer,
+  IN OUT UINTN   *Position,
+     OUT BOOLEAN *RootEscape
+
+  )
+{
+  ASSERT (*Position >= 3);
+  ASSERT (Buffer[*Position - 1] == '.');
+  ASSERT (Buffer[*Position - 2] == '.');
+  ASSERT (Buffer[*Position - 3] == '/');
+  (*Position) -= 2;
+
+  if (*Position == 1) {
+    //
+    // Root directory slash reached; don't try to climb higher.
+    //
+    *RootEscape = TRUE;
+    return;
+  }
+
+  //
+  // Skip slash.
+  //
+  (*Position)--;
+  //
+  // Scan until next slash to the left.
+  //
+  do {
+    ASSERT (*Position > 0);
+    (*Position)--;
+  } while (Buffer[*Position] != '/');
+  (*Position)++;
+}
+
+/**
+  Append the UEFI-style RhsPath16 to the POSIX-style, canonical format
+  LhsPath8. Output the POSIX-style, canonical format result in ResultPath, as a
+  dynamically allocated string.
+
+  Canonicalization (aka sanitization) establishes the following properties:
+  - ResultPath is absolute (starts with "/"),
+  - dot (.) and dot-dot (..) components are resolved/eliminated in ResultPath,
+    with the usual semantics,
+  - ResultPath uses forward slashes,
+  - sequences of slashes are squashed in ResultPath,
+  - the printable ASCII character set covers ResultPath,
+  - CHAR8 encoding is used in ResultPath,
+  - no trailing slash present in ResultPath except for the standalone root
+    directory,
+  - the length of ResultPath is at most VIRTIO_FS_MAX_PATHNAME_LENGTH.
+
+  Any dot-dot in RhsPath16 that would remove the root directory is dropped, and
+  reported through RootEscape, without failing the function call.
+
+  @param[in] LhsPath8      Identifies the base directory. The caller is
+                           responsible for ensuring that LhsPath8 conform to
+                           the above canonical pathname format on entry.
+
+  @param[in] RhsPath16     Identifies the desired file with a UEFI-style CHAR16
+                           pathname. If RhsPath16 starts with a backslash, then
+                           RhsPath16 is considered absolute, and LhsPath8 is
+                           ignored; RhsPath16 is sanitized in isolation, for
+                           producing ResultPath8. Otherwise (i.e., if RhsPath16
+                           is relative), RhsPath16 is transliterated to CHAR8,
+                           and naively appended to LhsPath8. The resultant
+                           fused pathname is then sanitized, to produce
+                           ResultPath8.
+
+  @param[out] ResultPath8  The POSIX-style, canonical format pathname that
+                           leads to the file desired by the caller. After use,
+                           the caller is responsible for freeing ResultPath8.
+
+  @param[out] RootEscape   Set to TRUE if at least one dot-dot component in
+                           RhsPath16 attempted to escape the root directory;
+                           set to FALSE otherwise.
+
+  @retval EFI_SUCCESS            ResultPath8 has been produced. RootEscape has
+                                 been output.
+
+  @retval EFI_INVALID_PARAMETER  RhsPath16 is zero-length.
+
+  @retval EFI_INVALID_PARAMETER  RhsPath16 failed the
+                                 VIRTIO_FS_MAX_PATHNAME_LENGTH check.
+
+  @retval EFI_OUT_OF_RESOURCES   Memory allocation failed.
+
+  @retval EFI_OUT_OF_RESOURCES   ResultPath8 would have failed the
+                                 VIRTIO_FS_MAX_PATHNAME_LENGTH check.
+
+  @retval EFI_UNSUPPORTED        RhsPath16 contains a character that either
+                                 falls outside of the printable ASCII set, or
+                                 is a forward slash.
+**/
+EFI_STATUS
+VirtioFsAppendPath (
+  IN     CHAR8   *LhsPath8,
+  IN     CHAR16  *RhsPath16,
+     OUT CHAR8   **ResultPath8,
+     OUT BOOLEAN *RootEscape
+  )
+{
+  UINTN        RhsLen;
+  CHAR8        *RhsPath8;
+  UINTN        Idx;
+  EFI_STATUS   Status;
+  UINTN        SizeToSanitize;
+  CHAR8        *BufferToSanitize;
+  CHAR8        *SanitizedBuffer;
+  PARSER_STATE State;
+  UINTN        SanitizedPosition;
+
+  //
+  // Appending an empty pathname is not allowed.
+  //
+  RhsLen = StrLen (RhsPath16);
+  if (RhsLen == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Enforce length restriction on RhsPath16.
+  //
+  if (RhsLen > VIRTIO_FS_MAX_PATHNAME_LENGTH) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Transliterate RhsPath16 to RhsPath8 by:
+  // - rejecting RhsPath16 if a character outside of printable ASCII is seen,
+  // - rejecting RhsPath16 if a forward slash is seen,
+  // - replacing backslashes with forward slashes,
+  // - casting the characters from CHAR16 to CHAR8.
+  //
+  RhsPath8 = AllocatePool (RhsLen + 1);
+  if (RhsPath8 == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  for (Idx = 0; RhsPath16[Idx] != L'\0'; Idx++) {
+    if (RhsPath16[Idx] < 0x20 || RhsPath16[Idx] > 0x7E ||
+        RhsPath16[Idx] == L'/') {
+      Status = EFI_UNSUPPORTED;
+      goto FreeRhsPath8;
+    }
+    RhsPath8[Idx] = (CHAR8)((RhsPath16[Idx] == L'\\') ? L'/' : RhsPath16[Idx]);
+  }
+  RhsPath8[Idx++] = '\0';
+
+  //
+  // Now prepare the input for the canonicalization (squashing of sequences of
+  // forward slashes, and eliminating . (dot) and .. (dot-dot) pathname
+  // components).
+  //
+  // The sanitized path can never be longer than the naive concatenation of the
+  // left hand side and right hand side paths, so we'll use the catenated size
+  // for allocating the sanitized output too.
+  //
+  if (RhsPath8[0] == '/') {
+    //
+    // If the right hand side path is absolute, then it is not appended to the
+    // left hand side path -- it *replaces* the left hand side path.
+    //
+    SizeToSanitize = RhsLen + 1;
+    BufferToSanitize = RhsPath8;
+  } else {
+    //
+    // If the right hand side path is relative, then it is appended (naively)
+    // to the left hand side.
+    //
+    UINTN LhsLen;
+
+    LhsLen = AsciiStrLen (LhsPath8);
+    SizeToSanitize = LhsLen + 1 + RhsLen + 1;
+    BufferToSanitize = AllocatePool (SizeToSanitize);
+    if (BufferToSanitize == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto FreeRhsPath8;
+    }
+    CopyMem (BufferToSanitize, LhsPath8, LhsLen);
+    BufferToSanitize[LhsLen] = '/';
+    CopyMem (BufferToSanitize + LhsLen + 1, RhsPath8, RhsLen + 1);
+  }
+
+  //
+  // Allocate the output buffer.
+  //
+  SanitizedBuffer = AllocatePool (SizeToSanitize);
+  if (SanitizedBuffer == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeBufferToSanitize;
+  }
+
+  //
+  // State machine for parsing the input and producing the canonical output
+  // follows.
+  //
+  *RootEscape       = FALSE;
+  Idx               = 0;
+  State             = ParserInit;
+  SanitizedPosition = 0;
+  do {
+    CHAR8 Chr8;
+
+    ASSERT (Idx < SizeToSanitize);
+    Chr8 = BufferToSanitize[Idx++];
+
+    switch (State) {
+    case ParserInit: // just starting
+      ASSERT (Chr8 == '/');
+      ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+      State = ParserSlash;
+      break;
+
+    case ParserSlash: // slash(es) seen
+      switch (Chr8) {
+      case '\0':
+        ParserStripSlash (SanitizedBuffer, &SanitizedPosition);
+        ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+        State = ParserEnd;
+        break;
+      case '/':
+        //
+        // skip & stay in same state
+        //
+        break;
+      case '.':
+        ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+        State = ParserDot;
+        break;
+      default:
+        ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+        State = ParserNormal;
+        break;
+      }
+      break;
+
+    case ParserDot: // one dot seen since last slash
+      switch (Chr8) {
+      case '\0':
+        ParserRewindDot (SanitizedBuffer, &SanitizedPosition);
+        ParserStripSlash (SanitizedBuffer, &SanitizedPosition);
+        ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+        State = ParserEnd;
+        break;
+      case '/':
+        ParserRewindDot (SanitizedBuffer, &SanitizedPosition);
+        State = ParserSlash;
+        break;
+      case '.':
+        ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+        State = ParserDotDot;
+        break;
+      default:
+        ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+        State = ParserNormal;
+        break;
+      }
+      break;
+
+    case ParserDotDot: // two dots seen since last slash
+      switch (Chr8) {
+      case '\0':
+        ParserRewindDotDot (SanitizedBuffer, &SanitizedPosition, RootEscape);
+        ParserStripSlash (SanitizedBuffer, &SanitizedPosition);
+        ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+        State = ParserEnd;
+        break;
+      case '/':
+        ParserRewindDotDot (SanitizedBuffer, &SanitizedPosition, RootEscape);
+        State = ParserSlash;
+        break;
+      case '.':
+        //
+        // fall through
+        //
+      default:
+        ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+        State = ParserNormal;
+        break;
+      }
+      break;
+
+    case ParserNormal: // a different sequence seen
+      switch (Chr8) {
+      case '\0':
+        ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+        State = ParserEnd;
+        break;
+      case '/':
+        ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+        State = ParserSlash;
+        break;
+      case '.':
+        //
+        // fall through
+        //
+      default:
+        //
+        // copy and stay in same state
+        //
+        ParserCopy (SanitizedBuffer, &SanitizedPosition, SizeToSanitize, Chr8);
+        break;
+      }
+      break;
+
+    default:
+      ASSERT (FALSE);
+      break;
+    }
+  } while (State != ParserEnd);
+
+  //
+  // Ensure length invariant on ResultPath8.
+  //
+  ASSERT (SanitizedPosition >= 2);
+  if (SanitizedPosition - 1 > VIRTIO_FS_MAX_PATHNAME_LENGTH) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeSanitizedBuffer;
+  }
+
+  *ResultPath8    = SanitizedBuffer;
+  SanitizedBuffer = NULL;
+  Status          = EFI_SUCCESS;
+  //
+  // Fall through.
+  //
+FreeSanitizedBuffer:
+  if (SanitizedBuffer != NULL) {
+    FreePool (SanitizedBuffer);
+  }
+
+FreeBufferToSanitize:
+  if (RhsPath8[0] != '/') {
+    FreePool (BufferToSanitize);
+  }
+
+FreeRhsPath8:
+  FreePool (RhsPath8);
+  return Status;
+}
-- 
2.19.1.3.g30247aa5d201




  parent reply	other threads:[~2020-12-16 21:10 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-16 21:10 [Virtio-fs] [edk2 PATCH 00/48] ArmVirtPkg, OvmfPkg: virtio filesystem driver Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 01/48] OvmfPkg: introduce VirtioFsDxe Laszlo Ersek
2020-12-18 17:42   ` Ard Biesheuvel
2020-12-18 18:13     ` Dr. David Alan Gilbert
2020-12-19 21:16       ` Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 02/48] ArmVirtPkg: include VirtioFsDxe in the ArmVirtQemu* platforms Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 03/48] OvmfPkg/VirtioFsDxe: DriverBinding: open VirtioDevice, install SimpleFs Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 04/48] OvmfPkg/VirtioFsDxe: implement virtio device (un)initialization Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 05/48] OvmfPkg/VirtioFsDxe: add a scatter-gather list data type Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 06/48] OvmfPkg/VirtioFsDxe: introduce the basic FUSE request/response headers Laszlo Ersek
2020-12-17 11:49   ` Dr. David Alan Gilbert
2020-12-17 13:57     ` Laszlo Ersek
2020-12-17 14:06       ` Dr. David Alan Gilbert
2020-12-17 14:32       ` Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 07/48] OvmfPkg/VirtioFsDxe: map "errno" values to EFI_STATUS Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 08/48] OvmfPkg/VirtioFsDxe: submit the FUSE_INIT request to the device Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 09/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_OPENDIR Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 10/48] OvmfPkg/VirtioFsDxe: add shared wrapper for FUSE_RELEASE / FUSE_RELEASEDIR Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 11/48] OvmfPkg/VirtioFsDxe: implement EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume() Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 12/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_FORGET Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 13/48] OvmfPkg/VirtioFsDxe: add a shared wrapper for FUSE_FSYNC / FUSE_FSYNCDIR Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 14/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_FLUSH Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 15/48] OvmfPkg/VirtioFsDxe: flush, sync, release and forget in Close() / Delete() Laszlo Ersek
2020-12-16 21:10 ` Laszlo Ersek [this message]
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 17/48] OvmfPkg/VirtioFsDxe: manage path lifecycle in OpenVolume, Close, Delete Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 18/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_OPEN Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 19/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_MKDIR Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 20/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_CREATE Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 21/48] OvmfPkg/VirtioFsDxe: convert FUSE inode attributes to EFI_FILE_INFO Laszlo Ersek
2020-12-16 21:10 ` [Virtio-fs] [edk2 PATCH 22/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_LOOKUP Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 23/48] OvmfPkg/VirtioFsDxe: split canon. path into last parent + last component Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 24/48] OvmfPkg/VirtioFsDxe: add a shared wrapper for FUSE_UNLINK / FUSE_RMDIR Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 25/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_GETATTR Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 26/48] OvmfPkg/VirtioFsDxe: implement EFI_FILE_PROTOCOL.Open() Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 27/48] OvmfPkg/VirtioFsDxe: erase the dir. entry in EFI_FILE_PROTOCOL.Delete() Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 28/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_STATFS Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 29/48] OvmfPkg/VirtioFsDxe: add helper for formatting UEFI basenames Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 30/48] OvmfPkg/VirtioFsDxe: implement EFI_FILE_PROTOCOL.GetInfo() Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 31/48] OvmfPkg/VirtioFsDxe: implement EFI_FILE_PROTOCOL.GetPosition, .SetPosition Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 32/48] OvmfPkg/VirtioFsDxe: add a shared wrapper for FUSE_READ / FUSE_READDIRPLUS Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 33/48] OvmfPkg/VirtioFsDxe: implement EFI_FILE_PROTOCOL.Read() for regular files Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 34/48] OvmfPkg/VirtioFsDxe: convert FUSE dirent filename to EFI_FILE_INFO Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 35/48] OvmfPkg/VirtioFsDxe: add EFI_FILE_INFO cache fields to VIRTIO_FS_FILE Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 36/48] OvmfPkg/VirtioFsDxe: implement EFI_FILE_PROTOCOL.Read() for directories Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 37/48] OvmfPkg/VirtioFsDxe: implement EFI_FILE_PROTOCOL.Flush() Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 38/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_WRITE Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 39/48] OvmfPkg/VirtioFsDxe: implement EFI_FILE_PROTOCOL.Write() Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 40/48] OvmfPkg/VirtioFsDxe: handle the volume label in EFI_FILE_PROTOCOL.SetInfo Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 41/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_RENAME2 Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 42/48] OvmfPkg/VirtioFsDxe: add helper for composing rename/move destination path Laszlo Ersek
2020-12-18 17:39   ` Ard Biesheuvel
2020-12-19 22:40     ` Laszlo Ersek
2020-12-19 22:54       ` Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 43/48] OvmfPkg/VirtioFsDxe: handle file rename/move in EFI_FILE_PROTOCOL.SetInfo Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 44/48] OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_SETATTR Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 45/48] OvmfPkg/VirtioFsDxe: add helper for determining file size update Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 46/48] OvmfPkg/VirtioFsDxe: add helper for determining access time updates Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 47/48] OvmfPkg/VirtioFsDxe: add helper for determining file mode bits update Laszlo Ersek
2020-12-16 21:11 ` [Virtio-fs] [edk2 PATCH 48/48] OvmfPkg/VirtioFsDxe: handle attribute updates in EFI_FILE_PROTOCOL.SetInfo Laszlo Ersek
2020-12-18 17:44 ` [Virtio-fs] [edk2 PATCH 00/48] ArmVirtPkg, OvmfPkg: virtio filesystem driver Ard Biesheuvel
2020-12-20  0:09   ` Laszlo Ersek
2020-12-20 10:15     ` Ard Biesheuvel
2020-12-21  1:46       ` Laszlo Ersek
2020-12-21 10:10         ` Ard Biesheuvel
2020-12-21 18:02           ` [Virtio-fs] [edk2-devel] " Laszlo Ersek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201216211125.19496-17-lersek@redhat.com \
    --to=lersek@redhat.com \
    --cc=ard.biesheuvel@arm.com \
    --cc=devel@edk2.groups.io \
    --cc=jordan.l.justen@intel.com \
    --cc=philmd@redhat.com \
    --cc=virtio-fs@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.