public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Laszlo Ersek" <lersek@redhat.com>
To: "Marvin Häuser" <mhaeuser@outlook.de>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: Andrew Fish <afish@apple.com>,
	Anthony Perard <anthony.perard@citrix.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Benjamin You <benjamin.you@intel.com>,
	Chao Zhang <chao.b.zhang@intel.com>,
	Dandan Bi <dandan.bi@intel.com>,
	David Woodhouse <dwmw2@infradead.org>,
	Eric Dong <eric.dong@intel.com>, Guo Dong <guo.dong@intel.com>,
	Hao A Wu <hao.a.wu@intel.com>,
	Jaben Carsey <jaben.carsey@intel.com>,
	Jian J Wang <jian.j.wang@intel.com>,
	Jiaxin Wu <jiaxin.wu@intel.com>,
	Jiewen Yao <jiewen.yao@intel.com>,
	Jordan Justen <jordan.l.justen@intel.com>,
	Julien Grall <julien.grall@arm.com>,
	Leif Lindholm <leif.lindholm@linaro.org>,
	Liming Gao <liming.gao@intel.com>,
	Maurice Ma <maurice.ma@intel.com>,
	Michael D Kinney <michael.d.kinney@intel.com>,
	Ray Ni <ray.ni@intel.com>, Siyuan Fu <siyuan.fu@intel.com>,
	Supreeth Venkatesh <supreeth.venkatesh@arm.com>,
	Zhichao Gao <zhichao.gao@intel.com>
Subject: Re: [edk2-devel] [PATCH 00/35] edk2: clean up the usage of standardized (VOID*) typedefs
Date: Tue, 24 Sep 2019 22:26:13 +0200	[thread overview]
Message-ID: <06b8b728-e38e-cc64-4499-9733fc993e5d@redhat.com> (raw)
In-Reply-To: <VI1PR0701MB25594288EE33C92D94A7F67CAC850@VI1PR0701MB2559.eurprd07.prod.outlook.com>

On 09/23/19 18:27, Marvin Häuser wrote:
> Good day,
> 
> Thank you, Laszlo, for your ambition to introduce stricter code style 
> enforcements. Sorry to "hijack" the actual topic (I did not CC anyone on 
> purpose, as this is mostly a separate topic and I'd like a quick comment 
> first), but this seems like a good occasion to mention another few bad 
> practices edk2 has been following. Mainly, I'd like to call *some* 
> attention to quality problems in the code base while this has some 
> traction, and cause a discussion on whether and how those are to be 
> approached.
> 
> Thank you for your time.

Sure, I can offer my personal opinion on these.


> "inadequate type punning":
> e.g. 
> https://github.com/tianocore/edk2/blob/fcdedafd97c8f18c33a63d26b954e5dbaee81a2b/MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.c#L446
> 
> This is mostly about the infamous "Strict Aliasing" rule, which is 
> basically:
> "An object shall have its stored value accessed only by an lvalue 
> expression that has one of the
> following types:
> — a type compatible with the effective type of the object,
> — a qualifed version of a type compatible with the effective type of the 
> object,
> — a type that is the signed or unsigned type corresponding to the 
> effective type of the object,
> — a type that is the signed or unsigned type corresponding to a qualifed 
> version of the effective
> type of the object,
> — an aggregate or union type that includes one of the aforementioned 
> types among its members
> (including, recursively, a member of a subaggregate or contained union), or
> — a character type."
> C18 (ISO/IEC 9899:2018), 6.5.7 (exists, though has been updated, since C90)
> 
> Currently optimisations based on this are disabled. This is a bit nasty 
> to work around if *seriously* needed when sticking to C90, I can only 
> think of memcpy right now. However, even though there are compilers that 
> do not fully support C99 (ahem, Microsoft :) ), type-punning by unions 
> should be supported by them all, and has been legal as of C99, where the 
> following part has been dropped from the standard:
> "With one exception, if a member of a union object is accessed after a 
> value has been stored in a different member of the object, the behavior 
> is implementation-defined."
> C90 (ISO/IEC 9899:1990), 6.3.2.3

