sandbox_ipc/windows/
mod.rs

1use ::io::{SendableFile, SendableSocket};
2use ::ser::{SerializeWrapper, SerializeWrapperGuard};
3
4extern crate mio_named_pipes;
5
6mod channel;
7mod sharedmem;
8mod sync;
9
10pub use self::channel::*;
11pub(crate) use self::sharedmem::*;
12pub(crate) use self::sync::*;
13
14use std::{io, fs, mem, ptr, fmt};
15use std::cell::RefCell;
16use std::borrow::Borrow;
17use std::sync::{Once, ONCE_INIT};
18use std::net::UdpSocket;
19use std::os::raw::{c_int, c_ulong, c_ushort, c_uchar};
20use std::os::windows::prelude::*;
21
22use serde::{Serialize, Deserialize, Serializer, Deserializer};
23use winapi::shared::ntdef::{HANDLE, WCHAR};
24use winapi::shared::guiddef::{GUID};
25use winapi::shared::minwindef::{DWORD, FALSE};
26use winapi::um::winnt::{DUPLICATE_CLOSE_SOURCE, DUPLICATE_SAME_ACCESS};
27use winapi::um::handleapi::{CloseHandle, DuplicateHandle};
28use winapi::um::processthreadsapi::{GetCurrentProcess, GetCurrentProcessId};
29use winapi::um::winsock2::{WSADuplicateSocketW, WSAGetLastError, WSASocketW};
30use winapi::um::winsock2::{INVALID_SOCKET};
31use winhandle::*;
32
33thread_local! {
34    static CURRENT_SERIALIZE_CHANNEL_REMOTE_PROCESS: RefCell<Option<HandleSender>> = RefCell::new(None);
35    static CURRENT_DESERIALIZE_CHANNEL_REMOTE_PROCESS: RefCell<Option<HandleReceiver>> = RefCell::new(None);
36}
37
38#[derive(Debug)]
39pub struct SendableWinHandle<B = WinHandle>(pub B);
40
41impl From<WinHandle> for SendableWinHandle {
42    fn from(h: WinHandle) -> Self { SendableWinHandle(h) }
43}
44
45impl<'a, B> Serialize for SendableWinHandle<&'a B> where
46    B: AsRawHandle,
47{
48    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
49        where S: Serializer
50    {
51        use serde::ser::Error;
52
53        CURRENT_SERIALIZE_CHANNEL_REMOTE_PROCESS.with(|sender_guard| {
54            let mut sender_guard = sender_guard.borrow_mut();
55            let sender = sender_guard.as_mut()
56                .ok_or_else(|| S::Error::custom("attempted to serialize handle outside of IPC channel"))?;
57            let remote_handle = sender.send(self.0.borrow().as_raw_handle())
58                .map_err(|x| S::Error::custom(x))?;
59            (remote_handle as usize).serialize(serializer)
60        })
61    }
62}
63
64impl Serialize for SendableWinHandle {
65    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
66        where S: Serializer
67    {
68        SendableWinHandle(&self.0).serialize(serializer)
69    }
70}
71
72impl<'de> Deserialize<'de> for SendableWinHandle {
73    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
74        where D: Deserializer<'de>
75    {
76        use serde::de::Error;
77
78        CURRENT_DESERIALIZE_CHANNEL_REMOTE_PROCESS.with(|receiver_guard| {
79            let mut receiver_guard = receiver_guard.borrow_mut();
80            let _receiver = receiver_guard.as_mut()
81                .ok_or_else(|| D::Error::custom("attempted to deserialize handle outside of IPC channel"))?;
82            let handle = usize::deserialize(deserializer)? as HANDLE;
83            let handle = WinHandle::from_raw(handle)
84                .ok_or_else(|| D::Error::custom("invalid Windows handle received"))?;
85            Ok(SendableWinHandle(handle))
86        })
87    }
88}
89
90impl<B> Serialize for SendableFile<B> where
91    B: Borrow<fs::File>,
92{
93    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
94        where S: Serializer
95    {
96        SendableWinHandle(self.0.borrow()).serialize(serializer)
97    }
98}
99
100impl<'de> Deserialize<'de> for SendableFile {
101    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
102        where D: Deserializer<'de>
103    {
104        let handle = SendableWinHandle::deserialize(deserializer)?;
105        Ok(SendableFile(unsafe { fs::File::from_raw_handle(handle.0.into_raw()) }))
106    }
107}
108
109impl<'a, T> Serialize for SendableSocket<T> where
110    T: AsRawSocket,
111{
112    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
113        where S: Serializer,
114    {
115        use serde::ser::Error;
116
117        CURRENT_SERIALIZE_CHANNEL_REMOTE_PROCESS.with(|sender_guard| {
118            let mut sender_guard = sender_guard.borrow_mut();
119            let sender = sender_guard.as_mut()
120                .ok_or_else(|| S::Error::custom("attempted to serialize handle outside of IPC channel"))?;
121            let proto_info = unsafe {
122                let mut proto_info: WsaProtoInfo = mem::zeroed();
123                if WSADuplicateSocketW(
124                    self.0.as_raw_socket() as usize,
125                    sender.remote_process_id().map_err(|x| S::Error::custom(x))?,
126                    &mut proto_info as *mut WsaProtoInfo as _,
127                ) != 0 {
128                    return Err(S::Error::custom(io::Error::from_raw_os_error(WSAGetLastError())));
129                }
130                proto_info
131            };
132            proto_info.serialize(serializer)
133        })
134    }
135}
136
137static CALLED_WSASTARTUP: Once = ONCE_INIT;
138
139impl<'de, T> Deserialize<'de> for SendableSocket<T> where
140    T: FromRawSocket,
141{
142    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
143        where D: Deserializer<'de>,
144    {
145        use serde::de::Error;
146
147        // Make sure we've called WSAStartup
148        CALLED_WSASTARTUP.call_once(|| {
149            // Any libstd socket operation will call WSAStartup
150            let _ = UdpSocket::bind("127.0.0.1:9999");
151        });
152
153        CURRENT_DESERIALIZE_CHANNEL_REMOTE_PROCESS.with(|receiver_guard| {
154            let mut receiver_guard = receiver_guard.borrow_mut();
155            let _receiver = receiver_guard.as_mut()
156                .ok_or_else(|| D::Error::custom("attempted to deserialize handle outside of IPC channel"))?;
157            let mut proto_info: WsaProtoInfo = WsaProtoInfo::deserialize(deserializer)?;
158            let raw_socket = unsafe { WSASocketW(
159                proto_info.iAddressFamily,
160                proto_info.iSocketType,
161                proto_info.iProtocol,
162                &mut proto_info as *mut WsaProtoInfo as _,
163                0,
164                0, // Flags are ignored when receiving sockets from another process
165            )};
166            if raw_socket == INVALID_SOCKET {
167                return Err(D::Error::custom(io::Error::from_raw_os_error(unsafe { WSAGetLastError() })));
168            }
169            Ok(SendableSocket(unsafe { T::from_raw_socket(raw_socket as RawSocket) }))
170        })
171    }
172}
173
174#[allow(bad_style)]
175#[repr(C)]
176#[derive(Serialize, Deserialize)]
177struct WsaProtoInfo {
178    dwServiceFlags1: DWORD,
179    dwServiceFlags2: DWORD,
180    dwServiceFlags3: DWORD,
181    dwServiceFlags4: DWORD,
182    dwProviderFlags: DWORD,
183    #[serde(with = "serde_guid")]
184    ProviderId: GUID,
185    dwCatalogEntryId: DWORD,
186    ProtocolChain: WsaProtocolChain,
187    iVersion: c_int,
188    iAddressFamily: c_int,
189    iMaxSockAddr: c_int,
190    iMinSockAddr: c_int,
191    iSocketType: c_int,
192    iProtocol: c_int,
193    iProtocolMaxOffset: c_int,
194    iNetworkByteOrder: c_int,
195    iSecurityScheme: c_int,
196    dwMessageSize: DWORD,
197    dwProviderReserved: DWORD,
198    #[serde(with = "serde_wchar256")]
199    szProtocol: [WCHAR; 256],
200}
201
202#[allow(bad_style)]
203#[repr(C)]
204#[derive(Serialize, Deserialize, Debug)]
205struct WsaProtocolChain {
206    ChainLen: c_int,
207    ChainEntries: [DWORD; 7],
208}
209
210mod serde_guid {
211    use super::*;
212
213    pub fn serialize<S>(f: &GUID, serializer: S) -> Result<S::Ok, S::Error> where
214        S: Serializer,
215    {
216        (f.Data1, f.Data2, f.Data3, f.Data4).serialize(serializer)
217    }
218
219    pub fn deserialize<'de, D>(deserializer: D) -> Result<GUID, D::Error> where
220        D: Deserializer<'de>,
221    {
222        let data: (c_ulong, c_ushort, c_ushort, [c_uchar; 8]) = Deserialize::deserialize(deserializer)?;
223        Ok(GUID {
224            Data1: data.0,
225            Data2: data.1,
226            Data3: data.2,
227            Data4: data.3,
228        })
229    }
230}
231
232mod serde_wchar256 {
233    use super::*;
234
235    pub fn serialize<S>(f: &[WCHAR; 256], serializer: S) -> Result<S::Ok, S::Error> where
236        S: Serializer,
237    {
238        use serde::ser::{SerializeTuple};
239
240        let mut serializer = serializer.serialize_tuple(256)?;
241        for wchar in f.iter() {
242            serializer.serialize_element::<WCHAR>(wchar)?;
243        }
244        serializer.end()
245    }
246
247    pub fn deserialize<'de, D>(deserializer: D) -> Result<[WCHAR; 256], D::Error> where
248        D: Deserializer<'de>,
249    {
250        use serde::de::{Visitor, SeqAccess, Error};
251
252        struct AVisitor;
253
254        impl<'de> Visitor<'de> for AVisitor {
255            type Value = [WCHAR; 256];
256
257            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
258                formatter.write_str("WCHAR string of length 256")
259            }
260
261            fn visit_seq<V>(self, mut seq: V) -> Result<[WCHAR; 256], V::Error>
262                where V: SeqAccess<'de>
263            {
264                let mut buffer: [WCHAR; 256] = [0; 256];
265                for (i, c) in buffer.iter_mut().enumerate() {
266                    let read_c: WCHAR = seq.next_element()?
267                              .ok_or_else(|| Error::invalid_length(i, &self))?;
268                    *c = read_c;
269                }
270                Ok(buffer)
271            }
272        }
273
274        deserializer.deserialize_tuple(256, AVisitor)
275    }
276}
277
278pub(crate) struct ChannelSerializeWrapper;
279
280impl<'a, C> SerializeWrapper<'a, C> for ChannelSerializeWrapper where
281    C: Channel,
282{
283    type SerializeGuard = ChannelSerializeGuard;
284    type DeserializeGuard = ChannelDeserializeGuard;
285
286    fn before_serialize(channel: &'a mut C) -> ChannelSerializeGuard {
287        let mut sender = Some(HandleSender {
288            target: unsafe { mem::transmute::<HandleTarget<&ProcessHandle>, HandleTarget<&'static ProcessHandle>>(channel.handle_target()) },
289            handles: Vec::new(),
290        });
291
292        CURRENT_SERIALIZE_CHANNEL_REMOTE_PROCESS.with(|x| 
293            mem::swap(
294                &mut *x.borrow_mut(),
295                &mut sender,
296            )
297        );
298        ChannelSerializeGuard(sender)
299    }
300
301    fn before_deserialize(_channel: &'a mut C) -> ChannelDeserializeGuard {
302        let mut receiver = Some(HandleReceiver);
303        CURRENT_DESERIALIZE_CHANNEL_REMOTE_PROCESS.with(|x|
304            mem::swap(
305                &mut *x.borrow_mut(),
306                &mut receiver,
307            )
308        );
309        ChannelDeserializeGuard(receiver)
310    }
311}
312
313pub(crate) struct ChannelSerializeGuard(Option<HandleSender>);
314
315impl Drop for ChannelSerializeGuard {
316    fn drop(&mut self) {
317        CURRENT_SERIALIZE_CHANNEL_REMOTE_PROCESS.with(|sender_guard| {
318            let mut sender_guard = sender_guard.borrow_mut();
319            *sender_guard = self.0.take()
320        });
321    }
322}
323
324impl<'a> SerializeWrapperGuard<'a> for ChannelSerializeGuard {
325    fn commit(self) {
326        CURRENT_SERIALIZE_CHANNEL_REMOTE_PROCESS.with(|sender_guard| {
327            let mut sender_guard = sender_guard.borrow_mut();
328            sender_guard.as_mut().unwrap().handles.clear();
329        });
330    }
331}
332
333pub(crate) struct ChannelDeserializeGuard(Option<HandleReceiver>);
334
335impl Drop for ChannelDeserializeGuard {
336    fn drop(&mut self) {
337        CURRENT_DESERIALIZE_CHANNEL_REMOTE_PROCESS.with(|x| *x.borrow_mut() = self.0.take());
338    }
339}
340
341impl<'a> SerializeWrapperGuard<'a> for ChannelDeserializeGuard {
342    fn commit(self) {
343    }
344}
345
346pub(crate) trait Channel {
347    fn handle_target(&self) -> HandleTarget<&ProcessHandle>;
348}
349
350struct HandleSender {
351    target: HandleTarget<&'static ProcessHandle>,
352    handles: Vec<HANDLE>,
353}
354
355impl Drop for HandleSender {
356    fn drop(&mut self) {
357        // If this is called without self.handles being empty, there was a failure somewhere and
358        // we should close all the handles we sent.
359        match self.target {
360            HandleTarget::CurrentProcess => {
361                for &handle in self.handles.iter() {
362                    unsafe { CloseHandle(handle); }
363                }
364            },
365            HandleTarget::RemoteProcess(process_handle) => {
366                for &handle in self.handles.iter() {
367                    if unsafe { DuplicateHandle(
368                        process_handle.handle.0.get(), handle,
369                        ptr::null_mut(), ptr::null_mut(),
370                        0, FALSE, DUPLICATE_CLOSE_SOURCE,
371                    ) } == FALSE {
372                        error!("Closing remote handle via DuplicateHandle failed: {}", io::Error::last_os_error());
373                    }
374                }
375            },
376            HandleTarget::None => {},
377        }
378    }
379}
380
381struct HandleReceiver;
382
383impl HandleSender {
384    fn send(&mut self, handle: HANDLE) -> io::Result<HANDLE> {
385        let remote_process_handle = match self.target {
386            HandleTarget::CurrentProcess => unsafe { GetCurrentProcess() },
387            HandleTarget::RemoteProcess(remote) => remote.handle.0.get(),
388            HandleTarget::None => return Err(io::Error::new(io::ErrorKind::BrokenPipe, "this pipe is not configured to send handles")),
389        };
390
391        unsafe {
392            let mut remote_handle = ptr::null_mut();
393            winapi_bool_call!(log: DuplicateHandle(
394                GetCurrentProcess(), handle,
395                remote_process_handle, &mut remote_handle,
396                0, FALSE, DUPLICATE_SAME_ACCESS,
397            ))?;
398
399            self.handles.push(remote_handle);
400
401            Ok(remote_handle)
402        }
403    }
404
405    fn remote_process_id(&self) -> io::Result<DWORD> {
406        Ok(match self.target {
407            HandleTarget::CurrentProcess => unsafe { GetCurrentProcessId() },
408            HandleTarget::RemoteProcess(remote) => remote.id,
409            HandleTarget::None => return Err(io::Error::new(io::ErrorKind::BrokenPipe, "this pipe is not configured to send handles")),
410        })
411    }
412}