Do not memcpy transparent wire structs on serialization

This removes a serialization optimization where structs could be
memcpy'ed. memcpy is still used for deserialization of structs.

Structs may contain padding bytes which when copied can leak
uninitialized data across a trusted boundary. In Chrome, this
means previously-written or uninitialized bytes in the GPU process
could leak into the Renderer process.

In the future, we may be able to bring this back by introducing
a concept of safe-to-memcpy structs, or by forking the code so
that Renderer->GPU process uses the unsafe memcpy, and
GPU->Renderer uses to the safe member-by-member version.

An alternative might be to ensure that everything returned from
the WebGPU API has initialized padding, but this invariant is not
trivial to guarantee.

Fixed: chromium:1359098
Change-Id: I91151251d1ab999e0f5552e1efccc472e451cc10
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/102461
Reviewed-by: Brandon Jones <bajones@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
Austin Eng 2022-09-16 14:14:08 +00:00 committed by Dawn LUCI CQ
parent 1fe74e5c0b
commit ba68620f6f
1 changed files with 4 additions and 7 deletions

View File

@ -64,13 +64,10 @@
{%- set Optional = "Optional" if member.optional else "" -%}
WIRE_TRY(provider.Get{{Optional}}Id({{in}}, &{{out}}));
{%- elif member.type.category == "structure" -%}
{%- if member.type.is_wire_transparent -%}
static_assert(sizeof({{out}}) == sizeof({{in}}), "Serialize memcpy size must match.");
memcpy(&{{out}}, &{{in}}, {{member_transfer_sizeof(member)}});
{%- else -%}
{%- set Provider = ", provider" if member.type.may_have_dawn_object else "" -%}
WIRE_TRY({{as_cType(member.type.name)}}Serialize({{in}}, &{{out}}, buffer{{Provider}}));
{%- endif -%}
//* Do not memcpy or we may serialize padding bytes which can leak information across a
//* trusted boundary.
{%- set Provider = ", provider" if member.type.may_have_dawn_object else "" -%}
WIRE_TRY({{as_cType(member.type.name)}}Serialize({{in}}, &{{out}}, buffer{{Provider}}));
{%- else -%}
{{out}} = {{in}};
{%- endif -%}