I'm opposed to enforcing the strict aliasing rules, even though in all
code that I write, I either try to conform to them, or at least I seek
to be fully conscious of breaking them.

Here's the thing: IMO, the strict aliasing rules sacrifice flexibility
for performance (optimization possibilities). Not to mention the amount
of code in edk2 that would have to be identified and updated.

BaseTools uses "-fno-strict-aliasing" everywhere, and I think that's a
good choice.

  https://blog.regehr.org/archives/1180

This proposal for a "friendly dialect of C" intended to eliminate the
strict aliasing rules altogether. (Item#10; possibly also item#13.)

Also, as it points out, the Linux kernel is built with
"-fno-strict-aliasing". I've checked now, with a *long* series of "git
blame" commands, even digging into the "history" repository (which is at
<git://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git>). I can
say that the current flag has been in place since *at least* Linux
v2.5.0 (2002-02-04).

QEMU has been built with "-fno-strict-aliasing" ever since commit
b932caba32c6 ("new disk image layer", 2004-08-01), known originally as
SVN rev 1030.


Consider the following example. You have a dynamically allocated buffer.
You read some data into it, from the network or the disk, using PCI DMA.
Let's assume that, from the block read via PCI DMA, the library
function(s) or protocol member(s) that you call, directly or indirectly,
there is at least one that:
- copies data from a source buffer to a target buffer, using UINT32 or
UINT64 assignments (for speed),
- and is implemented in C.

Now, according to the effective type rules, your dynamic buffer's
effective type is "array of UINT32" or "array of UINT64". That's because
of C99 6.5 Expressions, p6:

"If a value is stored into an object having no declared type through an
lvalue having a type that is not a character type, then the type of the
lvalue becomes the effective type of the object for that access and for
subsequent accesses that do not modify the stored value."

Then if you try to parse this buffer as a UEFI device path (= a packed
sequence of device path node structures), *IN PLACE*, you will break the
effective type rules no matter what. Because, you will necessarily look
at the next node in the blob as an EFI_DEVICE_PATH_PROTOCOL (because
you'll want to learn the Type and the SubType fields, and the Length
array too). Note that EFI_DEVICE_PATH_PROTOCOL is a structure with no
UINT32 or UINT64 members. Boom.

So you have to resort to one of the following things:

1. Define a union type, assign the *full union* first
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90167#c3>, and then check
the union helper variable. (First you must make sure there was enough
room in the buffer being parsed for a full union.)

2. Or, use memcpy() -- or something that the compiler is similarly
enlightened about --, to the same helper variable.

3. Or, write a manual copy loop with character access, to the helper
variable.

4. Or, use character access to read the fields.

#1 through #3 add a separate copying step, while #4 is extremely
uncomfortable to program.

In a nutshell, the effective type rules require separate
de-serialization routines for all data, and that's incredibly annoying.
It kills the utility of packed C structures.

I prefer packed C structures, size checks (!!!) against the buffers to
parse, and then type punning of pointers.


> "pointer unions":
> e.g. 
> https://github.com/tianocore/edk2/blob/fcdedafd97c8f18c33a63d26b954e5dbaee81a2b/MdePkg/Include/IndustryStandard/SmBios.h#L2592
> 
> While the idea behind them is certainly style preference, using a union 
> of pointers prevents two important things over a union of structs.
> 
> 1) CONST declaration: When defining a variable of a union type 
> containing pointers as CONST, speaking of its members, they are all 
> going to be CONST pointers to arbitrary memory and not arbitrary 
> pointers to CONST memory. With a union of structs, you can have either 
> as required (e.g. CONST UNION_TYPE *union, or UNION_TYPE *COST union).

Formally, you are right, but I'm doubtful of the utility of
"pointer-to-union-of-structs". We cannot de-reference a pointer to the
union unless the buffer has enough data for the complete union. This
leaves the parsing of small structs unsolved.

A union of pointers is just syntactic sugar, of course, but it's
convenient. The member that is "pointer-to-smallest-header-substructure"
can be used for determining the actual structure type. Then we can
determine if there's enough data for that structure in the buffer. Then
we can use the matching pointer member, for accessing that structure.

