1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <limits> 12 #include <memory> 13 #include <string> 14 #include <vector> 15 16 #include "base/callback.h" 17 #include "base/compiler_specific.h" 18 #include "base/component_export.h" 19 #include "base/logging.h" 20 #include "base/memory/ptr_util.h" 21 #include "mojo/public/cpp/bindings/lib/buffer.h" 22 #include "mojo/public/cpp/bindings/lib/message_internal.h" 23 #include "mojo/public/cpp/bindings/lib/unserialized_message_context.h" 24 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" 25 #include "mojo/public/cpp/system/message.h" 26 27 namespace mojo { 28 29 class AssociatedGroupController; 30 31 using ReportBadMessageCallback = 32 base::OnceCallback<void(const std::string& error)>; 33 34 // Message is a holder for the data and handles to be sent over a MessagePipe. 35 // Message owns its data and handles, but a consumer of Message is free to 36 // mutate the data and handles. The message's data is comprised of a header 37 // followed by payload. 38 class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) Message { 39 public: 40 static const uint32_t kFlagExpectsResponse = 1 << 0; 41 static const uint32_t kFlagIsResponse = 1 << 1; 42 static const uint32_t kFlagIsSync = 1 << 2; 43 44 // Constructs an uninitialized Message object. 45 Message(); 46 47 // See the move-assignment operator below. 48 Message(Message&& other); 49 50 // Constructs a new message with an unserialized context attached. This 51 // message may be serialized later if necessary. 52 explicit Message( 53 std::unique_ptr<internal::UnserializedMessageContext> context); 54 55 // Constructs a new serialized Message object with optional handles attached. 56 // This message is fully functional and may be exchanged for a 57 // ScopedMessageHandle for transit over a message pipe. See TakeMojoMessage(). 58 // 59 // If |handles| is non-null, any handles in |*handles| are attached to the 60 // newly constructed message. 61 // 62 // Note that |payload_size| is only the initially known size of the message 63 // payload, if any. The payload can be expanded after construction using the 64 // interface returned by |payload_buffer()|. 65 Message(uint32_t name, 66 uint32_t flags, 67 size_t payload_size, 68 size_t payload_interface_id_count, 69 std::vector<ScopedHandle>* handles); 70 71 // Constructs a new serialized Message object from an existing 72 // ScopedMessageHandle; e.g., one read from a message pipe. 73 // 74 // If the message had any handles attached, they will be extracted and 75 // retrievable via |handles()|. Such messages may NOT be sent back over 76 // another message pipe, but are otherwise safe to inspect and pass around. 77 Message(ScopedMessageHandle handle); 78 79 ~Message(); 80 81 // Moves |other| into a new Message object. The moved-from Message becomes 82 // invalid and is effectively in a default-constructed state after this call. 83 Message& operator=(Message&& other); 84 85 // Resets the Message to an uninitialized state. Upon reset, the Message 86 // exists as if it were default-constructed: it has no data buffer and owns no 87 // handles. 88 void Reset(); 89 90 // Indicates whether this Message is uninitialized. 91 bool IsNull() const { return !handle_.is_valid(); } 92 93 // Indicates whether this Message is serialized. 94 bool is_serialized() const { return serialized_; } 95 96 // Access the raw bytes of the message. 97 const uint8_t* data() const { 98 DCHECK(payload_buffer_.is_valid()); 99 return static_cast<const uint8_t*>(payload_buffer_.data()); 100 } 101 uint8_t* mutable_data() { return const_cast<uint8_t*>(data()); } 102 103 size_t data_num_bytes() const { 104 DCHECK(payload_buffer_.is_valid()); 105 return payload_buffer_.cursor(); 106 } 107 108 // Access the header. 109 const internal::MessageHeader* header() const { 110 return reinterpret_cast<const internal::MessageHeader*>(data()); 111 } 112 internal::MessageHeader* header() { 113 return reinterpret_cast<internal::MessageHeader*>(mutable_data()); 114 } 115 116 const internal::MessageHeaderV1* header_v1() const { 117 DCHECK_GE(version(), 1u); 118 return reinterpret_cast<const internal::MessageHeaderV1*>(data()); 119 } 120 internal::MessageHeaderV1* header_v1() { 121 DCHECK_GE(version(), 1u); 122 return reinterpret_cast<internal::MessageHeaderV1*>(mutable_data()); 123 } 124 125 const internal::MessageHeaderV2* header_v2() const { 126 DCHECK_GE(version(), 2u); 127 return reinterpret_cast<const internal::MessageHeaderV2*>(data()); 128 } 129 internal::MessageHeaderV2* header_v2() { 130 DCHECK_GE(version(), 2u); 131 return reinterpret_cast<internal::MessageHeaderV2*>(mutable_data()); 132 } 133 134 uint32_t version() const { return header()->version; } 135 136 uint32_t interface_id() const { return header()->interface_id; } 137 void set_interface_id(uint32_t id) { header()->interface_id = id; } 138 139 uint32_t name() const { return header()->name; } 140 bool has_flag(uint32_t flag) const { return !!(header()->flags & flag); } 141 142 // Access the request_id field (if present). 143 uint64_t request_id() const { return header_v1()->request_id; } 144 void set_request_id(uint64_t request_id) { 145 header_v1()->request_id = request_id; 146 } 147 148 // Access the payload. 149 const uint8_t* payload() const; 150 uint8_t* mutable_payload() { return const_cast<uint8_t*>(payload()); } 151 uint32_t payload_num_bytes() const; 152 153 uint32_t payload_num_interface_ids() const; 154 const uint32_t* payload_interface_ids() const; 155 156 internal::Buffer* payload_buffer() { return &payload_buffer_; } 157 158 // Access the handles of a received message. Note that these are unused on 159 // outgoing messages. 160 const std::vector<ScopedHandle>* handles() const { return &handles_; } 161 std::vector<ScopedHandle>* mutable_handles() { return &handles_; } 162 163 const std::vector<ScopedInterfaceEndpointHandle>* 164 associated_endpoint_handles() const { 165 return &associated_endpoint_handles_; 166 } 167 std::vector<ScopedInterfaceEndpointHandle>* 168 mutable_associated_endpoint_handles() { 169 return &associated_endpoint_handles_; 170 } 171 172 // Takes ownership of any handles within |*context| and attaches them to this 173 // Message. 174 void AttachHandlesFromSerializationContext( 175 internal::SerializationContext* context); 176 177 // Takes a scoped MessageHandle which may be passed to |WriteMessageNew()| for 178 // transmission. Note that this invalidates this Message object, taking 179 // ownership of its internal storage and any attached handles. 180 ScopedMessageHandle TakeMojoMessage(); 181 182 // Notifies the system that this message is "bad," in this case meaning it was 183 // rejected by bindings validation code. 184 void NotifyBadMessage(const std::string& error); 185 186 // Serializes |associated_endpoint_handles_| into the payload_interface_ids 187 // field. 188 void SerializeAssociatedEndpointHandles( 189 AssociatedGroupController* group_controller); 190 191 // Deserializes |associated_endpoint_handles_| from the payload_interface_ids 192 // field. 193 bool DeserializeAssociatedEndpointHandles( 194 AssociatedGroupController* group_controller); 195 196 // If this Message has an unserialized message context attached, force it to 197 // be serialized immediately. Otherwise this does nothing. 198 void SerializeIfNecessary(); 199 200 // Takes the unserialized message context from this Message if its tag matches 201 // |tag|. 202 std::unique_ptr<internal::UnserializedMessageContext> TakeUnserializedContext( 203 const internal::UnserializedMessageContext::Tag* tag); 204 205 template <typename MessageType> 206 std::unique_ptr<MessageType> TakeUnserializedContext() { 207 auto generic_context = TakeUnserializedContext(&MessageType::kMessageTag); 208 if (!generic_context) 209 return nullptr; 210 return base::WrapUnique( 211 generic_context.release()->template SafeCast<MessageType>()); 212 } 213 214 #if defined(ENABLE_IPC_FUZZER) 215 const char* interface_name() const { return interface_name_; } 216 void set_interface_name(const char* interface_name) { 217 interface_name_ = interface_name; 218 } 219 220 const char* method_name() const { return method_name_; } 221 void set_method_name(const char* method_name) { method_name_ = method_name; } 222 #endif 223 224 private: 225 ScopedMessageHandle handle_; 226 227 // A Buffer which may be used to allocate blocks of data within the message 228 // payload for reading or writing. 229 internal::Buffer payload_buffer_; 230 231 std::vector<ScopedHandle> handles_; 232 std::vector<ScopedInterfaceEndpointHandle> associated_endpoint_handles_; 233 234 // Indicates whether this Message object is transferable, i.e. can be sent 235 // elsewhere. In general this is true unless |handle_| is invalid or 236 // serialized handles have been extracted from the serialized message object 237 // identified by |handle_|. 238 bool transferable_ = false; 239 240 // Indicates whether this Message object is serialized. 241 bool serialized_ = false; 242 243 #if defined(ENABLE_IPC_FUZZER) 244 const char* interface_name_ = nullptr; 245 const char* method_name_ = nullptr; 246 #endif 247 248 DISALLOW_COPY_AND_ASSIGN(Message); 249 }; 250 251 class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) MessageReceiver { 252 public: 253 virtual ~MessageReceiver() {} 254 255 // Indicates whether the receiver prefers to receive serialized messages. 256 virtual bool PrefersSerializedMessages(); 257 258 // The receiver may mutate the given message. Returns true if the message 259 // was accepted and false otherwise, indicating that the message was invalid 260 // or malformed. 261 virtual bool Accept(Message* message) WARN_UNUSED_RESULT = 0; 262 }; 263 264 class MessageReceiverWithResponder : public MessageReceiver { 265 public: 266 ~MessageReceiverWithResponder() override {} 267 268 // A variant on Accept that registers a MessageReceiver (known as the 269 // responder) to handle the response message generated from the given 270 // message. The responder's Accept method may be called during 271 // AcceptWithResponder or some time after its return. 272 virtual bool AcceptWithResponder(Message* message, 273 std::unique_ptr<MessageReceiver> responder) 274 WARN_UNUSED_RESULT = 0; 275 }; 276 277 // A MessageReceiver that is also able to provide status about the state 278 // of the underlying MessagePipe to which it will be forwarding messages 279 // received via the |Accept()| call. 280 class MessageReceiverWithStatus : public MessageReceiver { 281 public: 282 ~MessageReceiverWithStatus() override {} 283 284 // Returns |true| if this MessageReceiver is currently bound to a MessagePipe, 285 // the pipe has not been closed, and the pipe has not encountered an error. 286 virtual bool IsConnected() = 0; 287 288 // Determines if this MessageReceiver is still bound to a message pipe and has 289 // not encountered any errors. This is asynchronous but may be called from any 290 // sequence. |callback| is eventually invoked from an arbitrary sequence with 291 // the result of the query. 292 virtual void IsConnectedAsync(base::OnceCallback<void(bool)> callback) = 0; 293 }; 294 295 // An alternative to MessageReceiverWithResponder for cases in which it 296 // is necessary for the implementor of this interface to know about the status 297 // of the MessagePipe which will carry the responses. 298 class MessageReceiverWithResponderStatus : public MessageReceiver { 299 public: 300 ~MessageReceiverWithResponderStatus() override {} 301 302 // A variant on Accept that registers a MessageReceiverWithStatus (known as 303 // the responder) to handle the response message generated from the given 304 // message. Any of the responder's methods (Accept or IsValid) may be called 305 // during AcceptWithResponder or some time after its return. 306 virtual bool AcceptWithResponder(Message* message, 307 std::unique_ptr<MessageReceiverWithStatus> 308 responder) WARN_UNUSED_RESULT = 0; 309 }; 310 311 class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) PassThroughFilter 312 : public MessageReceiver { 313 public: 314 PassThroughFilter(); 315 ~PassThroughFilter() override; 316 317 // MessageReceiver: 318 bool Accept(Message* message) override; 319 320 private: 321 DISALLOW_COPY_AND_ASSIGN(PassThroughFilter); 322 }; 323 324 namespace internal { 325 class SyncMessageResponseSetup; 326 } 327 328 // An object which should be constructed on the stack immediately before making 329 // a sync request for which the caller wishes to perform custom validation of 330 // the response value(s). It is illegal to make more than one sync call during 331 // the lifetime of the topmost SyncMessageResponseContext, but it is legal to 332 // nest contexts to support reentrancy. 333 // 334 // Usage should look something like: 335 // 336 // SyncMessageResponseContext response_context; 337 // foo_interface->SomeSyncCall(&response_value); 338 // if (response_value.IsBad()) 339 // response_context.ReportBadMessage("Bad response_value!"); 340 // 341 class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) SyncMessageResponseContext { 342 public: 343 SyncMessageResponseContext(); 344 ~SyncMessageResponseContext(); 345 346 static SyncMessageResponseContext* current(); 347 348 void ReportBadMessage(const std::string& error); 349 350 ReportBadMessageCallback GetBadMessageCallback(); 351 352 private: 353 friend class internal::SyncMessageResponseSetup; 354 355 SyncMessageResponseContext* outer_context_; 356 Message response_; 357 358 DISALLOW_COPY_AND_ASSIGN(SyncMessageResponseContext); 359 }; 360 361 // Read a single message from the pipe. The caller should have created the 362 // Message, but not called Initialize(). Returns MOJO_RESULT_SHOULD_WAIT if 363 // the caller should wait on the handle to become readable. Returns 364 // MOJO_RESULT_OK if the message was read successfully and should be 365 // dispatched, otherwise returns an error code if something went wrong. 366 // 367 // NOTE: The message hasn't been validated and may be malformed! 368 COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) 369 MojoResult ReadMessage(MessagePipeHandle handle, Message* message); 370 371 // Reports the currently dispatching Message as bad. Note that this is only 372 // legal to call from directly within the stack frame of a message dispatch. If 373 // you need to do asynchronous work before you can determine the legitimacy of 374 // a message, use GetBadMessageCallback() and retain its result until you're 375 // ready to invoke or discard it. 376 COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) 377 void ReportBadMessage(const std::string& error); 378 379 // Acquires a callback which may be run to report the currently dispatching 380 // Message as bad. Note that this is only legal to call from directly within the 381 // stack frame of a message dispatch, but the returned callback may be called 382 // exactly once any time thereafter to report the message as bad. This may only 383 // be called once per message. 384 COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) 385 ReportBadMessageCallback GetBadMessageCallback(); 386 387 } // namespace mojo 388 389 #endif // MOJO_PUBLIC_CPP_BINDINGS_MESSAGE_H_ 390