[fidl] Fix arena destruction ordering issue

For messages with handles, it is possible for the handles to be
destructed after the arena-stored handle buffer is destructed. This
is a use-after-free, which is fixed by this CL.

Fixed: 102974
Change-Id: I5a703729fb9022c07d8a31686c37feff0c56fe3d
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/693425
Commit-Queue: Benjamin Prosnitz <bprosnitz@google.com>
Reviewed-by: Yifei Teng <yifeit@google.com>
diff --git a/sdk/lib/fidl_driver/tests/transport/wire_async_zircon_handle_test.cc b/sdk/lib/fidl_driver/tests/transport/wire_async_zircon_handle_test.cc
index b8419ea..96d0d0f 100644
--- a/sdk/lib/fidl_driver/tests/transport/wire_async_zircon_handle_test.cc
+++ b/sdk/lib/fidl_driver/tests/transport/wire_async_zircon_handle_test.cc
@@ -26,7 +26,19 @@
   }
 };
 
-TEST(DriverTransport, WireSendZirconHandleAsync) {
+class CreateNewHandlesTestServer : public fdf::WireServer<test_transport::SendZirconHandleTest> {
+  void SendZirconHandle(SendZirconHandleRequestView request, fdf::Arena& arena,
+                        SendZirconHandleCompleter::Sync& completer) override {
+    ASSERT_TRUE(request->h.is_valid());
+
+    zx::event ev;
+    ASSERT_OK(zx::event::create(0, &ev));
+    completer.buffer(arena).Reply(std::move(ev));
+  }
+};
+
+template <typename TestServerType, bool HandlesEqual>
+void TestImpl() {
   fidl_driver_testing::ScopedFakeDriver driver;
 
   libsync::Completion dispatcher_shutdown;
@@ -48,25 +60,32 @@
 
   fdf::WireSharedClient<test_transport::SendZirconHandleTest> client;
   client.Bind(std::move(client_end), dispatcher->get());
-  auto arena = fdf::Arena::Create(0, "");
-  ASSERT_OK(arena.status_value());
-
-  zx::event ev;
-  zx::event::create(0, &ev);
-  zx_handle_t handle = ev.get();
-
   sync_completion_t done;
-  client.buffer(*arena)
-      ->SendZirconHandle(std::move(ev))
-      .ThenExactlyOnce(
-          [&done,
-           handle](fdf::WireUnownedResult<::test_transport::SendZirconHandleTest::SendZirconHandle>&
-                       result) {
-            ASSERT_OK(result.status());
-            ASSERT_TRUE(result->h.is_valid());
-            ASSERT_EQ(handle, result->h.get());
-            sync_completion_signal(&done);
-          });
+
+  // Use a scope block to close the local arena reference after the message is sent.
+  // This ensures that handles stored in the arena are closed before the arena is destructed.
+  {
+    auto arena = fdf::Arena::Create(0, "");
+    ASSERT_OK(arena.status_value());
+
+    zx::event ev;
+    zx::event::create(0, &ev);
+    zx_handle_t handle = ev.get();
+
+    client.buffer(*arena)
+        ->SendZirconHandle(std::move(ev))
+        .ThenExactlyOnce(
+            [&done, handle](
+                fdf::WireUnownedResult<::test_transport::SendZirconHandleTest::SendZirconHandle>&
+                    result) {
+              ASSERT_OK(result.status());
+              ASSERT_TRUE(result->h.is_valid());
+              if (HandlesEqual) {
+                ASSERT_EQ(handle, result->h.get());
+              }
+              sync_completion_signal(&done);
+            });
+  }
 
   ASSERT_OK(sync_completion_wait(&done, ZX_TIME_INFINITE));
 
@@ -74,6 +93,16 @@
   ASSERT_OK(dispatcher_shutdown.Wait());
 }
 
+TEST(DriverTransport, WireSendZirconHandleAsync) { TestImpl<TestServer, true>(); }
+
+// Instead of echoing the handles, create new handles.
+// This ensures CloseHandles() is called on the request object before the fdf::Arena
+// is destructed. In the case of echo, the handle is moved out of the request object
+// so this corner case is never encountered. (See fxbug.dev/102974 for motivation).
+TEST(DriverTransport, WireSendNewZirconHandleAsync) {
+  TestImpl<CreateNewHandlesTestServer, false>();
+}
+
 TEST(DriverTransport, WireSendZirconHandleEncodeErrorShouldCloseHandle) {
   fidl_driver_testing::ScopedFakeDriver driver;
   libsync::Completion dispatcher_shutdown;
diff --git a/tools/fidl/fidlgen_llcpp/codegen/driver/fragment_method_unownedresult.tmpl b/tools/fidl/fidlgen_llcpp/codegen/driver/fragment_method_unownedresult.tmpl
index c17ad0c..e9b73c6 100644
--- a/tools/fidl/fidlgen_llcpp/codegen/driver/fragment_method_unownedresult.tmpl
+++ b/tools/fidl/fidlgen_llcpp/codegen/driver/fragment_method_unownedresult.tmpl
@@ -94,8 +94,8 @@
     }
 
    private:
-    ::fidl::internal::DecodedValue<{{ .WireTransactionalResponse }}> decoded_;
     ::fdf::Arena arena_;
+    ::fidl::internal::DecodedValue<{{ .WireTransactionalResponse }}> decoded_;
     {{- if and .Result .HasWireResultBase }}
       std::optional<{{ .WireResultBase }}> result_ = std::nullopt;
     {{- end }}
diff --git a/tools/fidl/fidlgen_llcpp/codegen/fragment_protocol_dispatcher.tmpl b/tools/fidl/fidlgen_llcpp/codegen/fragment_protocol_dispatcher.tmpl
index e5bb599..23a3f70 100644
--- a/tools/fidl/fidlgen_llcpp/codegen/fragment_protocol_dispatcher.tmpl
+++ b/tools/fidl/fidlgen_llcpp/codegen/fragment_protocol_dispatcher.tmpl
@@ -35,6 +35,11 @@
     { {{ .OrdinalName }},
       [](void* interface, ::fidl::IncomingMessage&& msg,
         internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+        {{- if eq .Transport.Name "Driver" }}
+        {{/* |arena| needs to be declared before |decoded| so that |decoded| is destructed first.
+             This is for the case where handles used in |decoded| are stored in |arena|. */}}
+        fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
+        {{- end }}
         {{- if .RequestArgs }}
         ::fidl::unstable::DecodedMessage<{{ .WireTransactionalRequest }}> decoded{std::move(msg)};
         if (unlikely(!decoded.ok())) {
@@ -47,7 +52,6 @@
         {{- end }}
         {{ .WireCompleter }}::Sync completer(txn);
         {{- if eq .Transport.Name "Driver" }}
-        fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
         reinterpret_cast<{{ $.WireServer }}*>(interface)->{{ .Name }}(
             primary, arena, completer);
         {{- else }}
diff --git a/tools/fidl/fidlgen_llcpp/goldens/driver_handle_driver_wire_messaging.cc.golden b/tools/fidl/fidlgen_llcpp/goldens/driver_handle_driver_wire_messaging.cc.golden
index b40b286..3300141 100644
--- a/tools/fidl/fidlgen_llcpp/goldens/driver_handle_driver_wire_messaging.cc.golden
+++ b/tools/fidl/fidlgen_llcpp/goldens/driver_handle_driver_wire_messaging.cc.golden
@@ -77,13 +77,13 @@
         ::test_driverhandle::kHandlesInProtocol_SendHandles_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalRequest<::test_driverhandle::HandlesInProtocol::SendHandles>> decoded{std::move(msg)};
           if (unlikely(!decoded.ok())) {
             return ::fidl::Status{decoded};
           }
           auto* primary = &decoded.PrimaryObject()->body;
           ::fidl::internal::WireCompleter<::test_driverhandle::HandlesInProtocol::SendHandles>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_driverhandle::HandlesInProtocol>*>(interface)->SendHandles(
               primary, arena, completer);
           return ::fidl::Status::Ok();
diff --git a/tools/fidl/fidlgen_llcpp/goldens/driver_one_way_driver_wire_messaging.cc.golden b/tools/fidl/fidlgen_llcpp/goldens/driver_one_way_driver_wire_messaging.cc.golden
index dad824e..51e400d 100644
--- a/tools/fidl/fidlgen_llcpp/goldens/driver_one_way_driver_wire_messaging.cc.golden
+++ b/tools/fidl/fidlgen_llcpp/goldens/driver_one_way_driver_wire_messaging.cc.golden
@@ -77,13 +77,13 @@
         ::test_driveroneway::kOneWay_Send_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalRequest<::test_driveroneway::OneWay::Send>> decoded{std::move(msg)};
           if (unlikely(!decoded.ok())) {
             return ::fidl::Status{decoded};
           }
           auto* primary = &decoded.PrimaryObject()->body;
           ::fidl::internal::WireCompleter<::test_driveroneway::OneWay::Send>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_driveroneway::OneWay>*>(interface)->Send(
               primary, arena, completer);
           return ::fidl::Status::Ok();
diff --git a/tools/fidl/fidlgen_llcpp/goldens/driver_two_way_driver_wire_messaging.cc.golden b/tools/fidl/fidlgen_llcpp/goldens/driver_two_way_driver_wire_messaging.cc.golden
index 5447aea..47218369 100644
--- a/tools/fidl/fidlgen_llcpp/goldens/driver_two_way_driver_wire_messaging.cc.golden
+++ b/tools/fidl/fidlgen_llcpp/goldens/driver_two_way_driver_wire_messaging.cc.golden
@@ -79,13 +79,13 @@
         ::test_drivertwoway::kTwoWay_Add_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::unstable::DecodedMessage<::fidl::internal::TransactionalRequest<::test_drivertwoway::TwoWay::Add>> decoded{std::move(msg)};
           if (unlikely(!decoded.ok())) {
             return ::fidl::Status{decoded};
           }
           auto* primary = &decoded.PrimaryObject()->body;
           ::fidl::internal::WireCompleter<::test_drivertwoway::TwoWay::Add>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_drivertwoway::TwoWay>*>(interface)->Add(
               primary, arena, completer);
           return ::fidl::Status::Ok();
diff --git a/tools/fidl/fidlgen_llcpp/goldens/driver_two_way_driver_wire_messaging.h.golden b/tools/fidl/fidlgen_llcpp/goldens/driver_two_way_driver_wire_messaging.h.golden
index e958ab4..976f813a 100644
--- a/tools/fidl/fidlgen_llcpp/goldens/driver_two_way_driver_wire_messaging.h.golden
+++ b/tools/fidl/fidlgen_llcpp/goldens/driver_two_way_driver_wire_messaging.h.golden
@@ -346,8 +346,8 @@
   }
 
  private:
-  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_drivertwoway::TwoWay::Add>> decoded_;
   ::fdf::Arena arena_;
+  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_drivertwoway::TwoWay::Add>> decoded_;
 };
 template <>
 class ::fidl::internal::WireEventHandlerInterface<::test_drivertwoway::TwoWay> : public ::fidl::internal::BaseEventHandlerInterface {
diff --git a/tools/fidl/fidlgen_llcpp/goldens/unknown_interactions_driver_wire_messaging.cc.golden b/tools/fidl/fidlgen_llcpp/goldens/unknown_interactions_driver_wire_messaging.cc.golden
index 34defc2..4cae9f19 100644
--- a/tools/fidl/fidlgen_llcpp/goldens/unknown_interactions_driver_wire_messaging.cc.golden
+++ b/tools/fidl/fidlgen_llcpp/goldens/unknown_interactions_driver_wire_messaging.cc.golden
@@ -362,10 +362,10 @@
         ::test_unknowninteractions::kUnknownInteractionsDriverProtocol_StrictOneWay_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsDriverProtocol::StrictOneWay> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsDriverProtocol::StrictOneWay>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsDriverProtocol>*>(interface)->StrictOneWay(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -375,10 +375,10 @@
         ::test_unknowninteractions::kUnknownInteractionsDriverProtocol_FlexibleOneWay_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsDriverProtocol::FlexibleOneWay> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsDriverProtocol::FlexibleOneWay>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsDriverProtocol>*>(interface)->FlexibleOneWay(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -388,10 +388,10 @@
         ::test_unknowninteractions::kUnknownInteractionsDriverProtocol_StrictTwoWay_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsDriverProtocol::StrictTwoWay> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsDriverProtocol::StrictTwoWay>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsDriverProtocol>*>(interface)->StrictTwoWay(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -401,10 +401,10 @@
         ::test_unknowninteractions::kUnknownInteractionsDriverProtocol_StrictTwoWayErr_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsDriverProtocol::StrictTwoWayErr> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsDriverProtocol::StrictTwoWayErr>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsDriverProtocol>*>(interface)->StrictTwoWayErr(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -414,10 +414,10 @@
         ::test_unknowninteractions::kUnknownInteractionsDriverProtocol_FlexibleTwoWay_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsDriverProtocol::FlexibleTwoWay> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsDriverProtocol::FlexibleTwoWay>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsDriverProtocol>*>(interface)->FlexibleTwoWay(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -427,10 +427,10 @@
         ::test_unknowninteractions::kUnknownInteractionsDriverProtocol_FlexibleTwoWayErr_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsDriverProtocol::FlexibleTwoWayErr> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsDriverProtocol::FlexibleTwoWayErr>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsDriverProtocol>*>(interface)->FlexibleTwoWayErr(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -786,10 +786,10 @@
         ::test_unknowninteractions::kUnknownInteractionsClosedDriverProtocol_StrictOneWay_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol::StrictOneWay> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol::StrictOneWay>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol>*>(interface)->StrictOneWay(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -799,10 +799,10 @@
         ::test_unknowninteractions::kUnknownInteractionsClosedDriverProtocol_StrictTwoWay_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol::StrictTwoWay> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol::StrictTwoWay>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol>*>(interface)->StrictTwoWay(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -812,10 +812,10 @@
         ::test_unknowninteractions::kUnknownInteractionsClosedDriverProtocol_StrictTwoWayErr_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol::StrictTwoWayErr> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol::StrictTwoWayErr>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol>*>(interface)->StrictTwoWayErr(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -1154,10 +1154,10 @@
         ::test_unknowninteractions::kUnknownInteractionsAjarDriverProtocol_StrictOneWay_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::StrictOneWay> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::StrictOneWay>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol>*>(interface)->StrictOneWay(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -1167,10 +1167,10 @@
         ::test_unknowninteractions::kUnknownInteractionsAjarDriverProtocol_FlexibleOneWay_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::FlexibleOneWay> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::FlexibleOneWay>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol>*>(interface)->FlexibleOneWay(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -1180,10 +1180,10 @@
         ::test_unknowninteractions::kUnknownInteractionsAjarDriverProtocol_StrictTwoWay_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::StrictTwoWay> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::StrictTwoWay>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol>*>(interface)->StrictTwoWay(
               primary, arena, completer);
           return ::fidl::Status::Ok();
@@ -1193,10 +1193,10 @@
         ::test_unknowninteractions::kUnknownInteractionsAjarDriverProtocol_StrictTwoWayErr_Ordinal,
         [](void* interface, ::fidl::IncomingMessage&& msg,
            internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
+          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           ::fidl::WireRequest<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::StrictTwoWayErr> empty_request;
           auto* primary = &empty_request;
           ::fidl::internal::WireCompleter<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::StrictTwoWayErr>::Sync completer(txn);
-          fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
           reinterpret_cast<::fdf::WireServer<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol>*>(interface)->StrictTwoWayErr(
               primary, arena, completer);
           return ::fidl::Status::Ok();
diff --git a/tools/fidl/fidlgen_llcpp/goldens/unknown_interactions_driver_wire_messaging.h.golden b/tools/fidl/fidlgen_llcpp/goldens/unknown_interactions_driver_wire_messaging.h.golden
index dd7e313..e991353 100644
--- a/tools/fidl/fidlgen_llcpp/goldens/unknown_interactions_driver_wire_messaging.h.golden
+++ b/tools/fidl/fidlgen_llcpp/goldens/unknown_interactions_driver_wire_messaging.h.golden
@@ -1112,8 +1112,8 @@
   }
 
  private:
-  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsDriverProtocol::StrictTwoWay>> decoded_;
   ::fdf::Arena arena_;
+  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsDriverProtocol::StrictTwoWay>> decoded_;
 };
 
 template <>
@@ -1170,8 +1170,8 @@
   }
 
  private:
-  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsDriverProtocol::StrictTwoWayErr>> decoded_;
   ::fdf::Arena arena_;
+  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsDriverProtocol::StrictTwoWayErr>> decoded_;
   std::optional<::fitx::result<int32_t>> result_ = std::nullopt;
 };
 
@@ -1202,8 +1202,8 @@
   }
 
  private:
-  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsDriverProtocol::FlexibleTwoWay>> decoded_;
   ::fdf::Arena arena_;
+  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsDriverProtocol::FlexibleTwoWay>> decoded_;
 };
 
 template <>
@@ -1260,8 +1260,8 @@
   }
 
  private:
-  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsDriverProtocol::FlexibleTwoWayErr>> decoded_;
   ::fdf::Arena arena_;
+  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsDriverProtocol::FlexibleTwoWayErr>> decoded_;
   std::optional<::fitx::result<int32_t>> result_ = std::nullopt;
 };
 template <>
@@ -2076,8 +2076,8 @@
   }
 
  private:
-  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol::StrictTwoWay>> decoded_;
   ::fdf::Arena arena_;
+  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol::StrictTwoWay>> decoded_;
 };
 
 template <>
@@ -2134,8 +2134,8 @@
   }
 
  private:
-  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol::StrictTwoWayErr>> decoded_;
   ::fdf::Arena arena_;
+  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsClosedDriverProtocol::StrictTwoWayErr>> decoded_;
   std::optional<::fitx::result<int32_t>> result_ = std::nullopt;
 };
 template <>
@@ -2941,8 +2941,8 @@
   }
 
  private:
-  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::StrictTwoWay>> decoded_;
   ::fdf::Arena arena_;
+  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::StrictTwoWay>> decoded_;
 };
 
 template <>
@@ -2999,8 +2999,8 @@
   }
 
  private:
-  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::StrictTwoWayErr>> decoded_;
   ::fdf::Arena arena_;
+  ::fidl::internal::DecodedValue<::fidl::internal::TransactionalResponse<::test_unknowninteractions::UnknownInteractionsAjarDriverProtocol::StrictTwoWayErr>> decoded_;
   std::optional<::fitx::result<int32_t>> result_ = std::nullopt;
 };
 template <>