Furthermore, CONST gets too complex really soon, and we have to start
adding explicit casts. My favorite link is:

  http://c-faq.com/ansi/constmismatch.html

I had never met "pointer unions" before edk2, but I've found them quite
convenient.


> 2) Well-defined header inspection:
> "if a union contains several structures that share a common initial 
> sequence [...], it is permitted to inspect the common initial part of 
> any of them anywhere that a declaration of the completed type of the 
> union is visible"
> C18 (ISO/IEC 9899:2018), 6.5.2.3.6 (exists since at least C90)
> 
> This guarantee can be used to inspect the type defined in a common 
> header (e.g. SMBIOS_STRUCTURE) and the process the type-specific data by 
> accessing the appropiate member (e.g. SMBIOS_TABLE_TYPE0) legally.

This only applies *after* you have populated the union for inspection.
(Or at least enough bytes for the common header that you're going to
inspect.)

If you have a union collecting three structures: 5 bytes, 19 bytes, and
32 bytes, and you have a buffer with 24 bytes left (suggesting a 5 byte
structure and a 19 byte structure in it, or vice versa), you cannot
populate the full union -- you don't have 32 bytes left.

So let's then assume that the common header is 2 bytes long (with 3 vs.
17 vs. 30 additional bytes required in the specific structures). Fine,
then you read 2 bytes into the stand-alone union helper variable, for
inspecting the common header. Based on the header inspection, you then
decide to (attempt to) read 3 more bytes, or 17 bytes, continuing into
the union, and then parse the specific (now completed) structure through
the matching union member. Great?

Not really. Notice that, in this process, you didn't need the union *at
all*. You can simply use standalone structures, and you may not even
need more stack space.

Compare:

(i) with a union:

enum Type {
  type_1,
  type_2
}

struct H {
  enum Type t;
  ...
};

struct S1 {
  struct H h;
  int S1_i1;
};

struct S2 {
  struct H h;
  char S2_c;
  double S2_d;
};

union U {
  S1 s1;
  S2 s2;
};

Code:

union U u;
char unsigned *src = buffer;
char unsigned *dst = (void*)&u;
size_t specific;

if (room_left < sizeof(struct H)) {
  return BAD;
}

memcpy(dst, src, sizeof(struct H));
dst += sizeof(struct H);
src += sizeof(struct H);
room_left -= sizeof(struct H);

switch (u.s1.h.t) {
  case type_1:
    specific = sizeof(struct S1) - sizeof(struct H);
    if (room_left < specific) {
      return BAD;
    }
    memcpy(dst, src, specific);
    dst += specific;
    src += specific;
    room_left -= specific;
    /* now access u.s1.S1_i1 */
    return GOOD;

  case type_2:
    specific = sizeof(struct S2) - sizeof(struct H);
    if (room_left < specific) {
      return BAD;
    }
    memcpy(dst, src, specific);
    dst += specific;
    src += specific;
    room_left -= specific;
    /* now access u.s2.{S2_c,S2_d} */
    return GOOD;

  default:
    return BAD;
}


(ii) without a union:

enum Type {
  type_1,
  type_2
}

struct H {
  enum Type t;
  ...
};

/* note: header no longer embedded */
struct S1 {
  int S1_i1;
};

/* note: header no longer embedded */
struct S2 {
  char S2_c;
  double S2_d;
};

Code:

struct H h; /* note: no union, just the common header */
char unsigned *src = buffer;
/* note: no dst pointer into union */
size_t specific;

if (room_left < sizeof h) {
  return BAD;
}

memcpy(&h, src, sizeof h);
src += sizeof h;
room_left -= sizeof h;

switch (h.t) { /* note: no awkward reference to "u.s1" */
  case type_1:
    {
      struct S1 s1; /* note: never co-exists with "s2" on the stack */

      specific = sizeof s1; /* note: no awkward subtraction */
      if (room_left < specific) {
        return BAD;
      }
      memcpy(&s1, src, specific);
      src += specific;
      room_left -= specific;
      /* now access s1.S1_i1 */
    }
    return GOOD;

  case type_2:
    {
      struct S2 s2; /* note: never co-exists with "s1" on the stack */

      specific = sizeof s2; /* note: no awkward subtraction */
      if (room_left < specific) {
        return BAD;
      }
      memcpy(&s2, src, specific);
      src += specific;
      room_left -= specific;
      /* now access s2.S2_c, s2.S2_d */
    }
    return GOOD;

  default:
    return BAD;
}


