From 31a3ea2fb1cbafdf37b650e2df833f8235fc5ece Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Thu, 29 May 2025 19:22:10 +0000 Subject: [PATCH] Bug 1966936 - Switch various IPC IDs to 64-bits, r=ipc-reviewers,mccr8,jld a=RyanVM This changes a few IDs which have historically been 32-bit integers to instead be 64-bit integers, reducing the chance of the value overflowing. Differential Revision: https://phabricator.services.mozilla.com/D250502 --- dom/cache/Manager.cpp | 14 +- dom/cache/Manager.h | 5 +- dom/canvas/OffscreenCanvas.cpp | 2 +- dom/canvas/OffscreenCanvasDisplayHelper.cpp | 2 +- dom/canvas/OffscreenCanvasDisplayHelper.h | 6 +- dom/canvas/TexUnpackBlob.cpp | 2 +- .../webrtc/jsapi/WebrtcGlobalInformation.cpp | 8 +- gfx/ipc/CanvasManagerChild.cpp | 2 +- gfx/ipc/CanvasManagerChild.h | 2 +- gfx/ipc/CanvasManagerParent.cpp | 6 +- gfx/ipc/CanvasManagerParent.h | 6 +- gfx/ipc/PCanvasManager.ipdl | 3 +- gfx/layers/ipc/CanvasChild.cpp | 2 +- gfx/layers/ipc/CanvasTranslator.cpp | 2 +- gfx/layers/ipc/CanvasTranslator.h | 2 +- gfx/layers/ipc/LayersSurfaces.ipdlh | 3 +- gfx/layers/ipc/PCanvas.ipdl | 3 +- ipc/chromium/src/base/pickle.cc | 1 + ipc/chromium/src/base/pickle.h | 2 + ipc/chromium/src/chrome/common/ipc_message.cc | 5 +- ipc/chromium/src/chrome/common/ipc_message.h | 52 ++--- ipc/glue/Endpoint.cpp | 2 +- ipc/glue/Endpoint.h | 4 +- ipc/glue/MessageChannel.cpp | 84 ++++---- ipc/glue/MessageChannel.h | 17 +- ipc/glue/ProtocolMessageUtils.h | 17 +- ipc/glue/ProtocolUtils.cpp | 112 +++++----- ipc/glue/ProtocolUtils.h | 42 ++-- ipc/glue/Shmem.cpp | 9 +- ipc/glue/Shmem.h | 8 +- ipc/ipdl/ipdl/lower.py | 194 +++++++----------- tools/fuzzing/ipc/IPCFuzzController.cpp | 72 ++++--- tools/fuzzing/ipc/IPCFuzzController.h | 13 +- xpcom/threads/nsThreadUtils.cpp | 4 +- 34 files changed, 346 insertions(+), 362 deletions(-) diff --git a/dom/cache/Manager.cpp b/dom/cache/Manager.cpp index b176969d98ef..c3b598f29947 100644 --- a/dom/cache/Manager.cpp +++ b/dom/cache/Manager.cpp @@ -370,14 +370,16 @@ class Manager::Factory { } #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED - static void RecordMayNotDeleteCSCP(int32_t aCacheStreamControlParentId) { + static void RecordMayNotDeleteCSCP( + mozilla::ipc::ActorId aCacheStreamControlParentId) { if (sFactory) { sFactory->mPotentiallyUnreleasedCSCP.AppendElement( aCacheStreamControlParentId); } } - static void RecordHaveDeletedCSCP(int32_t aCacheStreamControlParentId) { + static void RecordHaveDeletedCSCP( + mozilla::ipc::ActorId aCacheStreamControlParentId) { if (sFactory) { sFactory->mPotentiallyUnreleasedCSCP.RemoveElement( aCacheStreamControlParentId); @@ -519,7 +521,7 @@ class Manager::Factory { // trigger the deletion of the factory while still executing this loop. bool mInSyncAbortOrShutdown; - nsTArray mPotentiallyUnreleasedCSCP; + nsTArray mPotentiallyUnreleasedCSCP; }; // static @@ -1691,11 +1693,13 @@ bool Manager::IsShutdownAllComplete() { } #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED -void Manager::RecordMayNotDeleteCSCP(int32_t aCacheStreamControlParentId) { +void Manager::RecordMayNotDeleteCSCP( + mozilla::ipc::ActorId aCacheStreamControlParentId) { Factory::RecordMayNotDeleteCSCP(aCacheStreamControlParentId); } -void Manager::RecordHaveDeletedCSCP(int32_t aCacheStreamControlParentId) { +void Manager::RecordHaveDeletedCSCP( + mozilla::ipc::ActorId aCacheStreamControlParentId) { Factory::RecordHaveDeletedCSCP(aCacheStreamControlParentId); } #endif diff --git a/dom/cache/Manager.h b/dom/cache/Manager.h index 3908f0680314..cd500bcfc995 100644 --- a/dom/cache/Manager.h +++ b/dom/cache/Manager.h @@ -199,8 +199,9 @@ class Manager final : public SafeRefCounted, public Stringifyable { nsCOMPtr&& aBodyStream); #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED - void RecordMayNotDeleteCSCP(int32_t aCacheStreamControlParentId); - void RecordHaveDeletedCSCP(int32_t aCacheStreamControlParentId); + void RecordMayNotDeleteCSCP( + mozilla::ipc::ActorId aCacheStreamControlParentId); + void RecordHaveDeletedCSCP(mozilla::ipc::ActorId aCacheStreamControlParentId); #endif private: diff --git a/dom/canvas/OffscreenCanvas.cpp b/dom/canvas/OffscreenCanvas.cpp index fc7bf81be655..8e0167133b9a 100644 --- a/dom/canvas/OffscreenCanvas.cpp +++ b/dom/canvas/OffscreenCanvas.cpp @@ -227,7 +227,7 @@ void OffscreenCanvas::GetContext( return; } - Maybe childId; + Maybe childId; MOZ_ASSERT(mCurrentContext); switch (mCurrentContextType) { diff --git a/dom/canvas/OffscreenCanvasDisplayHelper.cpp b/dom/canvas/OffscreenCanvasDisplayHelper.cpp index 6ca83129d045..d23421ef153d 100644 --- a/dom/canvas/OffscreenCanvasDisplayHelper.cpp +++ b/dom/canvas/OffscreenCanvasDisplayHelper.cpp @@ -90,7 +90,7 @@ RefPtr OffscreenCanvasDisplayHelper::GetImageContainer() void OffscreenCanvasDisplayHelper::UpdateContext( OffscreenCanvas* aOffscreenCanvas, RefPtr&& aWorkerRef, - CanvasContextType aType, const Maybe& aChildId) { + CanvasContextType aType, const Maybe& aChildId) { RefPtr imageContainer = MakeRefPtr( layers::ImageUsageType::OffscreenCanvas, diff --git a/dom/canvas/OffscreenCanvasDisplayHelper.h b/dom/canvas/OffscreenCanvasDisplayHelper.h index fc3091c6a0e6..54c4f1c77b8b 100644 --- a/dom/canvas/OffscreenCanvasDisplayHelper.h +++ b/dom/canvas/OffscreenCanvasDisplayHelper.h @@ -11,6 +11,7 @@ #include "GLContextTypes.h" #include "mozilla/dom/CanvasRenderingContextHelper.h" #include "mozilla/gfx/Point.h" +#include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/layers/LayersTypes.h" #include "mozilla/Maybe.h" #include "mozilla/Mutex.h" @@ -45,7 +46,8 @@ class OffscreenCanvasDisplayHelper final { void UpdateContext(OffscreenCanvas* aOffscreenCanvas, RefPtr&& aWorkerRef, - CanvasContextType aType, const Maybe& aChildId); + CanvasContextType aType, + const Maybe& aChildId); void FlushForDisplay(); @@ -83,7 +85,7 @@ class OffscreenCanvasDisplayHelper final { OffscreenCanvasDisplayData mData MOZ_GUARDED_BY(mMutex); CanvasContextType mType MOZ_GUARDED_BY(mMutex) = CanvasContextType::NoContext; Maybe mContextManagerId MOZ_GUARDED_BY(mMutex); - Maybe mContextChildId MOZ_GUARDED_BY(mMutex); + Maybe mContextChildId MOZ_GUARDED_BY(mMutex); const mozilla::layers::ImageContainer::ProducerID mImageProducerID; mozilla::layers::ImageContainer::FrameID mLastFrameID MOZ_GUARDED_BY(mMutex) = 0; diff --git a/dom/canvas/TexUnpackBlob.cpp b/dom/canvas/TexUnpackBlob.cpp index b996668fc165..f0c8e11f8d6a 100644 --- a/dom/canvas/TexUnpackBlob.cpp +++ b/dom/canvas/TexUnpackBlob.cpp @@ -1032,7 +1032,7 @@ bool TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec, // process as the WebGL canvas. Query it for the surface. const auto& sdc = sd.get_SurfaceDescriptorCanvasSurface(); uint32_t managerId = sdc.managerId(); - int32_t canvasId = sdc.canvasId(); + mozilla::ipc::ActorId canvasId = sdc.canvasId(); uintptr_t surfaceId = sdc.surfaceId(); surf = gfx::CanvasManagerParent::GetCanvasSurface( webgl->GetContentId(), managerId, canvasId, surfaceId); diff --git a/dom/media/webrtc/jsapi/WebrtcGlobalInformation.cpp b/dom/media/webrtc/jsapi/WebrtcGlobalInformation.cpp index 0727a580be70..152cfcc59a51 100644 --- a/dom/media/webrtc/jsapi/WebrtcGlobalInformation.cpp +++ b/dom/media/webrtc/jsapi/WebrtcGlobalInformation.cpp @@ -159,10 +159,12 @@ GetStatsPromiseForThisProcess(const nsAString& aPcIdFilter) { std::move(UnwrapUniquePtrs)); } -static std::map>& GetWebrtcGlobalLogStash() { - static StaticAutoPtr>> sStash; +static std::map>& +GetWebrtcGlobalLogStash() { + static StaticAutoPtr>> + sStash; if (!sStash) { - sStash = new std::map>(); + sStash = new std::map>(); ClearOnShutdown(&sStash); } return *sStash; diff --git a/gfx/ipc/CanvasManagerChild.cpp b/gfx/ipc/CanvasManagerChild.cpp index dc6377e0b899..01bc1d1d9dec 100644 --- a/gfx/ipc/CanvasManagerChild.cpp +++ b/gfx/ipc/CanvasManagerChild.cpp @@ -229,7 +229,7 @@ layers::ActiveResourceTracker* CanvasManagerChild::GetActiveResourceTracker() { } already_AddRefed CanvasManagerChild::GetSnapshot( - uint32_t aManagerId, int32_t aProtocolId, + uint32_t aManagerId, ActorId aProtocolId, const Maybe& aOwnerId, const Maybe& aCommandEncoderId, SurfaceFormat aFormat, bool aPremultiply, bool aYFlip) { diff --git a/gfx/ipc/CanvasManagerChild.h b/gfx/ipc/CanvasManagerChild.h index aebb7fbc6044..9b7189dc220d 100644 --- a/gfx/ipc/CanvasManagerChild.h +++ b/gfx/ipc/CanvasManagerChild.h @@ -38,7 +38,7 @@ class CanvasManagerChild final : public PCanvasManagerChild { uint32_t aId); uint32_t Id() const { return mId; } already_AddRefed GetSnapshot( - uint32_t aManagerId, int32_t aProtocolId, + uint32_t aManagerId, ActorId aProtocolId, const Maybe& aOwnerId, const Maybe& aCommandEncoderId, SurfaceFormat aFormat, bool aPremultiply, bool aYFlip); diff --git a/gfx/ipc/CanvasManagerParent.cpp b/gfx/ipc/CanvasManagerParent.cpp index 4e08933814b5..c91ee0874f8c 100644 --- a/gfx/ipc/CanvasManagerParent.cpp +++ b/gfx/ipc/CanvasManagerParent.cpp @@ -178,7 +178,7 @@ CanvasManagerParent::AllocPCanvasParent() { } mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot( - const uint32_t& aManagerId, const int32_t& aProtocolId, + const uint32_t& aManagerId, const ActorId& aProtocolId, const Maybe& aOwnerId, const Maybe& aCommandEncoderId, webgl::FrontBufferSnapshotIpc* aResult) { @@ -240,7 +240,7 @@ mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot( } /* static */ mozilla::ipc::IProtocol* CanvasManagerParent::GetCanvasActor( - dom::ContentParentId aContentId, uint32_t aManagerId, int32_t aCanvasId) { + dom::ContentParentId aContentId, uint32_t aManagerId, ActorId aCanvasId) { IProtocol* actor = nullptr; for (CanvasManagerParent* i : sManagers) { if (i->mContentId == aContentId && i->mId == aManagerId) { @@ -253,7 +253,7 @@ mozilla::ipc::IPCResult CanvasManagerParent::RecvGetSnapshot( /* static */ already_AddRefed CanvasManagerParent::GetCanvasSurface(dom::ContentParentId aContentId, - uint32_t aManagerId, int32_t aCanvasId, + uint32_t aManagerId, ActorId aCanvasId, uintptr_t aSurfaceId) { IProtocol* actor = GetCanvasActor(aContentId, aManagerId, aCanvasId); if (!actor) { diff --git a/gfx/ipc/CanvasManagerParent.h b/gfx/ipc/CanvasManagerParent.h index 623c932f8498..0149eaf8e495 100644 --- a/gfx/ipc/CanvasManagerParent.h +++ b/gfx/ipc/CanvasManagerParent.h @@ -47,16 +47,16 @@ class CanvasManagerParent final : public PCanvasManagerParent { mozilla::ipc::IPCResult RecvInitialize(const uint32_t& aId); mozilla::ipc::IPCResult RecvGetSnapshot( - const uint32_t& aManagerId, const int32_t& aProtocolId, + const uint32_t& aManagerId, const ActorId& aProtocolId, const Maybe& aOwnerId, const Maybe& aCommandEncoderId, webgl::FrontBufferSnapshotIpc* aResult); static mozilla::ipc::IProtocol* GetCanvasActor( - dom::ContentParentId aContentId, uint32_t aManagerId, int32_t aCanvasId); + dom::ContentParentId aContentId, uint32_t aManagerId, ActorId aCanvasId); static already_AddRefed GetCanvasSurface( - dom::ContentParentId aContentId, uint32_t aManagerId, int32_t aCanvasId, + dom::ContentParentId aContentId, uint32_t aManagerId, ActorId aCanvasId, uintptr_t aSurfaceId); private: diff --git a/gfx/ipc/PCanvasManager.ipdl b/gfx/ipc/PCanvasManager.ipdl index 07882b837cf3..b90f087b89f1 100644 --- a/gfx/ipc/PCanvasManager.ipdl +++ b/gfx/ipc/PCanvasManager.ipdl @@ -10,6 +10,7 @@ include protocol PCanvas; include protocol PWebGL; include protocol PWebGPU; +using mozilla::ipc::ActorId from "mozilla/ipc/ProtocolUtils.h"; using mozilla::layers::RemoteTextureOwnerId from "mozilla/layers/LayersTypes.h"; using mozilla::webgl::FrontBufferSnapshotIpc from "mozilla/dom/WebGLIpdl.h"; using mozilla::webgpu::RawId from "mozilla/webgpu/WebGPUTypes.h"; @@ -46,7 +47,7 @@ parent: // intended to be used by the main thread in the content process to block // reading without having to block on the worker thread that owns the context // instance. - sync GetSnapshot(uint32_t aManagerId, int32_t aProtocolId, RemoteTextureOwnerId? ownerId, RawId? commandEncoderId) returns (FrontBufferSnapshotIpc ret); + sync GetSnapshot(uint32_t aManagerId, ActorId aProtocolId, RemoteTextureOwnerId? ownerId, RawId? commandEncoderId) returns (FrontBufferSnapshotIpc ret); }; } // gfx diff --git a/gfx/layers/ipc/CanvasChild.cpp b/gfx/layers/ipc/CanvasChild.cpp index 227ff31dcd6a..c32621ef417a 100644 --- a/gfx/layers/ipc/CanvasChild.cpp +++ b/gfx/layers/ipc/CanvasChild.cpp @@ -765,7 +765,7 @@ already_AddRefed CanvasChild::SnapshotExternalCanvas( RecordedResolveExternalSnapshot(syncId, gfx::ReferencePtr(surface))); uint32_t managerId = static_cast(Manager())->Id(); - int32_t canvasId = aActor->Id(); + ActorId canvasId = aActor->Id(); // Actually send the request via IPDL to snapshot the external WebGL canvas. SendSnapshotExternalCanvas(syncId, managerId, canvasId); diff --git a/gfx/layers/ipc/CanvasTranslator.cpp b/gfx/layers/ipc/CanvasTranslator.cpp index 82e12343215e..2896b72ba81b 100644 --- a/gfx/layers/ipc/CanvasTranslator.cpp +++ b/gfx/layers/ipc/CanvasTranslator.cpp @@ -1660,7 +1660,7 @@ void CanvasTranslator::SyncTranslation(uint64_t aSyncId) { } mozilla::ipc::IPCResult CanvasTranslator::RecvSnapshotExternalCanvas( - uint64_t aSyncId, uint32_t aManagerId, int32_t aCanvasId) { + uint64_t aSyncId, uint32_t aManagerId, ActorId aCanvasId) { if (NS_WARN_IF(!IsInTaskQueue())) { return IPC_FAIL(this, "RecvSnapshotExternalCanvas used outside of task queue."); diff --git a/gfx/layers/ipc/CanvasTranslator.h b/gfx/layers/ipc/CanvasTranslator.h index ad16e6666e84..bd10e4c4e7c9 100644 --- a/gfx/layers/ipc/CanvasTranslator.h +++ b/gfx/layers/ipc/CanvasTranslator.h @@ -196,7 +196,7 @@ class CanvasTranslator final : public gfx::InlineTranslator, */ mozilla::ipc::IPCResult RecvSnapshotExternalCanvas(uint64_t aSyncId, uint32_t aManagerId, - int32_t aCanvasId); + ActorId aCanvasId); /** * Resolves the given sync-id from the recording stream to a snapshot from diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh index 1446bde511ab..fdfa10604e11 100644 --- a/gfx/layers/ipc/LayersSurfaces.ipdlh +++ b/gfx/layers/ipc/LayersSurfaces.ipdlh @@ -33,6 +33,7 @@ using mozilla::layers::CompositeProcessFencesHolderId from "mozilla/layers/Layer using mozilla::wr::ExternalImageSource from "mozilla/webrender/WebRenderTypes.h"; using mozilla::wr::ExternalImageId from "mozilla/webrender/WebRenderTypes.h"; using mozilla::layers::SurfaceDescriptorRemoteDecoderId from "mozilla/layers/LayersTypes.h"; +using mozilla::ipc::ActorId from "mozilla/ipc/ProtocolUtils.h"; [MoveOnly] using mozilla::ipc::ReadOnlySharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h"; namespace mozilla { @@ -207,7 +208,7 @@ struct SurfaceDescriptorShared [Comparable] struct SurfaceDescriptorCanvasSurface { uint32_t managerId; - int32_t canvasId; + ActorId canvasId; uintptr_t surfaceId; }; diff --git a/gfx/layers/ipc/PCanvas.ipdl b/gfx/layers/ipc/PCanvas.ipdl index 9783a959b11c..387d6fbfaa8e 100644 --- a/gfx/layers/ipc/PCanvas.ipdl +++ b/gfx/layers/ipc/PCanvas.ipdl @@ -12,6 +12,7 @@ include "mozilla/layers/CanvasTranslator.h"; using mozilla::layers::RemoteTextureOwnerId from "mozilla/layers/LayersTypes.h"; using mozilla::layers::TextureType from "mozilla/layers/LayersTypes.h"; using mozilla::gfx::BackendType from "mozilla/gfx/Types.h"; +using mozilla::ipc::ActorId from "mozilla/ipc/ProtocolUtils.h"; [MoveOnly] using mozilla::ipc::ReadOnlySharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h"; [MoveOnly] using mozilla::ipc::MutableSharedMemoryHandle from "mozilla/ipc/SharedMemoryHandle.h"; @@ -69,7 +70,7 @@ parent: /** * Snapshot an external canvas and label it for later lookup under a sync-id. */ - async SnapshotExternalCanvas(uint64_t aSyncId, uint32_t aManagerId, int32_t aCanvasId); + async SnapshotExternalCanvas(uint64_t aSyncId, uint32_t aManagerId, ActorId aCanvasId); async __delete__(); diff --git a/ipc/chromium/src/base/pickle.cc b/ipc/chromium/src/base/pickle.cc index 5df427318518..14f9655e6649 100644 --- a/ipc/chromium/src/base/pickle.cc +++ b/ipc/chromium/src/base/pickle.cc @@ -127,6 +127,7 @@ Pickle::Pickle(uint32_t header_size, size_t segment_capacity) DCHECK(static_cast(header_size) >= sizeof(Header)); DCHECK(header_size_ <= kHeaderSegmentCapacity); header_ = reinterpret_cast(buffers_.Start()); + memset(header_, 0, header_size_); header_->payload_size = 0; } diff --git a/ipc/chromium/src/base/pickle.h b/ipc/chromium/src/base/pickle.h index 45779546108e..f0d0104c60f0 100644 --- a/ipc/chromium/src/base/pickle.h +++ b/ipc/chromium/src/base/pickle.h @@ -217,6 +217,8 @@ class Pickle { struct Header { uint32_t payload_size; // Specifies the size of the payload. }; + static_assert(std::has_unique_object_representations_v
, + "Header must not contain padding bytes"); // Returns the header, cast to a user-specified type T. The type T must be a // subclass of Header and its size must correspond to the header_size passed diff --git a/ipc/chromium/src/chrome/common/ipc_message.cc b/ipc/chromium/src/chrome/common/ipc_message.cc index 472c0fb4e15b..8a68ac0532b8 100644 --- a/ipc/chromium/src/chrome/common/ipc_message.cc +++ b/ipc/chromium/src/chrome/common/ipc_message.cc @@ -21,7 +21,7 @@ const mojo::core::ports::UserMessage::TypeInfo Message::kUserMessageTypeInfo{}; Message::~Message() { MOZ_COUNT_DTOR(IPC::Message); } -Message::Message(int32_t routing_id, msgid_t type, uint32_t segment_capacity, +Message::Message(routeid_t routing_id, msgid_t type, uint32_t segment_capacity, HeaderFlags flags) : UserMessage(&kUserMessageTypeInfo), Pickle(sizeof(Header), segment_capacity) { @@ -37,6 +37,7 @@ Message::Message(int32_t routing_id, msgid_t type, uint32_t segment_capacity, header()->num_send_rights = 0; #endif header()->event_footer_size = 0; + header()->_padding = 0; } Message::Message(const char* data, int data_len) @@ -46,7 +47,7 @@ Message::Message(const char* data, int data_len) } /*static*/ mozilla::UniquePtr Message::IPDLMessage( - int32_t routing_id, msgid_t type, uint32_t segment_capacity, + routeid_t routing_id, msgid_t type, uint32_t segment_capacity, HeaderFlags flags) { return mozilla::MakeUnique(routing_id, type, segment_capacity, flags); diff --git a/ipc/chromium/src/chrome/common/ipc_message.h b/ipc/chromium/src/chrome/common/ipc_message.h index 1663a60db094..eadf83cd0e5b 100644 --- a/ipc/chromium/src/chrome/common/ipc_message.h +++ b/ipc/chromium/src/chrome/common/ipc_message.h @@ -50,7 +50,9 @@ class Message : public mojo::core::ports::UserMessage, public Pickle { public: static const TypeInfo kUserMessageTypeInfo; - typedef uint32_t msgid_t; + using routeid_t = int64_t; + using msgid_t = uint32_t; + using seqno_t = int64_t; enum NestedLevel { NOT_NESTED = 1, @@ -175,8 +177,8 @@ class Message : public mojo::core::ports::UserMessage, public Pickle { // Initialize a message with a user-defined type, priority value, and // destination WebView ID. - Message(int32_t routing_id, msgid_t type, - uint32_t segmentCapacity = 0, // 0 for the default capacity. + Message(routeid_t routing_id, msgid_t type, + uint32_t segment_capacity = 0, // 0 for the default capacity. HeaderFlags flags = HeaderFlags()); Message(const char* data, int data_len); @@ -190,7 +192,7 @@ class Message : public mojo::core::ports::UserMessage, public Pickle { // the write latency of messages) of IPDL message creation. This helps // move the malloc and some of the parameter setting out of autogenerated // code. - static mozilla::UniquePtr IPDLMessage(int32_t routing_id, + static mozilla::UniquePtr IPDLMessage(routeid_t routing_id, msgid_t type, uint32_t segmentCapacity, HeaderFlags flags); @@ -219,17 +221,17 @@ class Message : public mojo::core::ports::UserMessage, public Pickle { msgid_t type() const { return header()->type; } - int32_t routing_id() const { return header()->routing; } + routeid_t routing_id() const { return header()->routing; } - void set_routing_id(int32_t new_id) { header()->routing = new_id; } + void set_routing_id(routeid_t new_id) { header()->routing = new_id; } - int32_t transaction_id() const { return header()->txid; } + seqno_t transaction_id() const { return header()->txid; } - void set_transaction_id(int32_t txid) { header()->txid = txid; } + void set_transaction_id(seqno_t txid) { header()->txid = txid; } - int32_t seqno() const { return header()->seqno; } + seqno_t seqno() const { return header()->seqno; } - void set_seqno(int32_t aSeqno) { header()->seqno = aSeqno; } + void set_seqno(seqno_t aSeqno) { header()->seqno = aSeqno; } const char* name() const { return StringFromIPCMessageType(type()); } @@ -369,22 +371,25 @@ class Message : public mojo::core::ports::UserMessage, public Pickle { #endif struct Header : Pickle::Header { - int32_t routing; // ID of the view that this message is destined for - msgid_t type; // specifies the user-defined message type - HeaderFlags flags; // specifies control flags for the message + // Pickle::Header contains a 32-bit payload_size field + msgid_t type; // specifies the user-defined message type + HeaderFlags flags; // specifies control flags for the message + uint32_t event_footer_size; // Size of the message's event footer + + routeid_t routing; // ID of the view that this message is destined for + seqno_t txid; // For sync messages, a transaction ID for message ordering. + seqno_t seqno; // Sequence number + uint32_t num_handles; // the number of handles included with this message #if defined(XP_DARWIN) uint32_t cookie; // cookie to ACK that the descriptors have been read. uint32_t num_send_rights; // the number of mach send rights included with // this message #endif - // For sync messages, a transaction ID for message ordering. - int32_t txid; - // Sequence number - int32_t seqno; - // Size of the message's event footer - uint32_t event_footer_size; + uint32_t _padding; }; + static_assert(std::has_unique_object_representations_v
, + "Header must not contain padding bytes"); Header* header() { return headerT
(); } const Header* header() const { return headerT
(); } @@ -423,15 +428,12 @@ class Message : public mojo::core::ports::UserMessage, public Pickle { } // namespace IPC -enum SpecialRoutingIDs { +enum SpecialRoutingIDs : IPC::Message::routeid_t { // indicates that we don't have a routing ID yet. - MSG_ROUTING_NONE = kint32min, + MSG_ROUTING_NONE = INT64_MIN, // indicates a general message not sent to a particular tab. - MSG_ROUTING_CONTROL = kint32max + MSG_ROUTING_CONTROL = INT64_MAX }; -#define IPC_REPLY_ID 0xFFF0 // Special message id for replies -#define IPC_LOGGING_ID 0xFFF1 // Special message id for logging - #endif // CHROME_COMMON_IPC_MESSAGE_H__ diff --git a/ipc/glue/Endpoint.cpp b/ipc/glue/Endpoint.cpp index e10a5c2273b4..6d124825e1e0 100644 --- a/ipc/glue/Endpoint.cpp +++ b/ipc/glue/Endpoint.cpp @@ -84,7 +84,7 @@ bool UntypedManagedEndpoint::BindCommon(IProtocol* aActor, return false; } - int32_t id = mInner->mId; + ActorId id = mInner->mId; mInner.reset(); // Our typed caller will insert the actor into the managed container. diff --git a/ipc/glue/Endpoint.h b/ipc/glue/Endpoint.h index fc643f967f4a..96ce81ba8179 100644 --- a/ipc/glue/Endpoint.h +++ b/ipc/glue/Endpoint.h @@ -231,9 +231,9 @@ class UntypedManagedEndpoint { RefPtr mOtherSide; RefPtr mToplevel; - int32_t mId = 0; + ActorId mId = 0; ProtocolId mType = LastMsgIndex; - int32_t mManagerId = 0; + ActorId mManagerId = 0; ProtocolId mManagerType = LastMsgIndex; }; Maybe mInner; diff --git a/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index ed0119af0499..4dae1dcd6eca 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -133,9 +133,10 @@ bool MessageChannel::sIsPumpingMessages = false; class AutoEnterTransaction { public: - explicit AutoEnterTransaction(MessageChannel* aChan, int32_t aMsgSeqno, - int32_t aTransactionID, int aNestedLevel) - MOZ_REQUIRES(*aChan->mMonitor) + explicit AutoEnterTransaction(MessageChannel* aChan, + IPC::Message::seqno_t aMsgSeqno, + IPC::Message::seqno_t aTransactionID, + int aNestedLevel) MOZ_REQUIRES(*aChan->mMonitor) : mChan(aChan), mActive(true), mOutgoing(true), @@ -234,12 +235,12 @@ class AutoEnterTransaction { return mNestedLevel; } - int32_t SequenceNumber() const { + IPC::Message::seqno_t SequenceNumber() const { MOZ_RELEASE_ASSERT(mActive); return mSeqno; } - int32_t TransactionID() const { + IPC::Message::seqno_t TransactionID() const { MOZ_RELEASE_ASSERT(mActive); return mTransaction; } @@ -248,7 +249,7 @@ class AutoEnterTransaction { MOZ_RELEASE_ASSERT(aMessage->seqno() == mSeqno); MOZ_RELEASE_ASSERT(aMessage->transaction_id() == mTransaction); MOZ_RELEASE_ASSERT(!mReply); - IPC_LOG("Reply received on worker thread: seqno=%d", mSeqno); + IPC_LOG("Reply received on worker thread: seqno=%" PRId64, mSeqno); mReply = std::move(aMessage); MOZ_RELEASE_ASSERT(IsComplete()); } @@ -297,8 +298,8 @@ class AutoEnterTransaction { // Properties of the message being sent/received. int mNestedLevel; - int32_t mSeqno; - int32_t mTransaction; + IPC::Message::seqno_t mSeqno; + IPC::Message::seqno_t mTransaction; // Next item in mChan->mTransactionStack. AutoEnterTransaction* mNext; @@ -497,7 +498,7 @@ void MessageChannel::AssertMaybeDeferredCountCorrect() { // function is only called when the current transaction is known to be for a // NESTED_INSIDE_SYNC message. In that case, we know for sure what the caller is // looking for. -int32_t MessageChannel::CurrentNestedInsideSyncTransaction() const { +auto MessageChannel::CurrentNestedInsideSyncTransaction() const -> seqno_t { mMonitor->AssertCurrentThreadOwns(); if (!mTransactionStack) { return 0; @@ -710,7 +711,7 @@ bool MessageChannel::OpenOnSameThread(MessageChannel* aTargetChan, Open(std::move(porta), aSide, channelId, currentThread); } -bool MessageChannel::Send(UniquePtr aMsg, int32_t* aSeqno) { +bool MessageChannel::Send(UniquePtr aMsg, seqno_t* aSeqno) { MOZ_RELEASE_ASSERT(!aMsg->is_sync()); MOZ_RELEASE_ASSERT(aMsg->nested_level() != IPC::Message::NESTED_INSIDE_SYNC); MOZ_RELEASE_ASSERT(aMsg->routing_id() != MSG_ROUTING_NONE); @@ -843,7 +844,7 @@ bool MessageChannel::SendBuildIDsMatchMessage(const char* aParentBuildID) { class CancelMessage : public IPC::Message { public: - explicit CancelMessage(int transaction) + explicit CancelMessage(seqno_t transaction) : IPC::Message(MSG_ROUTING_NONE, CANCEL_MESSAGE_TYPE) { set_transaction_id(transaction); } @@ -1001,12 +1002,12 @@ void MessageChannel::OnMessageReceivedFromLink(UniquePtr aMsg) { // If we're awaiting a sync reply, we know that it needs to be immediately // handled to unblock us. if (aMsg->is_sync() && aMsg->is_reply()) { - IPC_LOG("Received reply seqno=%d xid=%d", aMsg->seqno(), + IPC_LOG("Received reply seqno=%" PRId64 " xid=%" PRId64, aMsg->seqno(), aMsg->transaction_id()); if (aMsg->seqno() == mTimedOutMessageSeqno) { // Drop the message, but allow future sync messages to be sent. - IPC_LOG("Received reply to timedout message; igoring; xid=%d", + IPC_LOG("Received reply to timedout message; igoring; xid=%" PRId64, mTimedOutMessageSeqno); EndTimeout(); return; @@ -1062,8 +1063,9 @@ void MessageChannel::OnMessageReceivedFromLink(UniquePtr aMsg) { bool shouldWakeUp = AwaitingSyncReply() && !ShouldDeferMessage(*aMsg); - IPC_LOG("Receive from link; seqno=%d, xid=%d, shouldWakeUp=%d", aMsg->seqno(), - aMsg->transaction_id(), shouldWakeUp); + IPC_LOG("Receive from link; seqno=%" PRId64 ", xid=%" PRId64 + ", shouldWakeUp=%d", + aMsg->seqno(), aMsg->transaction_id(), shouldWakeUp); struct FlowMarkerDispatch { FlowMarkerDispatch(msgid_t type, Flow flow) : type(type), flow(flow) { @@ -1086,8 +1088,8 @@ void MessageChannel::OnMessageReceivedFromLink(UniquePtr aMsg) { // We want this marker to span the time when Post is called so that we // can inherit the connection to the runnable. FlowMarkerDispatch marker( - aMsg->type(), - Flow::Global(aMsg->seqno() ^ LossyNarrowChannelId(mMessageChannelId))); + aMsg->type(), Flow::Global(static_cast(aMsg->seqno()) ^ + LossyNarrowChannelId(mMessageChannelId))); // There are two cases we're concerned about, relating to the state of the // worker thread: @@ -1149,7 +1151,7 @@ void MessageChannel::ProcessPendingRequests( return; } - IPC_LOG("ProcessPendingRequests for seqno=%d, xid=%d", + IPC_LOG("ProcessPendingRequests for seqno=%" PRId64 ", xid=%" PRId64, aTransaction.SequenceNumber(), aTransaction.TransactionID()); // Loop until there aren't any more nested messages to process. @@ -1176,7 +1178,8 @@ void MessageChannel::ProcessPendingRequests( // Only log the interesting messages. if (msg->is_sync() || msg->nested_level() == IPC::Message::NESTED_INSIDE_CPOW) { - IPC_LOG("ShouldDeferMessage(seqno=%d) = %d", msg->seqno(), defer); + IPC_LOG("ShouldDeferMessage(seqno=%" PRId64 ") = %d", msg->seqno(), + defer); } if (!defer) { @@ -1292,7 +1295,7 @@ bool MessageChannel::Send(UniquePtr aMsg, UniquePtr* aReply) { aMsg->set_seqno(NextSeqno()); - int32_t seqno = aMsg->seqno(); + seqno_t seqno = aMsg->seqno(); int nestedLevel = aMsg->nested_level(); msgid_t replyType = aMsg->type() + 1; @@ -1304,12 +1307,12 @@ bool MessageChannel::Send(UniquePtr aMsg, UniquePtr* aReply) { // message we're sending). bool nest = stackTop && stackTop->NestedLevel() == IPC::Message::NESTED_INSIDE_SYNC; - int32_t transaction = nest ? stackTop->TransactionID() : seqno; + seqno_t transaction = nest ? stackTop->TransactionID() : seqno; aMsg->set_transaction_id(transaction); AutoEnterTransaction transact(this, seqno, transaction, nestedLevel); - IPC_LOG("Send seqno=%d, xid=%d", seqno, transaction); + IPC_LOG("Send seqno=%" PRId64 ", xid=%" PRId64, seqno, transaction); // aMsg will be destroyed soon, let's keep its type. const char* msgName = aMsg->name(); @@ -1365,7 +1368,7 @@ bool MessageChannel::Send(UniquePtr aMsg, UniquePtr* aReply) { break; } - IPC_LOG("Timing out Send: xid=%d", transaction); + IPC_LOG("Timing out Send: xid=%" PRId64, transaction); mTimedOutMessageSeqno = seqno; mTimedOutMessageNestedLevel = nestedLevel; @@ -1379,20 +1382,22 @@ bool MessageChannel::Send(UniquePtr aMsg, UniquePtr* aReply) { } if (transact.IsCanceled()) { - IPC_LOG("Other side canceled seqno=%d, xid=%d", seqno, transaction); + IPC_LOG("Other side canceled seqno=%" PRId64 ", xid=%" PRId64, seqno, + transaction); mLastSendError = SyncSendError::CancelledAfterSend; return false; } if (transact.IsError()) { - IPC_LOG("Error: seqno=%d, xid=%d", seqno, transaction); + IPC_LOG("Error: seqno=%" PRId64 ", xid=%" PRId64, seqno, transaction); mLastSendError = SyncSendError::ReplyError; return false; } uint32_t latencyMs = round((TimeStamp::Now() - start).ToMilliseconds()); - IPC_LOG("Got reply: seqno=%d, xid=%d, msgName=%s, latency=%ums", seqno, - transaction, msgName, latencyMs); + IPC_LOG("Got reply: seqno=%" PRId64 ", xid=%" PRId64 + ", msgName=%s, latency=%ums", + seqno, transaction, msgName, latencyMs); UniquePtr reply = transact.GetReply(); @@ -1420,7 +1425,7 @@ bool MessageChannel::ProcessPendingRequest(ActorLifecycleProxy* aProxy, AssertWorkerThread(); mMonitor->AssertCurrentThreadOwns(); - IPC_LOG("Process pending: seqno=%d, xid=%d", aUrgent->seqno(), + IPC_LOG("Process pending: seqno=%" PRId64 ", xid=%" PRId64, aUrgent->seqno(), aUrgent->transaction_id()); // keep the error relevant information @@ -1694,14 +1699,14 @@ void MessageChannel::DispatchMessage(ActorLifecycleProxy* aProxy, } #endif - IPC_LOG("DispatchMessage: seqno=%d, xid=%d", aMsg->seqno(), + IPC_LOG("DispatchMessage: seqno=%" PRId64 ", xid=%" PRId64, aMsg->seqno(), aMsg->transaction_id()); AddProfilerMarker(*aMsg, MessageDirection::eReceiving); { AutoEnterTransaction transaction(this, *aMsg); - int id = aMsg->transaction_id(); + seqno_t id = aMsg->transaction_id(); MOZ_RELEASE_ASSERT(!aMsg->is_sync() || id == transaction.TransactionID()); { @@ -1721,7 +1726,8 @@ void MessageChannel::DispatchMessage(ActorLifecycleProxy* aProxy, if (reply && transaction.IsCanceled()) { // The transaction has been canceled. Don't send a reply. - IPC_LOG("Nulling out reply due to cancellation, seqno=%d, xid=%d", + IPC_LOG("Nulling out reply due to cancellation, seqno=%" PRId64 + ", xid=%" PRId64, aMsg->seqno(), id); reply = nullptr; } @@ -1734,7 +1740,7 @@ void MessageChannel::DispatchMessage(ActorLifecycleProxy* aProxy, #endif if (reply && ChannelConnected == mChannelState) { - IPC_LOG("Sending reply seqno=%d, xid=%d", aMsg->seqno(), + IPC_LOG("Sending reply seqno=%" PRId64 ", xid=%" PRId64, aMsg->seqno(), aMsg->transaction_id()); AddProfilerMarker(*reply, MessageDirection::eSending); @@ -2263,7 +2269,7 @@ void MessageChannel::AddProfilerMarker(const IPC::Message& aMessage, void MessageChannel::EndTimeout() { mMonitor->AssertCurrentThreadOwns(); - IPC_LOG("Ending timeout of seqno=%d", mTimedOutMessageSeqno); + IPC_LOG("Ending timeout of seqno=%" PRId64, mTimedOutMessageSeqno); mTimedOutMessageSeqno = 0; mTimedOutMessageNestedLevel = 0; @@ -2303,7 +2309,7 @@ void MessageChannel::RepostAllMessages() { AssertMaybeDeferredCountCorrect(); } -void MessageChannel::CancelTransaction(int transaction) { +void MessageChannel::CancelTransaction(seqno_t transaction) { mMonitor->AssertCurrentThreadOwns(); // When we cancel a transaction, we need to behave as if there's no longer @@ -2316,13 +2322,13 @@ void MessageChannel::CancelTransaction(int transaction) { // tampered with (by us). If so, they don't reset the variable to the old // value. - IPC_LOG("CancelTransaction: xid=%d", transaction); + IPC_LOG("CancelTransaction: xid=%" PRId64, transaction); // An unusual case: We timed out a transaction which the other side then // cancelled. In this case we just leave the timedout state and try to // forget this ever happened. if (transaction == mTimedOutMessageSeqno) { - IPC_LOG("Cancelled timed out message %d", mTimedOutMessageSeqno); + IPC_LOG("Cancelled timed out message %" PRId64, mTimedOutMessageSeqno); EndTimeout(); // Normally mCurrentTransaction == 0 here. But it can be non-zero if: @@ -2353,8 +2359,8 @@ void MessageChannel::CancelTransaction(int transaction) { if (msg->is_sync() && msg->nested_level() != IPC::Message::NOT_NESTED) { MOZ_RELEASE_ASSERT(!foundSync); MOZ_RELEASE_ASSERT(msg->transaction_id() != transaction); - IPC_LOG("Removing msg from queue seqno=%d xid=%d", msg->seqno(), - msg->transaction_id()); + IPC_LOG("Removing msg from queue seqno=%" PRId64 " xid=%" PRId64, + msg->seqno(), msg->transaction_id()); foundSync = true; if (!IsAlwaysDeferred(*msg)) { mMaybeDeferredPendingCount--; @@ -2379,7 +2385,7 @@ void MessageChannel::CancelCurrentTransaction() { mListener->IntentionalCrash(); } - IPC_LOG("Cancel requested: current xid=%d", + IPC_LOG("Cancel requested: current xid=%" PRId64, CurrentNestedInsideSyncTransaction()); MOZ_RELEASE_ASSERT(DispatchingSyncMessage()); auto cancel = diff --git a/ipc/glue/MessageChannel.h b/ipc/glue/MessageChannel.h index 7f31800c01cf..6ec439542e73 100644 --- a/ipc/glue/MessageChannel.h +++ b/ipc/glue/MessageChannel.h @@ -114,6 +114,7 @@ class MessageChannel : HasResultCodes { public: using Message = IPC::Message; + using seqno_t = Message::seqno_t; static constexpr int32_t kNoTimeout = INT32_MIN; @@ -205,7 +206,7 @@ class MessageChannel : HasResultCodes { // Asynchronously send a message to the other side of the channel. // If aSeqno is non-null, it will be set to the seqno of the sent message. - bool Send(UniquePtr aMsg, int32_t* aSeqno = nullptr) + bool Send(UniquePtr aMsg, seqno_t* aSeqno = nullptr) MOZ_EXCLUDES(*mMonitor); bool SendBuildIDsMatchMessage(const char* aParentBuildID) @@ -361,12 +362,13 @@ class MessageChannel : HasResultCodes { bool ShouldContinueFromTimeout() MOZ_REQUIRES(*mMonitor); void EndTimeout() MOZ_REQUIRES(*mMonitor); - void CancelTransaction(int transaction) MOZ_REQUIRES(*mMonitor); + void CancelTransaction(seqno_t transaction) MOZ_REQUIRES(*mMonitor); void RepostAllMessages() MOZ_REQUIRES(*mMonitor); - int32_t NextSeqno() { + seqno_t NextSeqno() { AssertWorkerThread(); + MOZ_RELEASE_ASSERT(mozilla::Abs(mNextSeqno) < INT64_MAX, "seqno overflow"); return (mSide == ChildSide) ? --mNextSeqno : ++mNextSeqno; } @@ -420,7 +422,6 @@ class MessageChannel : HasResultCodes { // Called to flush [LazySend] messages to the link. void FlushLazySendMessages() MOZ_REQUIRES(*mMonitor); - bool WasTransactionCanceled(int transaction); bool ShouldDeferMessage(const Message& aMsg) MOZ_REQUIRES(*mMonitor); void OnMessageReceivedFromLink(UniquePtr aMsg) MOZ_REQUIRES(*mMonitor); @@ -606,7 +607,7 @@ class MessageChannel : HasResultCodes { // Worker-thread only; sequence numbers for messages that require // replies. - int32_t mNextSeqno = 0; + seqno_t mNextSeqno = 0; static bool sIsPumpingMessages; @@ -659,7 +660,7 @@ class MessageChannel : HasResultCodes { friend class AutoEnterTransaction; AutoEnterTransaction* mTransactionStack MOZ_GUARDED_BY(*mMonitor) = nullptr; - int32_t CurrentNestedInsideSyncTransaction() const MOZ_REQUIRES(*mMonitor); + seqno_t CurrentNestedInsideSyncTransaction() const MOZ_REQUIRES(*mMonitor); bool AwaitingSyncReply() const MOZ_REQUIRES(*mMonitor); int AwaitingSyncReplyNestedLevel() const MOZ_REQUIRES(*mMonitor); @@ -686,7 +687,7 @@ class MessageChannel : HasResultCodes { // A message is only timed out if it initiated a transaction. This avoids // hitting a lot of corner cases with message nesting that we don't really // care about. - int32_t mTimedOutMessageSeqno MOZ_GUARDED_BY(*mMonitor) = 0; + seqno_t mTimedOutMessageSeqno MOZ_GUARDED_BY(*mMonitor) = 0; int mTimedOutMessageNestedLevel MOZ_GUARDED_BY(*mMonitor) = 0; // Queue of all incoming messages. @@ -754,7 +755,7 @@ struct IPCMarker { static void StreamJSONMarkerData( mozilla::baseprofiler::SpliceableJSONWriter& aWriter, mozilla::TimeStamp aStart, mozilla::TimeStamp aEnd, int32_t aOtherPid, - int32_t aMessageSeqno, IPC::Message::msgid_t aMessageType, + IPC::Message::seqno_t aMessageSeqno, IPC::Message::msgid_t aMessageType, mozilla::ipc::Side aSide, mozilla::ipc::MessageDirection aDirection, mozilla::ipc::MessagePhase aPhase, bool aSync, mozilla::MarkerThreadId aOriginThreadId) { diff --git a/ipc/glue/ProtocolMessageUtils.h b/ipc/glue/ProtocolMessageUtils.h index 74089d96af96..26d2dcef1bbd 100644 --- a/ipc/glue/ProtocolMessageUtils.h +++ b/ipc/glue/ProtocolMessageUtils.h @@ -46,21 +46,12 @@ struct ParamTraits LastMsgIndex> {}; template <> -struct ParamTraits { - typedef mozilla::ipc::ActorHandle paramType; +struct ParamTraits { + using paramType = mozilla::ipc::IProtocol*; - static void Write(MessageWriter* aWriter, const paramType& aParam) { - IPC::WriteParam(aWriter, aParam.mId); - } + static void Write(MessageWriter* aWriter, const paramType& aParam); - static bool Read(MessageReader* aReader, paramType* aResult) { - int id; - if (IPC::ReadParam(aReader, &id)) { - aResult->mId = id; - return true; - } - return false; - } + static bool Read(MessageReader* aReader, paramType* aResult); }; template <> diff --git a/ipc/glue/ProtocolUtils.cpp b/ipc/glue/ProtocolUtils.cpp index 9c9100575748..97bae5a5a361 100644 --- a/ipc/glue/ProtocolUtils.cpp +++ b/ipc/glue/ProtocolUtils.cpp @@ -337,12 +337,12 @@ IProtocol::~IProtocol() { // The following methods either directly forward to the toplevel protocol, or // almost directly do. -IProtocol* IProtocol::Lookup(int32_t aId) { return mToplevel->Lookup(aId); } +IProtocol* IProtocol::Lookup(ActorId aId) { return mToplevel->Lookup(aId); } Shmem IProtocol::CreateSharedMemory(size_t aSize, bool aUnsafe) { return mToplevel->CreateSharedMemory(aSize, aUnsafe); } -Shmem::Segment* IProtocol::LookupSharedMemory(int32_t aId) { +Shmem::Segment* IProtocol::LookupSharedMemory(Shmem::id_t aId) { return mToplevel->LookupSharedMemory(aId); } bool IProtocol::IsTrackingSharedMemory(const Shmem::Segment* aSegment) { @@ -363,39 +363,6 @@ nsISerialEventTarget* IProtocol::GetActorEventTarget() { return GetIPCChannel()->GetWorkerEventTarget(); } -Maybe IProtocol::ReadActor(IPC::MessageReader* aReader, - bool aNullable, - const char* aActorDescription, - int32_t aProtocolTypeId) { - int32_t id; - if (!IPC::ReadParam(aReader, &id)) { - ActorIdReadError(aActorDescription); - return Nothing(); - } - - if (id == 1 || (id == 0 && !aNullable)) { - BadActorIdError(aActorDescription); - return Nothing(); - } - - if (id == 0) { - return Some(static_cast(nullptr)); - } - - IProtocol* listener = this->Lookup(id); - if (!listener) { - ActorLookupError(aActorDescription); - return Nothing(); - } - - if (listener->GetProtocolId() != aProtocolTypeId) { - MismatchedActorTypeError(aActorDescription); - return Nothing(); - } - - return Some(listener); -} - void IProtocol::FatalError(const char* const aErrorMsg) { HandleFatalError(aErrorMsg); } @@ -457,7 +424,7 @@ void IProtocol::SetManager(IRefCountedProtocol* aManager) { } bool IProtocol::SetManagerAndRegister(IRefCountedProtocol* aManager, - int32_t aId) { + ActorId aId) { MOZ_RELEASE_ASSERT(mLinkStatus == LinkStatus::Inactive, "Actor must be inactive to SetManagerAndRegister"); @@ -515,7 +482,8 @@ void IProtocol::UnlinkManager() { mManager = nullptr; } -bool IProtocol::ChannelSend(UniquePtr aMsg, int32_t* aSeqno) { +bool IProtocol::ChannelSend(UniquePtr aMsg, + IPC::Message::seqno_t* aSeqno) { if (CanSend()) { // NOTE: This send call failing can only occur during toplevel channel // teardown. As this is an async call, this isn't reasonable to predict or @@ -601,9 +569,8 @@ void IProtocol::ActorDisconnected(ActorDestroyReason aWhy) { fuzzing::IPCFuzzController::instance().OnActorDestroyed(actor); #endif - int32_t id = actor->mId; + ActorId id = actor->mId; if (IProtocol* manager = actor->Manager()) { - actor->mId = kFreedActorId; auto entry = toplevel->mActorMap.Lookup(id); MOZ_DIAGNOSTIC_ASSERT(entry && *entry == actor->GetLifecycleProxy(), "ID must be present and reference this actor"); @@ -673,7 +640,7 @@ IToplevelProtocol::IToplevelProtocol(const char* aName, ProtocolId aProtoId, Side aSide) : IRefCountedProtocol(aProtoId, aSide), mOtherPid(base::kInvalidProcessId), - mLastLocalId(0), + mLastLocalId(kNullActorId), mChannel(aName, this) { mToplevel = this; } @@ -723,23 +690,15 @@ bool IToplevelProtocol::IsOnCxxStack() const { return GetIPCChannel()->IsOnCxxStack(); } -int32_t IToplevelProtocol::NextId() { +int64_t IToplevelProtocol::NextId() { // Generate the next ID to use for a shared memory or protocol. Parent and // Child sides of the protocol use different pools. - int32_t tag = 0; - if (GetSide() == ParentSide) { - tag |= 1 << 1; - } - - // Check any overflow - MOZ_RELEASE_ASSERT(mLastLocalId < (1 << 29)); - - // Compute the ID to use with the low two bits as our tag, and the remaining - // bits as a monotonic. - return (++mLastLocalId << 2) | tag; + MOZ_RELEASE_ASSERT(mozilla::Abs(mLastLocalId) < MSG_ROUTING_CONTROL - 1, + "actor id overflow"); + return (GetSide() == ChildSide) ? --mLastLocalId : ++mLastLocalId; } -IProtocol* IToplevelProtocol::Lookup(int32_t aId) { +IProtocol* IToplevelProtocol::Lookup(ActorId aId) { if (auto entry = mActorMap.Lookup(aId)) { return entry.Data()->Get(); } @@ -888,8 +847,8 @@ bool IPDLAsyncReturnsCallbacks::EntryKey::operator<( (mSeqno == aOther.mSeqno && mType < aOther.mType); } -void IPDLAsyncReturnsCallbacks::AddCallback(int32_t aSeqno, msgid_t aType, - Callback aResolve, +void IPDLAsyncReturnsCallbacks::AddCallback(IPC::Message::seqno_t aSeqno, + msgid_t aType, Callback aResolve, RejectCallback aReject) { Entry entry{{aSeqno, aType}, std::move(aResolve), std::move(aReject)}; MOZ_ASSERT(!mMap.ContainsSorted(entry)); @@ -950,3 +909,46 @@ void IPDLAsyncReturnsCallbacks::RejectPendingResponses( } // namespace ipc } // namespace mozilla + +namespace IPC { + +void ParamTraits::Write(MessageWriter* aWriter, + const paramType& aParam) { + MOZ_RELEASE_ASSERT(aWriter->GetActor(), + "Cannot serialize managed actors without an actor"); + + mozilla::ipc::ActorId id = mozilla::ipc::IProtocol::kNullActorId; + if (aParam) { + id = aParam->Id(); + MOZ_RELEASE_ASSERT(id != mozilla::ipc::IProtocol::kNullActorId, + "Actor has ID of 0?"); + MOZ_RELEASE_ASSERT(aParam->CanSend(), + "Actor must still be open when sending"); + MOZ_RELEASE_ASSERT( + aWriter->GetActor()->GetIPCChannel() == aParam->GetIPCChannel(), + "Actor must be from the same tree as the actor it is being sent over"); + } + + IPC::WriteParam(aWriter, id); +} + +bool ParamTraits::Read(MessageReader* aReader, + paramType* aResult) { + MOZ_RELEASE_ASSERT(aReader->GetActor(), + "Cannot serialize managed actors without an actor"); + + mozilla::ipc::ActorId id; + if (!IPC::ReadParam(aReader, &id)) { + return false; + } + + if (id == mozilla::ipc::IProtocol::kNullActorId) { + *aResult = nullptr; + return true; + } + + *aResult = aReader->GetActor()->Lookup(id); + return *aResult != nullptr; +} + +} // namespace IPC diff --git a/ipc/glue/ProtocolUtils.h b/ipc/glue/ProtocolUtils.h index 8037eefe4f6f..3e910418d927 100644 --- a/ipc/glue/ProtocolUtils.h +++ b/ipc/glue/ProtocolUtils.h @@ -124,9 +124,7 @@ struct EndpointProcInfo { // Used to pass references to protocol actors across the wire. // Actors created on the parent-side have a positive ID, and actors // allocated on the child side have a negative ID. -struct ActorHandle { - int mId; -}; +using ActorId = IPC::Message::routeid_t; enum class LinkStatus : uint8_t { // The actor has not established a link yet, or the actor is no longer in use @@ -194,10 +192,10 @@ class IProtocol : public HasResultCodes { const IToplevelProtocol* ToplevelProtocol() const { return mToplevel; } // Lookup() is forwarded directly to the toplevel protocol. - IProtocol* Lookup(int32_t aId); + IProtocol* Lookup(ActorId aId); Shmem CreateSharedMemory(size_t aSize, bool aUnsafe); - Shmem::Segment* LookupSharedMemory(int32_t aId); + Shmem::Segment* LookupSharedMemory(ActorId aId); bool IsTrackingSharedMemory(const Shmem::Segment* aSegment); bool DestroySharedMemory(Shmem& aShmem); @@ -213,7 +211,7 @@ class IProtocol : public HasResultCodes { ProtocolId GetProtocolId() const { return mProtocolId; } const char* GetProtocolName() const { return ProtocolIdToName(mProtocolId); } - int32_t Id() const { return mId; } + ActorId Id() const { return mId; } IRefCountedProtocol* Manager() const { return mManager; } uint32_t AllManagedActorsCount() const; @@ -232,11 +230,7 @@ class IProtocol : public HasResultCodes { } // Deallocate a managee given its type. - virtual void DeallocManagee(int32_t, IProtocol*) = 0; - - Maybe ReadActor(IPC::MessageReader* aReader, bool aNullable, - const char* aActorDescription, - int32_t aProtocolTypeId); + virtual void DeallocManagee(ProtocolId, IProtocol*) = 0; virtual Result OnMessageReceived(const Message& aMessage) = 0; virtual Result OnMessageReceived(const Message& aMessage, @@ -255,6 +249,7 @@ class IProtocol : public HasResultCodes { friend class ActorLifecycleProxy; friend class IPDLResolverInner; friend class UntypedManagedEndpoint; + friend struct IPC::ParamTraits; // We have separate functions because the accessibility code and BrowserParent // manually calls SetManager. @@ -269,10 +264,11 @@ class IProtocol : public HasResultCodes { // its manager, setting up channels for the protocol as well. Not // for use outside of IPDL. bool SetManagerAndRegister(IRefCountedProtocol* aManager, - int32_t aId = kNullActorId); + ActorId aId = kNullActorId); // Helpers for calling `Send` on our underlying IPC channel. - bool ChannelSend(UniquePtr aMsg, int32_t* aSeqno = nullptr); + bool ChannelSend(UniquePtr aMsg, + IPC::Message::seqno_t* aSeqno = nullptr); bool ChannelSend(UniquePtr aMsg, UniquePtr* aReply); @@ -311,8 +307,7 @@ class IProtocol : public HasResultCodes { // The actor has been freed after this method returns. virtual void ActorDealloc() = 0; - static const int32_t kNullActorId = 0; - static const int32_t kFreedActorId = 1; + static const ActorId kNullActorId = 0; private: #ifdef DEBUG @@ -327,7 +322,7 @@ class IProtocol : public HasResultCodes { // identify managed actors to destroy when tearing down an actor tree. IProtocol* PeekManagedActor() const; - int32_t mId; + ActorId mId; const ProtocolId mProtocolId; const Side mSide; LinkStatus mLinkStatus; @@ -444,10 +439,10 @@ class IToplevelProtocol : public IRefCountedProtocol { public: // Shadows the method on IProtocol, which will forward to the top. - IProtocol* Lookup(int32_t aId); + IProtocol* Lookup(Shmem::id_t aId); Shmem CreateSharedMemory(size_t aSize, bool aUnsafe); - Shmem::Segment* LookupSharedMemory(int32_t aId); + Shmem::Segment* LookupSharedMemory(Shmem::id_t aId); bool IsTrackingSharedMemory(const Shmem::Segment* aSegment); bool DestroySharedMemory(Shmem& aShmem); @@ -546,17 +541,17 @@ class IToplevelProtocol : public IRefCountedProtocol { GeckoChildID OtherChildIDMaybeInvalid() const { return mOtherChildID; } private: - int32_t NextId(); + int64_t NextId(); template - using IDMap = nsTHashMap; + using IDMap = nsTHashMap; base::ProcessId mOtherPid; GeckoChildID mOtherChildID; // NOTE NOTE NOTE // Used to be on mState - int32_t mLastLocalId; + int64_t mLastLocalId; IDMap> mActorMap; IDMap> mShmemMap; @@ -761,16 +756,17 @@ class IPDLAsyncReturnsCallbacks : public HasResultCodes { // the IPC::MessageReader* argument. using Callback = mozilla::MoveOnlyFunction; + using seqno_t = IPC::Message::seqno_t; using msgid_t = IPC::Message::msgid_t; - void AddCallback(int32_t aSeqno, msgid_t aType, Callback aResolve, + void AddCallback(seqno_t aSeqno, msgid_t aType, Callback aResolve, RejectCallback aReject); Result GotReply(IProtocol* aActor, const IPC::Message& aMessage); void RejectPendingResponses(ResponseRejectReason aReason); private: struct EntryKey { - int32_t mSeqno; + seqno_t mSeqno; msgid_t mType; bool operator==(const EntryKey& aOther) const; diff --git a/ipc/glue/Shmem.cpp b/ipc/glue/Shmem.cpp index f8b535d7c72d..c3435afbad1f 100644 --- a/ipc/glue/Shmem.cpp +++ b/ipc/glue/Shmem.cpp @@ -20,7 +20,7 @@ class ShmemCreated : public IPC::Message { typedef Shmem::id_t id_t; public: - ShmemCreated(int32_t routingId, id_t aIPDLId, + ShmemCreated(routeid_t routingId, id_t aIPDLId, MutableSharedMemoryHandle&& aHandle) : IPC::Message( routingId, SHMEM_CREATED_MESSAGE_TYPE, 0, @@ -46,7 +46,7 @@ class ShmemDestroyed : public IPC::Message { typedef Shmem::id_t id_t; public: - ShmemDestroyed(int32_t routingId, id_t aIPDLId) + ShmemDestroyed(routeid_t routingId, id_t aIPDLId) : IPC::Message( routingId, SHMEM_DESTROYED_MESSAGE_TYPE, 0, HeaderFlags(NOT_NESTED, NORMAL_PRIORITY, COMPRESSION_NONE, @@ -127,7 +127,7 @@ Shmem::Builder::Builder(size_t aSize) : mSize(aSize) { } std::tuple, Shmem> Shmem::Builder::Build( - id_t aId, bool aUnsafe, int32_t aRoutingId) { + id_t aId, bool aUnsafe, IPC::Message::routeid_t aRoutingId) { Shmem shmem(std::move(mSegment), aId, mSize, aUnsafe); shmem.AssertInvariants(); MOZ_ASSERT(mHandle, "null shmem handle"); @@ -160,7 +160,8 @@ already_AddRefed Shmem::OpenExisting( return MakeAndAddRef(std::move(mapping)); } -UniquePtr Shmem::MkDestroyedMessage(int32_t routingId) { +UniquePtr Shmem::MkDestroyedMessage( + IPC::Message::routeid_t routingId) { AssertInvariants(); return MakeUnique(routingId, mId); } diff --git a/ipc/glue/Shmem.h b/ipc/glue/Shmem.h index 1bef5648a98e..da12e5e26118 100644 --- a/ipc/glue/Shmem.h +++ b/ipc/glue/Shmem.h @@ -68,7 +68,7 @@ class Shmem final { friend class IToplevelProtocol; public: - using id_t = int32_t; + using id_t = int64_t; // Low-level wrapper around platform shmem primitives. class Segment final : public SharedMemoryMapping { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Segment); @@ -89,8 +89,8 @@ class Shmem final { // Prepare this to be shared with another process. Return an IPC message // that contains enough information for the other process to map this // segment in OpenExisting(), and the shmem. - std::tuple, Shmem> Build(id_t aId, bool aUnsafe, - int32_t aRoutingId); + std::tuple, Shmem> Build( + id_t aId, bool aUnsafe, IPC::Message::routeid_t aRoutingId); private: size_t mSize; @@ -169,7 +169,7 @@ class Shmem final { // contains enough information for the other process to unmap this // segment. Return a new message if successful (owned by the // caller), nullptr if not. - UniquePtr MkDestroyedMessage(int32_t routingId); + UniquePtr MkDestroyedMessage(IPC::Message::routeid_t routingId); // Return a Segment instance in this process using the descriptor shared // to us by the process that created the underlying OS shmem resource. The diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index 57f99e39c36c..a6dd54f2672a 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -130,7 +130,7 @@ def _protocolId(ptype): def _protocolIdType(): - return Type.INT32 + return Type("mozilla::ipc::ProtocolId") def _actorName(pname, side): @@ -142,11 +142,7 @@ def _actorName(pname, side): def _actorIdType(): - return Type.INT32 - - -def _actorTypeTagType(): - return Type.INT32 + return Type("mozilla::ipc::ActorId") def _actorId(actor=None): @@ -155,10 +151,6 @@ def _actorId(actor=None): return ExprCall(ExprVar("Id")) -def _actorHId(actorhandle): - return ExprSelect(actorhandle, ".", "mId") - - def _deleteId(): return ExprVar("Msg___delete____ID") @@ -1822,7 +1814,7 @@ def _generateMessageConstructor(md, segmentSize, protocol, forReply=False): func = FunctionDefn( FunctionDecl( clsname, - params=[Decl(Type("int32_t"), routingId.name)], + params=[Decl(Type("IPC::Message::routeid_t"), routingId.name)], ret=Type("mozilla::UniquePtr"), ) ) @@ -2144,53 +2136,38 @@ class _ParamTraits: Write and read callers will perform nullability validation.""" cxxtype = _cxxBareType(actortype, side, fq=True) + basetype = Type("mozilla::ipc::IProtocol", ptr=True) - write = StmtCode( - """ - MOZ_RELEASE_ASSERT( - ${writervar}->GetActor(), - "Cannot serialize managed actors without an actor"); - - int32_t id; - if (!${var}) { - id = 0; // kNullActorId - } else { - id = ${var}->Id(); - if (id == 1) { // kFreedActorId - ${var}->FatalError("Actor has been |delete|d"); - } - MOZ_RELEASE_ASSERT( - ${writervar}->GetActor()->GetIPCChannel() == ${var}->GetIPCChannel(), - "Actor must be from the same channel as the" - " actor it's being sent over"); - MOZ_RELEASE_ASSERT( - ${var}->CanSend(), - "Actor must still be open when sending"); - } - - ${write}; - """, - var=cls.var, - writervar=cls.writervar, - write=cls.write(ExprVar("id"), cls.writervar), + # void Write(..) impl - Write actor as IProtocol* + write = cls.checkedWrite( + None, + ExprCast(cls.var, basetype, static=True), + cls.writervar, + sentinelKey=actortype.name(), ) - # bool Read(..) impl + # bool Read(..) impl - Read actor as IProtocol* read = StmtCode( """ - MOZ_RELEASE_ASSERT( - ${readervar}->GetActor(), - "Cannot deserialize managed actors without an actor"); - mozilla::Maybe actor = ${readervar}->GetActor() - ->ReadActor(${readervar}, true, ${actortype}, ${protocolid}); - if (actor.isSome()) { - return static_cast<${cxxtype}>(actor.ref()); + ${read} + if (actor && actor->GetProtocolId() != ${protocolid}) { + ${typeerror} + return {}; } - return {}; + return static_cast<${cxxtype}>(actor); """, - readervar=cls.readervar, - actortype=ExprLiteral.String(actortype.name()), + read=cls._checkedRead( + None, + basetype, + ExprVar("actor"), + sentinelKey=actortype.name(), + what="managed " + actortype.name() + " actor", + ), protocolid=_protocolId(actortype), + typeerror=cls.fatalError( + cls.readervar, + "Unexpected actor type (expected " + actortype.name() + ")", + ), cxxtype=cxxtype, ) @@ -3350,7 +3327,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): self.nonForwardDeclaredHeaders = set() self.typedefSet = set( [ - Typedef(Type("mozilla::ipc::ActorHandle"), "ActorHandle"), + Typedef(Type("mozilla::ipc::ActorId"), "ActorId"), Typedef(Type("base::ProcessId"), "ProcessId"), Typedef(Type("mozilla::ipc::ProtocolId"), "ProtocolId"), Typedef(Type("mozilla::ipc::Endpoint"), "Endpoint", ["FooSide"]), @@ -4034,8 +4011,8 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): # for ctor recv cases, we can't read the actor ID into a PFoo* # because it doesn't exist on this side yet. Use a "special" # actor handle instead - handlevar = ExprVar("handle__") - self.handlevar = handlevar + actoridvar = ExprVar("actorid__") + self.actoridvar = actoridvar msgtype = ExprCode("msg__.type()") self.asyncSwitch = StmtSwitch(msgtype) @@ -4130,7 +4107,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): method.addcode( """ - int32_t route__ = ${msgvar}.routing_id(); + IPC::Message::routeid_t route__ = ${msgvar}.routing_id(); if (MSG_ROUTING_CONTROL != route__) { IProtocol* routed__ = Lookup(route__); if (!routed__ || !routed__->GetLifecycleProxy()) { @@ -4762,7 +4739,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): def genCtorRecvCase(self, md): lbl = CaseLabel(md.pqMsgId()) case = StmtBlock() - actorhandle = self.handlevar stmts = self.deserializeMessage( md, self.side, errfnRecv, errfnSent=errfnSentinel(_Result.ValuError) @@ -4778,7 +4754,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): # alloc the actor, register it under the foreign ID + [self.callAllocActor(md, retsems="in", side=self.side)] + self.bindManagedActor( - md.actorDecl(), errfn=_Result.ValuError, idexpr=_actorHId(actorhandle) + md.actorDecl(), errfn=_Result.ValuError, idexpr=self.actoridvar ) + [Whitespace.NL] + saveIdStmts @@ -4847,33 +4823,45 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): def makeMessage(self, md, errfn, fromActor=None): msgvar = self.msgvar writervar = ExprVar("writer__") + isctor = md.decl.type.isCtor() routingId = self.protocol.routingId(fromActor) this = fromActor or ExprVar.THIS - stmts = ( - [ - StmtDecl( - Decl(Type("UniquePtr"), msgvar.name), - init=ExprCall(ExprVar(md.pqMsgCtorFunc()), args=[routingId]), - ), - StmtDecl( - Decl(Type("IPC::MessageWriter"), writervar.name), - initargs=[ExprDeref(msgvar), this], - ), - ] - + [Whitespace.NL] - + [ + stmts = [ + StmtDecl( + Decl(Type("UniquePtr"), msgvar.name), + init=ExprCall(ExprVar(md.pqMsgCtorFunc()), args=[routingId]), + ), + StmtDecl( + Decl(Type("IPC::MessageWriter"), writervar.name), + initargs=[ExprDeref(msgvar), this], + ), + Whitespace.NL, + ] + + start = 0 + if isctor: + # serialize the actor as the raw actor ID so that it can be used to + # construct the "real" actor on the other side. + stmts += [ _ParamTraits.checkedWrite( - p.ipdltype, - p.var(), + None, + _actorId(ExprVar("actor")), ExprAddrOf(writervar), - sentinelKey=p.name, + sentinelKey="actorid", ) - for p in md.params ] - + [Whitespace.NL] - + self.setMessageFlags(md, msgvar) - ) + start = 1 + + stmts += [ + _ParamTraits.checkedWrite( + p.ipdltype, + p.var(), + ExprAddrOf(writervar), + sentinelKey=p.name, + ) + for p in md.params[start:] + ] return msgvar, stmts def makeResolver(self, md, errfn, routingId): @@ -4964,20 +4952,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): ) for r in md.returns ] - + self.setMessageFlags(md, replyvar) + [self.logMessage(md, replyvar, "Sending reply ")] ) - def setMessageFlags(self, md, var, seqno=None): - stmts = [] - - if seqno: - stmts.append( - StmtExpr(ExprCall(ExprSelect(var, "->", "set_seqno"), args=[seqno])) - ) - - return stmts + [Whitespace.NL] - def deserializeMessage(self, md, side, errfn, errfnSent): msgvar = self.msgvar msgexpr = ExprAddrOf(msgvar) @@ -4996,17 +4973,17 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): if isctor: # return the raw actor handle so that its ID can be used # to construct the "real" actor - handlevar = self.handlevar - handletype = Type("ActorHandle") + actoridvar = self.actoridvar + actoridtype = _actorIdType() reads = [ _ParamTraits.checkedRead( None, - handletype, - handlevar, + actoridtype, + actoridvar, ExprAddrOf(readervar), errfn, - "'%s'" % handletype.name, - sentinelKey="actor", + "'%s'" % actoridtype.name, + sentinelKey="actorid", errfnSentinel=errfnSent, ) ] @@ -5066,27 +5043,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): StmtReturn(errcode), ] - start, reads = 0, [] - if md.decl.type.isCtor(): - # return the raw actor handle so that its ID can be used - # to construct the "real" actor - handlevar = self.handlevar - handletype = Type("ActorHandle") - reads = [ - _ParamTraits.checkedRead( - None, - handletype, - handlevar, - readervar, - errfn, - "'%s'" % handletype.name, - sentinelKey="actor", - errfnSentinel=errfnSentinel(_Result.ValuError), - ) - ] - start = 1 - - reads += [ + reads = [ _ParamTraits.checkedRead( p.ipdltype, p.bareType(side), @@ -5097,7 +5054,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): sentinelKey=p.name, errfnSentinel=errfnSentinel(_Result.ValuError), ) - for p in md.returns[start:] + for p in md.returns ] if len(md.returns) > 1: @@ -5185,7 +5142,12 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): if actor is not None: send = ExprSelect(actor, "->", send.name) if md.returns: - stmts.append(StmtDecl(Decl(Type.INT32, seqno.name), init=ExprLiteral.ZERO)) + stmts.append( + StmtDecl( + Decl(Type("IPC::Message::seqno_t"), seqno.name), + init=ExprLiteral.ZERO, + ) + ) ifsendok = StmtIf( ExprCall(send, args=[ExprMove(msgexpr), ExprAddrOf(seqno)]) ) diff --git a/tools/fuzzing/ipc/IPCFuzzController.cpp b/tools/fuzzing/ipc/IPCFuzzController.cpp index 60ed598114f0..ed802c6a31bb 100644 --- a/tools/fuzzing/ipc/IPCFuzzController.cpp +++ b/tools/fuzzing/ipc/IPCFuzzController.cpp @@ -326,52 +326,53 @@ void IPCFuzzController::OnActorConnected(IProtocol* protocol) { Maybe portName = channel->GetPortName(); if (!portName) { - MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %d Protocol: %s\n", + MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64 + " Protocol: %s\n", protocol->Id(), protocol->GetProtocolName()); } if (portName) { if (!protoIdFilter.empty()) { if (!strcmp(protocol->GetProtocolName(), protoIdFilter.c_str())) { - MOZ_FUZZING_NYX_PRINTF( - "INFO: [OnActorConnected] ActorID %d Protocol: %s matches " - "target.\n", - protocol->Id(), protocol->GetProtocolName()); + MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64 + " Protocol: %s matches " + "target.\n", + protocol->Id(), protocol->GetProtocolName()); // If our matching protocol is not a toplevel actor, then we need to // exclude the toplevel protocol later in `MakeTargetDecision` because // the actor will always be added to the map. protoFilterTargetExcludeToplevel = protocol->Manager() != nullptr; } else if (actorIds[*portName].empty()) { - MOZ_FUZZING_NYX_PRINTF( - "INFO: [OnActorConnected] ActorID %d Protocol: %s is toplevel " - "actor.\n", - protocol->Id(), protocol->GetProtocolName()); + MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64 + " Protocol: %s is toplevel " + "actor.\n", + protocol->Id(), protocol->GetProtocolName()); } else if (allowSubActors && IsManagedByTargetActor(protocol, protoIdFilter)) { - MOZ_FUZZING_NYX_PRINTF( - "INFO: [OnActorConnected] ActorID %d Protocol: %s is managed by " - "target actor.\n", - protocol->Id(), protocol->GetProtocolName()); + MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64 + " Protocol: %s is managed by " + "target actor.\n", + protocol->Id(), protocol->GetProtocolName()); } else { // Not a toplevel actor, not matching the filter and also either not a // sub actor of our target or we are focusing only on the target. Ignore // this actor. if (!!getenv("MOZ_FUZZ_DEBUG")) { - MOZ_FUZZING_NYX_PRINTF( - "INFO: [OnActorConnected] ActorID %d Protocol: %s ignored due to " - "filter.\n", - protocol->Id(), protocol->GetProtocolName()); + MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64 + " Protocol: %s ignored due to " + "filter.\n", + protocol->Id(), protocol->GetProtocolName()); } return; } } if (!!getenv("MOZ_FUZZ_DEBUG")) { - MOZ_FUZZING_NYX_PRINTF( - "INFO: [OnActorConnected] ActorID %d Protocol: %s Port: %lu %lu\n", - protocol->Id(), protocol->GetProtocolName(), portName->v1, - portName->v2); + MOZ_FUZZING_NYX_PRINTF("INFO: [OnActorConnected] ActorID %" PRId64 + " Protocol: %s Port: %lu %lu\n", + protocol->Id(), protocol->GetProtocolName(), + portName->v1, portName->v2); } actorIds[*portName].emplace_back(protocol->Id(), protocol->GetProtocolId()); @@ -474,7 +475,8 @@ bool IPCFuzzController::ObserveIPCMessage(mozilla::ipc::NodeChannel* channel, } return true; } else if (aMessage.type() == mIPCTriggerMsg && !Nyx::instance().started()) { - MOZ_FUZZING_NYX_PRINTF("DEBUG: Ready message detected on actor %d.\n", + MOZ_FUZZING_NYX_PRINTF("DEBUG: Ready message detected on actor %" PRId64 + ".\n", aMessage.routing_id()); if (!haveTargetNodeName && !!getenv("MOZ_FUZZ_PROTOID_FILTER")) { @@ -504,7 +506,7 @@ bool IPCFuzzController::ObserveIPCMessage(mozilla::ipc::NodeChannel* channel, // In this mode, we really want to focus on a single actor. useLastActor = 1024; maybeLastActorId = aMessage.routing_id(); - MOZ_FUZZING_NYX_PRINTF("DEBUG: Pinned to actor %d forever.\n", + MOZ_FUZZING_NYX_PRINTF("DEBUG: Pinned to actor %" PRId64 " forever.\n", aMessage.routing_id()); } else { // In this mode, we want to focus on a particular actor and all of its @@ -644,8 +646,8 @@ bool IPCFuzzController::ObserveIPCMessage(mozilla::ipc::NodeChannel* channel, // Called on the I/O thread and modifies `portSeqNos`. MutexAutoLock lock(mMutex); portSeqNos.insert_or_assign( - name, std::pair(aMessage.seqno(), - userMsgEv->sequence_num())); + name, std::pair( + aMessage.seqno(), userMsgEv->sequence_num())); #ifdef FUZZ_DEBUG MOZ_FUZZING_NYX_PRINTF( "DEBUG: Port %lu %lu updated sequence number to %lu\n", name.v1, @@ -718,8 +720,9 @@ void IPCFuzzController::OnMessageError( bool IPCFuzzController::MakeTargetDecision( uint8_t portIndex, uint8_t portInstanceIndex, uint8_t actorIndex, uint8_t actorProtocolIndex, uint16_t typeOffset, PortName* name, - int32_t* seqno, uint64_t* fseqno, int32_t* actorId, uint32_t* type, - bool* is_cons, bool update) { + IPC::Message::seqno_t* seqno, uint64_t* fseqno, + mozilla::ipc::ActorId* actorId, uint32_t* type, bool* is_cons, + bool update) { if (useLastActor) { useLastActor--; *name = lastActorPortName; @@ -894,14 +897,15 @@ bool IPCFuzzController::MakeTargetDecision( MOZ_FUZZING_NYX_PRINTF( "DEBUG: MakeTargetDecision: Top-Level Protocol: %s Protocol: %s msgType: " - "%s (%u), Actor Instance %u of %zu, actor ID: %d, PreservedHeader: %d\n", + "%s (%u), Actor Instance %u of %zu, actor ID: %" PRId64 + ", PreservedHeader: %d\n", portNameToProtocolName[*name].c_str(), ProtocolIdToName(ids.second), IPC::StringFromIPCMessageType(*type), *type, actorIndex, actors.size(), *actorId, isPreserveHeader); if (update) { - portSeqNos.insert_or_assign(*name, - std::pair(*seqno, *fseqno)); + portSeqNos.insert_or_assign( + *name, std::pair(*seqno, *fseqno)); } return true; @@ -1048,7 +1052,7 @@ NS_IMETHODIMP IPCFuzzController::IPCFuzzLoop::Run() { // have to adjust these so the next calculated sequence number pair // matches the start sequence numbers. IPCFuzzController::instance().portSeqNos.insert_or_assign( - iter->first, std::pair(0, 0)); + iter->first, std::pair(0, 0)); IPCFuzzController::instance().AddToplevelActor( iter->first, iter->second[0].second); @@ -1139,10 +1143,10 @@ NS_IMETHODIMP IPCFuzzController::IPCFuzzLoop::Run() { ipchdr->payload_size = ipcMsgLen - sizeof(IPC::Message::Header); PortName new_port_name; - int32_t new_seqno; + IPC::Message::seqno_t new_seqno; uint64_t new_fseqno; - int32_t actorId; + mozilla::ipc::ActorId actorId; uint32_t msgType = 0; bool isConstructor = false; // Control Data Layout (16 byte) @@ -1575,7 +1579,7 @@ UniquePtr IPCFuzzController::replaceIPCMessage( UniquePtr msg(new IPC::Message(ipcMsgData, ipcMsgLen)); if (!!getenv("MOZ_FUZZ_DEBUG")) { - MOZ_FUZZING_NYX_PRINTF("INFO: Name: %s Target: %d\n", msg->name(), + MOZ_FUZZING_NYX_PRINTF("INFO: Name: %s Target: %" PRId64 "\n", msg->name(), msg->routing_id()); } diff --git a/tools/fuzzing/ipc/IPCFuzzController.h b/tools/fuzzing/ipc/IPCFuzzController.h index 539a13c26fd1..96a5d2ab1a8c 100644 --- a/tools/fuzzing/ipc/IPCFuzzController.h +++ b/tools/fuzzing/ipc/IPCFuzzController.h @@ -52,6 +52,7 @@ namespace ipc { // We can't include ProtocolUtils.h here class IProtocol; typedef IPCMessageStart ProtocolId; +typedef IPC::Message::routeid_t ActorId; class NodeChannel; } // namespace ipc @@ -59,9 +60,10 @@ class NodeChannel; namespace fuzzing { class IPCFuzzController { - typedef std::pair SeqNoPair; + typedef std::pair SeqNoPair; - typedef std::pair ActorIdPair; + typedef std::pair + ActorIdPair; class IPCFuzzLoop final : public Runnable { friend class IPCFuzzController; @@ -87,8 +89,9 @@ class IPCFuzzController { bool MakeTargetDecision(uint8_t portIndex, uint8_t portInstanceIndex, uint8_t actorIndex, uint8_t actorProtocolIndex, uint16_t typeOffset, - mojo::core::ports::PortName* name, int32_t* seqno, - uint64_t* fseqno, int32_t* actorId, uint32_t* type, + mojo::core::ports::PortName* name, + IPC::Message::seqno_t* seqno, uint64_t* fseqno, + mozilla::ipc::ActorId* actorId, uint32_t* type, bool* is_cons, bool update = true); void OnActorConnected(mozilla::ipc::IProtocol* protocol); @@ -159,7 +162,7 @@ class IPCFuzzController { Atomic useLastActor; // If this is non-zero, we want a specific actor ID instead of the last. - Atomic maybeLastActorId; + Atomic maybeLastActorId; // If this is non-empty and in certain configurations, we only use a fixed // set of messages, rather than sending any message type for that actor. diff --git a/xpcom/threads/nsThreadUtils.cpp b/xpcom/threads/nsThreadUtils.cpp index 0f6ebee34398..1dbc02ff1183 100644 --- a/xpcom/threads/nsThreadUtils.cpp +++ b/xpcom/threads/nsThreadUtils.cpp @@ -596,7 +596,7 @@ template <> void LogTaskBase::LogDispatchWithPid(IPC::Message* aEvent, int32_t aPid) { if (aEvent->seqno() && aPid > 0) { - LOG1(("SEND %p %d %d", aEvent, aEvent->seqno(), aPid)); + LOG1(("SEND %p %" PRId64 " %d", aEvent, aEvent->seqno(), aPid)); } } @@ -651,7 +651,7 @@ LogTaskBase::Run::Run(Task* aTask, bool aWillRunAgain) template <> LogTaskBase::Run::Run(IPC::Message* aMessage, bool aWillRunAgain) : mWillRunAgain(aWillRunAgain) { - LOG1(("RECV %p %p %d [%s]", aMessage, this, aMessage->seqno(), + LOG1(("RECV %p %p %" PRId64 " [%s]", aMessage, this, aMessage->seqno(), aMessage->name())); }