• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SANDBOX_MAC_MACH_MESSAGE_SERVER_H_
6 #define SANDBOX_MAC_MACH_MESSAGE_SERVER_H_
7 
8 #include <dispatch/dispatch.h>
9 #include <mach/mach.h>
10 
11 #include "base/mac/scoped_mach_port.h"
12 #include "base/mac/scoped_mach_vm.h"
13 
14 namespace sandbox {
15 
16 // A delegate interface for MachMessageServer that handles processing of
17 // incoming intercepted IPC messages.
18 class MessageDemuxer {
19  public:
20   // Handle a |request| message and optionally create a |reply|. Both message
21   // objects are owned by the server. Use the server's methods to send a
22   // reply message.
23   virtual void DemuxMessage(mach_msg_header_t* request,
24                             mach_msg_header_t* reply) = 0;
25 
26  protected:
~MessageDemuxer()27   virtual ~MessageDemuxer() {}
28 };
29 
30 // A Mach message server that operates a receive port. Messages are received
31 // and then passed to the MessageDemuxer for handling. The Demuxer
32 // can use the server class to send a reply, forward the message to a
33 // different port, or reply to the message with a MIG error.
34 class MachMessageServer {
35  public:
36   // Creates a new Mach message server that will send messages to |demuxer|
37   // for handling. If the |server_receive_right| is non-NULL, this class will
38   // take ownership of the port and it will be used to receive messages.
39   // Otherwise the server will create a new receive right.
40   // The maximum size of messages is specified by |buffer_size|.
41   MachMessageServer(MessageDemuxer* demuxer,
42                     mach_port_t server_receive_right,
43                     mach_msg_size_t buffer_size);
44   ~MachMessageServer();
45 
46   // Initializes the class and starts running the message server. If this
47   // returns false, no other methods may be called on this class.
48   bool Initialize();
49 
50   // Given a received request message, returns the PID of the sending process.
51   pid_t GetMessageSenderPID(mach_msg_header_t* request);
52 
53   // Sends a reply message. Returns true if the message was sent successfully.
54   bool SendReply(mach_msg_header_t* reply);
55 
56   // Forwards the original |request| to the |destination| for handling.
57   void ForwardMessage(mach_msg_header_t* request, mach_port_t destination);
58 
59   // Replies to the message with the specified |error_code| as a MIG
60   // error_reply RetCode.
61   void RejectMessage(mach_msg_header_t* reply, int error_code);
62 
server_port()63   mach_port_t server_port() const { return server_port_.get(); }
64 
65  private:
66   // Event handler for the |server_source_| that reads a message from the queue
67   // and processes it.
68   void ReceiveMessage();
69 
70   // The demuxer delegate. Weak.
71   MessageDemuxer* demuxer_;
72 
73   // The Mach port on which the server is receiving requests.
74   base::mac::ScopedMachReceiveRight server_port_;
75 
76   // The dispatch queue used to service the server_source_.
77   dispatch_queue_t server_queue_;
78 
79   // A MACH_RECV dispatch source for the server_port_.
80   dispatch_source_t server_source_;
81 
82   // The size of the two message buffers below.
83   const mach_msg_size_t buffer_size_;
84 
85   // Request and reply buffers used in ReceiveMessage.
86   base::mac::ScopedMachVM request_buffer_;
87   base::mac::ScopedMachVM reply_buffer_;
88 
89   // Whether or not ForwardMessage() was called during ReceiveMessage().
90   bool did_forward_message_;
91 };
92 
93 }  // namespace sandbox
94 
95 #endif  // SANDBOX_MAC_MACH_MESSAGE_SERVER_H_
96