To me, (ii) is much cleaner than (i); the union is not needed.

Of course, I find the type punning approach even better than (ii) :) See
below:

(iii) no union, yes type punning:

struct H *h;
char unsigned *src = buffer;

if (room_left < sizeof *h) {
  return BAD;
}
h = (struct H *)src; /* note: no copying */
src += sizeof *h;
room_left -= sizeof *h;

switch (h->t) {
  case type_1:
    {
      struct S1 *s1;

      specific = sizeof *s1;
      if (room_left < specific) {
        return BAD;
      }
      s1 = (struct S1 *)src; /* note: no copying */
      src += specific;
      room_left -= specific;
      /* now access s1->S1_i1 */
    }
    return GOOD;

and so on.


> Plain 
> casts and "pointer union" accesses are illegal as per the "inadequate 
> type punning" point above.
> 
> 
> 
> "casting away CONST":
> e.g. 
> https://github.com/tianocore/edk2/blob/fcdedafd97c8f18c33a63d26b954e5dbaee81a2b/MdePkg/Library/BaseIoLibIntrinsic/IoLibMmioBuffer.c#L236

In this case, the real problem is with the function prototype /
specification, not the implementation. The implementation follows from
the problematic function semantics -- if you take Buffer as (CONST UINT8
*), then why return the exact same buffer as (UINT8 *)?


> This should be obvious as Undefined Behaviour because memory previously 
> guaranteed to be read-only is returned as a pointer to memory that 
> allows writing,

Note: this is *per se* not undefined behavior. Casting away CONST
(explicitly) in itself is OK. Writing through the pointer is also OK
*if* the pointed-to object was never defined as CONST. Otherwise, the
behavior is undefined. See C99 6.7.3 Type qualifiers, p5:

"If an attempt is made to modify an object defined with a
const-qualified type through use of an lvalue with non-const-qualified
type, the behavior is undefined. If an attempt is made to refer to an
object defined with a volatile-qualified type through use of an lvalue
with non-volatile-qualified type, the behavior is undefined."

I've cited the part about "volatile" to highlight the difference between
"modify" and "refer to". When casting away const, the behavior is only
undefined if you actually try to modify an object that is actually const.

int       i = 2;
int const ci = 3;
int       *pi;
int const *pci;

pci = &i;
pi = (int *)pci; /* fine in itself, but now you're on your own */
*pi = 3;         /* fine, as "i" is not defined const */

pci = &ci;
pi = (int *)pci; /* fine in itself, but now you're on your own */
i = *pi;         /* fine, not modifying "ci" */
*pi = 3;         /* undefined, as "ci" is defined const */


But, yes, the pattern seen under the link is risky practice.


> but for easier lookup, here's the related rule:
> "the left operand has atomic, qualifed, or unqualifed pointer type, and 
> [...] the type pointed to by the left has all the qualifers of the type 
> pointed to by the right"
> C18 (ISO/IEC 9899:2018), 6.5.16.1 (exists since at least C90)

What you quote is from the Constraints of "Simple assignment". Look at
"6.5.4 Cast operators" as well, paragraph 3:

"Conversions that involve pointers, other than where permitted by the
constraints of 6.5.16.1, shall be specified by means of an explicit cast."

In brief, casting away const is not invalid in itself; it just throws
away protections (diagnostics) that the compiler would otherwise be
required to emit. Sometimes it's unavoidable. In most cases we should
avoid it. That might require fixing a few function prototypes.


> "structs with trailing 1-length array"
> e.g. 
> https://github.com/tianocore/edk2/blob/fcdedafd97c8f18c33a63d26b954e5dbaee81a2b/MdePkg/Include/Guid/FileInfo.h#L51
> 
> This is undefined as per:
> "The behavior is undefned in the following circumstances:
> [...]
> — Addition or subtraction of a pointer into, or just beyond, an array 
> object and an integer type produces a result that does not point into, 
> or just beyond, the same array object (6.5.6).
> — Addition or subtraction of a pointer into, or just beyond, an array 
> object and an integer type produces a result that points just beyond the 
> array object and is used as the operand of a unary * operator that is 
> evaluated (6.5.6).
> — Pointers that do not point into, or just beyond, the same array object 
> are subtracted (6.5.6)."
> C18 (ISO/IEC 9899:2018), J.2 (exists since at least C90)
> 
> Same as above, while not all compilers fully support C99, flexible 
> arrays should be support by all reasonably new compilers and allow a 
> legal declaration and usage where this hack is in place. At worst, a 
> macro could be provided to declare a [1] vs a [] array on demand and a 
> requirement be introduced to have a "SIZE_OF_" macro for each such 
> struct, but my personal preference would be to just enforce flexible arrays.

Yes, in C99, the flexible array member was introduced to replace the
"struct hack", which had always been undefined.

It would be nice to remove all toolchains that don't support the
flexible array member, and then to replace all struct hacks with the
flexible array member. I agree.

Unfortunately, there's one extra difficulty (beyond the "expected"
regressions in adjusting code for the fixed element at offset 0): the
struct hack is used in several places in the UEFI 2.8 spec. So that
would have to be updated too.


