crashpad/doc/generated/doxygen/classcrashpad_1_1ChildPortHandshake.html
2015-10-08 14:55:01 -04:00

356 lines
23 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.9.1"/>
<title>Crashpad: crashpad::ChildPortHandshake Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
$(document).ready(function() { init_search(); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">Crashpad
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.9.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main&#160;Page</span></a></li>
<li><a href="pages.html"><span>Related&#160;Pages</span></a></li>
<li><a href="namespaces.html"><span>Namespaces</span></a></li>
<li class="current"><a href="annotated.html"><span>Classes</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
<li>
<div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</li>
</ul>
</div>
<div id="navrow2" class="tabs2">
<ul class="tablist">
<li><a href="annotated.html"><span>Class&#160;List</span></a></li>
<li><a href="classes.html"><span>Class&#160;Index</span></a></li>
<li><a href="hierarchy.html"><span>Class&#160;Hierarchy</span></a></li>
<li><a href="functions.html"><span>Class&#160;Members</span></a></li>
</ul>
</div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="namespacecrashpad.html">crashpad</a></li><li class="navelem"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html">ChildPortHandshake</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="summary">
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pub-static-methods">Static Public Member Functions</a> &#124;
<a href="#friends">Friends</a> &#124;
<a href="classcrashpad_1_1ChildPortHandshake-members.html">List of all members</a> </div>
<div class="headertitle">
<div class="title">crashpad::ChildPortHandshake Class Reference</div> </div>
</div><!--header-->
<div class="contents">
<p>Implements a handshake protocol that allows a parent process to obtain a Mach port right from a child process.
<a href="classcrashpad_1_1ChildPortHandshake.html#details">More...</a></p>
<p><code>#include &quot;util/mach/child_port_handshake.h&quot;</code></p>
<div class="dynheader">
Inheritance diagram for crashpad::ChildPortHandshake:</div>
<div class="dyncontent">
<div class="center">
<img src="classcrashpad_1_1ChildPortHandshake.png" usemap="#crashpad::ChildPortHandshake_map" alt=""/>
<map id="crashpad::ChildPortHandshake_map" name="crashpad::ChildPortHandshake_map">
<area href="classcrashpad_1_1ChildPortServer_1_1Interface.html" title="An interface that the request message that is a part of the child_port Mach subsystem can be dispatch..." alt="crashpad::ChildPortServer::Interface" shape="rect" coords="0,0,218,24"/>
</map>
</div></div>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:aa1dac94439be91816ba8dd0505809855"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#aa1dac94439be91816ba8dd0505809855">ChildPortHandshake</a> ()</td></tr>
<tr class="memdesc:aa1dac94439be91816ba8dd0505809855"><td class="mdescLeft">&#160;</td><td class="mdescRight">Initializes the server. <a href="#aa1dac94439be91816ba8dd0505809855">More...</a><br /></td></tr>
<tr class="separator:aa1dac94439be91816ba8dd0505809855"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3d7b5d2827a8354b48389e71f2f03223"><td class="memItemLeft" align="right" valign="top">int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a3d7b5d2827a8354b48389e71f2f03223">ReadPipeFD</a> () const </td></tr>
<tr class="memdesc:a3d7b5d2827a8354b48389e71f2f03223"><td class="mdescLeft">&#160;</td><td class="mdescRight">Obtains the “read” side of the pipe, to be used by the client. <a href="#a3d7b5d2827a8354b48389e71f2f03223">More...</a><br /></td></tr>
<tr class="separator:a3d7b5d2827a8354b48389e71f2f03223"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:afd67dca5fc51170a919501fdbcf0fd32"><td class="memItemLeft" align="right" valign="top">mach_port_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#afd67dca5fc51170a919501fdbcf0fd32">RunServer</a> ()</td></tr>
<tr class="memdesc:afd67dca5fc51170a919501fdbcf0fd32"><td class="mdescLeft">&#160;</td><td class="mdescRight">Runs the server. <a href="#afd67dca5fc51170a919501fdbcf0fd32">More...</a><br /></td></tr>
<tr class="separator:afd67dca5fc51170a919501fdbcf0fd32"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a756cb29fcc496c457c1df79a6c188849"><td class="memItemLeft" align="right" valign="top">kern_return_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a756cb29fcc496c457c1df79a6c188849">HandleChildPortCheckIn</a> (child_port_server_t server, child_port_token_t token, mach_port_t port, mach_msg_type_name_t right_type, const mach_msg_trailer_t *trailer, bool *destroy_request) override</td></tr>
<tr class="memdesc:a756cb29fcc496c457c1df79a6c188849"><td class="mdescLeft">&#160;</td><td class="mdescRight">Handles check-ins sent by <code>child_port_check_in()</code>. <a href="#a756cb29fcc496c457c1df79a6c188849">More...</a><br /></td></tr>
<tr class="separator:a756cb29fcc496c457c1df79a6c188849"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-static-methods"></a>
Static Public Member Functions</h2></td></tr>
<tr class="memitem:a013db6f4b1eab305b280b62f2ce8897c"><td class="memItemLeft" align="right" valign="top">static void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a013db6f4b1eab305b280b62f2ce8897c">RunClient</a> (int pipe_read, mach_port_t port, mach_msg_type_name_t right_type)</td></tr>
<tr class="memdesc:a013db6f4b1eab305b280b62f2ce8897c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Runs the client. <a href="#a013db6f4b1eab305b280b62f2ce8897c">More...</a><br /></td></tr>
<tr class="separator:a013db6f4b1eab305b280b62f2ce8897c"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="friends"></a>
Friends</h2></td></tr>
<tr class="memitem:abd5035bd503394e6b1ff4ff7f50fd62a"><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="abd5035bd503394e6b1ff4ff7f50fd62a"></a>
class&#160;</td><td class="memItemRight" valign="bottom"><b>test::ChildPortHandshakeTest</b></td></tr>
<tr class="separator:abd5035bd503394e6b1ff4ff7f50fd62a"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p>Implements a handshake protocol that allows a parent process to obtain a Mach port right from a child process. </p>
<p>Ordinarily, there is no way for parent and child processes to exchange port rights, outside of the rights that children inherit from their parents. These include task-special ports and exception ports, but all of these have system-defined uses, and cannot reliably be replaced: in a multi-threaded parent, it is impossible to temporarily change one an inheritable port while maintaining a guarantee that another thread will not attempt to use it, and in children, it difficult to guarantee that nothing will attempt to use an inheritable port before it can be replaced with the correct one. This latter concern is becoming increasingly more pronounced as system libraries perform more operations that rely on an inheritable port in module initializers.</p>
<p>The protocol implemented by this class involves a server that runs in the parent process. The server is published with the bootstrap server, which the child has access to because the bootstrap port is one of the inherited task-special ports. The parent and child also share a pipe, which the parent can write to and the child can read from. After launching a child process, the parent will write a random token to this pipe, along with the name under which its server has been registered with the bootstrap server. The child can then obtain a send right to this server with <code>bootstrap_look_up()</code>, and send a check-in message containing the token value and the port right of its choice by calling <code>child_port_check_in()</code>.</p>
<p>The inclusion of the token authenticates the child to its parent. This is necessary because the service is published with the bootstrap server, which opens up access to it to more than the child process. Because the token is passed to the child by a shared pipe, it constitutes a shared secret not known by other processes that may have incidental access to the server. The <a class="el" href="classcrashpad_1_1ChildPortHandshake.html" title="Implements a handshake protocol that allows a parent process to obtain a Mach port right from a child...">ChildPortHandshake</a> server considers its randomly-generated token valid until a client checks in with it. This mechanism is used instead of examining the request messages audit trailer to verify the senders process ID because in some process architectures, it may be impossible to verify the childs process ID. This may happen when the child disassociates from the parent with a double fork(), and the actual client is the parents grandchild. In this case, the child would not check in, but the grandchild, in possession of the token, would check in.</p>
<p>The shared pipe serves another purpose: the server monitors it for an end-of-file (no readers) condition. Once detected, it will stop its blocking wait for a client to check in. This mechanism was chosen over monitoring a child process directly for exit to account for the possibility that the child might disassociate with a double fork().</p>
<p>This class can be used to allow a child process to provide its parent with a send right to its task port, in cases where it is desirable for the parent to have such access. It can also be used to allow a child process to establish its own server and provide its parent with a send right to that server, for cases where a service is provided and it is undesirable or impossible to provide it via the bootstrap or launchd interfaces. </p>
</div><h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a class="anchor" id="aa1dac94439be91816ba8dd0505809855"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">crashpad::ChildPortHandshake::ChildPortHandshake </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Initializes the server. </p>
<p>This creates the pipe so that the “read” side can be obtained by calling <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a3d7b5d2827a8354b48389e71f2f03223" title="Obtains the “read” side of the pipe, to be used by the client. ">ReadPipeFD()</a>. </p>
</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a class="anchor" id="a756cb29fcc496c457c1df79a6c188849"></a>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">kern_return_t crashpad::ChildPortHandshake::HandleChildPortCheckIn </td>
<td>(</td>
<td class="paramtype">child_port_server_t&#160;</td>
<td class="paramname"><em>server</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">child_port_token_t&#160;</td>
<td class="paramname"><em>token</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">mach_port_t&#160;</td>
<td class="paramname"><em>port</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">mach_msg_type_name_t&#160;</td>
<td class="paramname"><em>right_type</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">const mach_msg_trailer_t *&#160;</td>
<td class="paramname"><em>trailer</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">bool *&#160;</td>
<td class="paramname"><em>destroy_request</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">override</span><span class="mlabel">virtual</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Handles check-ins sent by <code>child_port_check_in()</code>. </p>
<p>This behaves equivalently to a <code>handle_child_port_check_in()</code> function used with <code>child_port_server()</code>.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramdir">[in]</td><td class="paramname">trailer</td><td>The trailer received with the request message. </td></tr>
<tr><td class="paramdir">[out]</td><td class="paramname">destroy_request</td><td><code>true</code> if the request message is to be destroyed even when this method returns success. See <a class="el" href="classcrashpad_1_1MachMessageServer_1_1Interface.html" title="A Mach RPC callback interface, called by Run(). ">MachMessageServer::Interface</a>. </td></tr>
</table>
</dd>
</dl>
<p>Implements <a class="el" href="classcrashpad_1_1ChildPortServer_1_1Interface.html#a5ecd466de45fe69854d37980b7373369">crashpad::ChildPortServer::Interface</a>.</p>
</div>
</div>
<a class="anchor" id="a3d7b5d2827a8354b48389e71f2f03223"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int crashpad::ChildPortHandshake::ReadPipeFD </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td> const</td>
</tr>
</table>
</div><div class="memdoc">
<p>Obtains the “read” side of the pipe, to be used by the client. </p>
<p>Callers must obtain this file descriptor and arrange for the caller to have access to it before calling <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#afd67dca5fc51170a919501fdbcf0fd32" title="Runs the server. ">RunServer()</a>.</p>
<dl class="section return"><dt>Returns</dt><dd>The file descriptor that the client should read from. </dd></dl>
</div>
</div>
<a class="anchor" id="a013db6f4b1eab305b280b62f2ce8897c"></a>
<div class="memitem">
<div class="memproto">
<table class="mlabels">
<tr>
<td class="mlabels-left">
<table class="memname">
<tr>
<td class="memname">void crashpad::ChildPortHandshake::RunClient </td>
<td>(</td>
<td class="paramtype">int&#160;</td>
<td class="paramname"><em>pipe_read</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">mach_port_t&#160;</td>
<td class="paramname"><em>port</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">mach_msg_type_name_t&#160;</td>
<td class="paramname"><em>right_type</em>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</td>
<td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span> </td>
</tr>
</table>
</div><div class="memdoc">
<p>Runs the client. </p>
<p>This function performs these tasks:</p><ul>
<li>Reads the token from the pipe.</li>
<li>Reads the bootstrap service name from the pipe.</li>
<li>Obtains a send right to the server by calling <code>bootstrap_look_up()</code>.</li>
<li>Sends a check-in message to the server by calling <code>child_port_check_in()</code>, providing the token and the user-supplied port right.</li>
<li>Deallocates the send right to the server, and closes the pipe.</li>
</ul>
<p>There is no return value because <code>child_port_check_in()</code> is a MIG <code>simpleroutine</code>, and the server does not send a reply. This allows check-in to occur without blocking to wait for a reply.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramdir">[in]</td><td class="paramname">pipe_read</td><td>The “read” side of the pipe shared with the server process. </td></tr>
<tr><td class="paramdir">[in]</td><td class="paramname">port</td><td>The port that will be passed to the server by <code>child_port_check_in()</code>. </td></tr>
<tr><td class="paramdir">[in]</td><td class="paramname">right_type</td><td>The right type to furnish the parent with. If <em>port</em> is a send right, this can be <code>MACH_MSG_TYPE_COPY_SEND</code> or <code>MACH_MSG_TYPE_MOVE_SEND</code>. If <em>port</em> is a send-once right, this can be <code>MACH_MSG_TYPE_MOVE_SEND_ONCE</code>. If <em>port</em> is a receive right, this can be <code>MACH_MSG_TYPE_MAKE_SEND</code>. <code>MACH_MSG_TYPE_MOVE_RECEIVE</code> is supported by the client interface but will be silently rejected by server run by <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#afd67dca5fc51170a919501fdbcf0fd32" title="Runs the server. ">RunServer()</a>, which expects to receive only send or send-once rights. </td></tr>
</table>
</dd>
</dl>
</div>
</div>
<a class="anchor" id="afd67dca5fc51170a919501fdbcf0fd32"></a>
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">mach_port_t crashpad::ChildPortHandshake::RunServer </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div><div class="memdoc">
<p>Runs the server. </p>
<p>This method performs these tasks:</p><ul>
<li>Closes the “read” side of the pipe in-process, so that the client process holds the only file descriptor that can read from the pipe.</li>
<li>Creates a random token and sends it via the pipe.</li>
<li>Checks its service in with the bootstrap server, and sends the name of its bootstrap service mapping via the pipe.</li>
<li>Simultaneously receives messages on its Mach server and monitors the pipe for end-of-file. This is a blocking operation.</li>
<li>When a Mach message is received, calls <a class="el" href="classcrashpad_1_1ChildPortHandshake.html#a756cb29fcc496c457c1df79a6c188849" title="Handles check-ins sent by child_port_check_in(). ">HandleChildPortCheckIn()</a> to interpret and validate it, and if the message is valid, returns the port right extracted from the message. If the message is not valid, this method will continue waiting for a valid message. Valid messages are properly formatted and have the correct token. If a valid message carries a send or send-once right, it will be returned. If a valid message contains a receive right, it will be destroyed and <code>MACH_PORT_NULL</code> will be returned. If a message is not valid, this method will continue waiting for pipe EOF or a valid message.</li>
<li>When notified of pipe EOF, returns <code>MACH_PORT_NULL</code>.</li>
<li>Regardless of return value, destroys the servers receive right and closes the pipe.</li>
</ul>
<dl class="section return"><dt>Returns</dt><dd>On success, the send or send-once right to the port provided by the client. The caller takes ownership of this right. On failure, <code>MACH_PORT_NULL</code>, indicating that the client did not check in properly before terminating, where termination is detected by noticing that the read side of the shared pipe has closed. On failure, a message indiciating the nature of the failure will be logged. </dd></dl>
</div>
</div>
<hr/>The documentation for this class was generated from the following files:<ul>
<li>util/mach/child_port_handshake.h</li>
<li>util/mach/child_port_handshake.cc</li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
</body>
</html>