> "Missing security checks for external data":
> e.g. 
> https://github.com/tianocore/edk2/blob/fcdedafd97c8f18c33a63d26b954e5dbaee81a2b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c#L943
> 
> The given example misses an alignment verification of the resulting 
> pointer (which technically has to be verified *before* casting), as 
> documented here:
> "The behavior is undefined in the following circumstances:
> [...]
> — Conversion between two pointer types produces a result that is 
> incorrectly aligned (6.3.2.3)."
> C18 (ISO/IEC 9899:2018), J.2 (exists since at least C90)

In C99 anyway, "6.3.2.3 Pointers", paragraph 7 writes,

"A pointer to an object or incomplete type may be converted to a pointer
to a different object or incomplete type. If the resulting pointer is
not correctly aligned [...] for the pointed-to type, the behavior is
undefined. [...]"

I find this very impractical and limiting, when accessing RAM (not
MMIO). I prefer if unaligned pointers (into RAM) just work, albeit slow,
perhaps. I believe AARCH64 can be configured to trip a fault vs. work
(but more slowly). On Intel, it just works.

I think we should be given the freedom to "define" the behavior that's
left undefined in this case by the standard.


> There are more such issues throughout the codebase, including missing 
> overflow and (or flawed, see before) bounds checks, however I cannot 
> find such quickly.
> 
> 
> 
> "signed int BIT definitions":
> e.g. 
> https://github.com/tianocore/edk2/blob/fcdedafd97c8f18c33a63d26b954e5dbaee81a2b/MdePkg/Include/Base.h#L348
> 
> Fixing this would be prone to regressions, but I'd like to add it for 
> tracking purposes. Related discussion can be found down the chain here: 
> https://lists.01.org/pipermail/edk2-devel/2018-February/021919.html

I agree about this, in theory. I'm afraid it's impossible to fix in
practice, given the huge amounts of dependent code (esp. out of tree code).


More or less, I'd summarize my opinion as follows:

- we should try to write such new code that conforms to the standard,

- *except* when the standard doesn't give us enough guarantees (i.e.
leaves the behavior undefined) that we need for convenient *in-place*
parsing (from RAM). Integer range checks and buffer boundary checks are
extremely important and we should implement those meticulously, but once
we've made sure our accesses are in range, the compiler should just
follow our pointers wherever they point. We should drag our toolchains
kicking and screaming into a state where they build the source the way
we need, for *in-place* parsing of RAM buffers, through packed
structures. As long as the architectures that we target don't prevent us
from in-place parsing, the toolchains should neither.

Thanks
Laszlo

  reply	other threads:[~2019-09-24 20:26 UTC|newest]

Thread overview: 155+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-17 19:49 [PATCH 00/35] edk2: clean up the usage of standardized (VOID*) typedefs Laszlo Ersek
2019-09-17 19:49 ` [PATCH 01/35] DO NOT APPLY: edk2: turn standard handle types into pointers to non-VOID Laszlo Ersek
2019-09-17 20:06   ` [edk2-devel] " Ni, Ray
2019-09-17 20:22     ` Andrew Fish
2019-09-17 20:28       ` Ni, Ray
2019-09-17 21:07         ` Andrew Fish
2019-09-17 21:11           ` Michael D Kinney
2019-09-18  8:41       ` Laszlo Ersek
2019-09-18 15:16         ` Michael D Kinney
2019-09-18 17:41           ` Laszlo Ersek
2019-09-18 15:55         ` Andrew Fish
2019-09-18 16:16           ` Leif Lindholm
2019-09-18 17:45           ` Laszlo Ersek
2019-09-18  8:36     ` Laszlo Ersek
2019-09-17 19:49 ` [PATCH 02/35] EmbeddedPkg: add missing EFIAPI calling convention specifiers Laszlo Ersek
2019-09-18 17:41   ` Leif Lindholm
2019-09-17 19:49 ` [PATCH 03/35] EmbeddedPkg/AndroidFastbootTransportTcpDxe: fix DestroyChild() call Laszlo Ersek
2019-09-24 10:47   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-26 12:12   ` Laszlo Ersek
2019-09-26 12:16   ` Ard Biesheuvel
2019-09-17 19:49 ` [PATCH 04/35] EmbeddedPkg/Universal/MmcDxe: "fix" CloseProtocol() call in BindingStop() Laszlo Ersek
2019-09-25 15:52   ` Ard Biesheuvel
2019-09-17 19:49 ` [PATCH 05/35] EmulatorPkg/DxeTimerLib: drop superfluous cast Laszlo Ersek
2019-09-17 20:02   ` Ni, Ray
2019-09-20 15:00   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-17 19:49 ` [PATCH 06/35] EmulatorPkg: stop abusing EFI_HANDLE for keystroke notify registration Laszlo Ersek
2019-09-17 20:01   ` Ni, Ray
2019-09-24 10:44   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-17 19:49 ` [PATCH 07/35] MdeModulePkg: fix cast in GetModuleInfoFromHandle() calls Laszlo Ersek
2019-09-19  1:46   ` Dandan Bi
2019-09-24 10:43   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-17 19:49 ` [PATCH 08/35] MdeModulePkg/UefiHiiLib: stop using EFI_HANDLE in place of EFI_HII_HANDLE Laszlo Ersek
2019-09-19  1:46   ` Dandan Bi
2019-09-24 10:49   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-17 19:49 ` [PATCH 09/35] MdeModulePkg: stop abusing EFI_EVENT for protocol notify registration Laszlo Ersek
2019-09-17 20:17   ` Ni, Ray
2019-09-25 16:02   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-26 12:10     ` Laszlo Ersek
2019-09-17 19:49 ` [PATCH 10/35] MdeModulePkg/PlatformVarCleanupLib: fix HiiConstructConfigHdr() call Laszlo Ersek
2019-09-23 11:45   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-24 17:28     ` Laszlo Ersek
2019-09-17 19:49 ` [PATCH 11/35] MdeModulePkg: document workaround for EFI_RUNTIME_EVENT_ENTRY PI spec bug Laszlo Ersek
2019-09-19  1:47   ` Dandan Bi
2019-09-17 19:49 ` [PATCH 12/35] MdeModulePkg: stop abusing EFI_HANDLE for keystroke notify registration Laszlo Ersek
2019-09-17 20:16   ` [edk2-devel] " Ni, Ray
2019-09-19  1:47   ` Dandan Bi
2019-09-24 10:54   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-17 19:49 ` [PATCH 13/35] MdeModulePkg: PEI Core: clean up "AprioriFile" handling in FindFileEx() Laszlo Ersek
2019-09-19  1:46   ` Dandan Bi
2019-09-24 15:40   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-17 19:49 ` [PATCH 14/35] MdeModulePkg: fix UninstallMultipleProtocolInterfaces() calls Laszlo Ersek
2019-09-17 20:16   ` Ni, Ray
2019-09-17 19:49 ` [PATCH 15/35] MdeModulePkg/PiSmmCore: make type punning consistent Laszlo Ersek
2019-09-18  2:38   ` Dong, Eric
2019-09-17 19:49 ` [PATCH 16/35] MdeModulePkg/S3SaveState: cast Position for S3BootScriptLib explicitly Laszlo Ersek
2019-09-19  1:47   ` [edk2-devel] " Dandan Bi
2019-09-17 19:49 ` [PATCH 17/35] MdePkg/DxeServicesLib: remove bogus cast Laszlo Ersek
2019-09-18  4:47   ` [edk2-devel] " Liming Gao
2019-09-24 15:38   ` Philippe Mathieu-Daudé
2019-09-17 19:49 ` [PATCH 18/35] NetworkPkg/DxeNetLib: fix type typo in NetLibGetMacAddress() Laszlo Ersek
2019-09-24 11:00   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-10-08  0:32     ` Siyuan, Fu
2019-10-08 23:36       ` Laszlo Ersek
2019-09-26 12:14   ` Laszlo Ersek
2019-10-03 11:05     ` Laszlo Ersek
2019-10-04 19:18       ` Laszlo Ersek
2019-10-07 18:15   ` Michael D Kinney
2019-09-17 19:49 ` [PATCH 19/35] NetworkPkg: fix CloseProtocol & UninstallMultipleProtocolInterfaces calls Laszlo Ersek
2019-09-26 12:14   ` [edk2-devel] " Laszlo Ersek
2019-09-26 12:42   ` Philippe Mathieu-Daudé
2019-09-30 20:16     ` Laszlo Ersek
2019-10-01  7:18       ` Philippe Mathieu-Daudé
2019-09-27  0:03   ` Siyuan, Fu
2019-09-17 19:49 ` [PATCH 20/35] NetworkPkg/Ip4Dxe: fix NetLibDestroyServiceChild() call Laszlo Ersek
2019-09-23 16:03   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-27  0:04     ` Siyuan, Fu
2019-09-26 12:14   ` Laszlo Ersek
2019-09-17 19:49 ` [PATCH 21/35] NetworkPkg/TcpDxe: fix SockFreeFoo() parameter list Laszlo Ersek
2019-09-23 15:09   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-26 12:14   ` Laszlo Ersek
2019-09-27  0:06   ` Siyuan, Fu
2019-09-17 19:49 ` [PATCH 22/35] OvmfPkg/XenBusDxe: fix UninstallMultipleProtocolInterfaces() call Laszlo Ersek
2019-09-18  9:32   ` Anthony PERARD
2019-09-18 10:30   ` Julien Grall
2019-09-23 15:03   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-17 19:49 ` [PATCH 23/35] OvmfPkg/VirtioNetDxe: fix SignalEvent() call Laszlo Ersek
2019-09-20 14:59   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-26 12:16   ` Laszlo Ersek
2019-09-26 12:17   ` Ard Biesheuvel
2019-09-17 19:49 ` [PATCH 24/35] OvmfPkg/PlatformDxe: fix EFI_HII_HANDLE parameters of internal functions Laszlo Ersek
2019-09-20 14:56   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-25 15:57   ` Ard Biesheuvel
2019-09-17 19:49 ` [PATCH 25/35] OvmfPkg/VideoDxe: document EFI_EDID_OVERRIDE_PROTOCOL.GetEdid() call Laszlo Ersek
2019-09-23 15:59   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-26 12:43     ` Laszlo Ersek
2019-10-04 20:01       ` Laszlo Ersek
2019-09-17 19:49 ` [PATCH 26/35] SecurityPkg: fix UninstallMultipleProtocolInterfaces() calls Laszlo Ersek
2019-09-23  9:55   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-26 12:45   ` Laszlo Ersek
2019-10-03 11:06     ` Laszlo Ersek
2019-10-04  0:05       ` Yao, Jiewen
2019-10-04 13:14       ` Zhang, Chao B
2019-10-04 18:15         ` Laszlo Ersek
2019-10-05 14:28       ` Zhang, Chao B
2019-10-07 18:14         ` Laszlo Ersek
2019-09-17 19:49 ` [PATCH 27/35] SecurityPkg: stop abusing EFI_EVENT for protocol notify registration Laszlo Ersek
2019-09-23  9:56   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-26 12:46   ` Laszlo Ersek
2019-10-03 11:06     ` Laszlo Ersek
2019-10-04  0:05       ` Yao, Jiewen
2019-10-04 13:16       ` Zhang, Chao B
2019-10-05 14:28       ` Zhang, Chao B
2019-09-17 19:49 ` [PATCH 28/35] ShellPkg/UefiShellDriver1CommandsLib: fix parameter list typo Laszlo Ersek
2019-09-24 15:44   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-26  2:46   ` Gao, Zhichao
2019-09-17 19:49 ` [PATCH 29/35] ShellPkg: stop using EFI_HANDLE in place of EFI_HII_HANDLE Laszlo Ersek
2019-09-25 18:04   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-26 11:48     ` Laszlo Ersek
2019-09-26  2:43   ` Gao, Zhichao
2019-09-17 19:49 ` [PATCH 30/35] ShellPkg: stop taking EFI_HANDLE in place of SHELL_FILE_HANDLE Laszlo Ersek
2019-09-23  9:58   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-26  2:53   ` Gao, Zhichao
2019-09-26 12:08     ` Laszlo Ersek
2019-09-26 14:43       ` Gao, Zhichao
2019-09-30 19:52         ` Laszlo Ersek
2019-09-17 19:49 ` [PATCH 31/35] ShellPkg/UefiShellDebug1CommandsLib: fix ShellCloseFile() call Laszlo Ersek
2019-09-23 10:01   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-23 14:28     ` Carsey, Jaben
2019-09-24  1:18       ` Gao, Zhichao
2019-09-17 19:49 ` [PATCH 32/35] ShellPkg/UefiShellLib: clarify workaround for unfixable EdkShell bug Laszlo Ersek
2019-09-26 12:47   ` [edk2-devel] " Laszlo Ersek
2019-09-26 14:05     ` Gao, Zhichao
2019-09-26 14:58     ` Carsey, Jaben
2019-09-17 19:49 ` [PATCH 33/35] StandaloneMmPkg/Core: stop abusing EFI_HANDLE for FwVolHeader tracking Laszlo Ersek
2019-09-26 12:48   ` [edk2-devel] " Laszlo Ersek
2019-10-03 11:10     ` Laszlo Ersek
2019-10-03 11:17       ` Achin Gupta
2019-10-04  0:10       ` Yao, Jiewen
2019-10-04 14:53       ` Achin Gupta
2019-09-17 19:49 ` [PATCH 34/35] UefiPayloadPkg/BlSupportPei: fix MMCONFIG assignment from XSDT Laszlo Ersek
2019-09-23  2:30   ` Guo Dong
2019-09-26 13:17   ` [edk2-devel] " Philippe Mathieu-Daudé
2019-09-17 19:49 ` [PATCH 35/35] UefiPayloadPkg/BlSupportDxe: fix ReserveResourceInGcd() calls Laszlo Ersek
2019-09-23  2:28   ` [edk2-devel] " Guo Dong
2019-09-23 15:08   ` Philippe Mathieu-Daudé
2019-09-23 16:02     ` Guo Dong
2019-09-23 16:04       ` Philippe Mathieu-Daudé
2019-09-24 17:29     ` Laszlo Ersek
2019-09-19  0:32 ` [edk2-devel] [PATCH 00/35] edk2: clean up the usage of standardized (VOID*) typedefs Wu, Hao A
2019-09-23 16:27 ` Marvin Häuser
2019-09-24 20:26   ` Laszlo Ersek [this message]
2019-09-25  8:13     ` Marvin Häuser
2019-09-25 15:54       ` Laszlo Ersek
2019-10-08 23:49 ` Laszlo Ersek
2019-10-09  9:50   ` 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-list 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=06b8b728-e38e-cc64-4499-9733fc993e5d@redhat.com \
    --to=devel@edk2.groups.io \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox