Skip to content

Commit f2baf3b

Browse files
epilysstsquad
authored andcommitted
xen-store: add SAFETY docs to unsafe {} blocks
Signed-off-by: Manos Pitsidianakis <[email protected]>
1 parent 116f7d3 commit f2baf3b

File tree

1 file changed

+88
-83
lines changed

1 file changed

+88
-83
lines changed

xen-store/src/xs.rs

Lines changed: 88 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,11 @@ use std::{
1717
mem,
1818
net::Shutdown,
1919
os::unix::{io::AsRawFd, net::UnixStream},
20-
slice,
2120
sync::{Arc, Condvar, Mutex},
2221
thread,
2322
thread::JoinHandle,
2423
};
2524

26-
use libc::writev;
2725
use nix::libc::iovec;
2826
use vmm_sys_util::eventfd::{EventFd, EFD_SEMAPHORE};
2927
use xen_bindings::bindings::xs_watch_type;
@@ -71,78 +69,79 @@ fn thread_function(
7169
Condvar,
7270
)>,
7371
) -> Result<(), std::io::Error> {
74-
let xen_socket_msg_size = mem::size_of::<XenSocketMessage>();
75-
7672
loop {
7773
let mut xen_socket_reply_msg = XenSocketMessage::default();
7874
let mut buffer: Vec<u8> = vec![0];
7975
let mut condvar = reply_condvar.clone();
8076
let mut eventfd: Option<EventFd> = None;
8177

82-
unsafe {
83-
let xen_socket_reply_msg_slice = slice::from_raw_parts_mut(
84-
&mut xen_socket_reply_msg as *mut _ as *mut u8,
85-
xen_socket_msg_size,
86-
);
78+
{
79+
// SAFETY: `xen_socket_reply_msg` is `XenSocketMessage` bytes sized.
80+
let xen_socket_reply_msg_slice: &mut [u8] = unsafe {
81+
std::slice::from_raw_parts_mut(
82+
std::ptr::addr_of_mut!(xen_socket_reply_msg).cast(),
83+
mem::size_of::<XenSocketMessage>(),
84+
)
85+
};
8786

8887
rx_socket.read_exact(xen_socket_reply_msg_slice)?;
88+
}
8989

90-
if xen_socket_reply_msg.r#type == XS_READ && xen_socket_reply_msg.len == 0 {
91-
queue_message(
92-
&condvar,
93-
eventfd,
94-
Ok(XenStoreMessage {
95-
r#type: xen_socket_reply_msg.r#type,
96-
body: "".to_string(),
97-
}),
98-
);
99-
continue;
100-
}
90+
if xen_socket_reply_msg.r#type == XS_READ && xen_socket_reply_msg.len == 0 {
91+
queue_message(
92+
&condvar,
93+
eventfd,
94+
Ok(XenStoreMessage {
95+
r#type: xen_socket_reply_msg.r#type,
96+
body: "".to_string(),
97+
}),
98+
);
99+
continue;
100+
}
101+
102+
buffer.resize(xen_socket_reply_msg.len as usize, 0);
103+
104+
rx_socket.read_exact(buffer.as_mut_slice())?;
105+
106+
if xen_socket_reply_msg.r#type != XS_READ
107+
&& xen_socket_reply_msg.r#type != XS_WRITE
108+
&& xen_socket_reply_msg.r#type != XS_WATCH
109+
&& xen_socket_reply_msg.r#type != XS_WATCH_EVENT
110+
&& xen_socket_reply_msg.r#type != XS_DIRECTORY
111+
{
112+
queue_message(
113+
&condvar,
114+
eventfd,
115+
Err(Error::new(ErrorKind::Other, "Xen Store transaction error")),
116+
);
117+
continue;
118+
}
101119

102-
buffer.resize(xen_socket_reply_msg.len as usize, 0);
120+
if xen_socket_reply_msg.r#type == XS_WATCH_EVENT {
121+
condvar = watch_condvar.clone();
122+
eventfd = Some(tx_eventfd.try_clone()?);
123+
}
103124

104-
rx_socket.read_exact(buffer.as_mut_slice())?;
125+
match String::from_utf8(buffer) {
126+
Ok(result) => {
127+
if result.len() != xen_socket_reply_msg.len as usize {
128+
queue_message(&condvar, eventfd, Err(Error::from(ErrorKind::InvalidData)));
129+
continue;
130+
}
105131

106-
if xen_socket_reply_msg.r#type != XS_READ
107-
&& xen_socket_reply_msg.r#type != XS_WRITE
108-
&& xen_socket_reply_msg.r#type != XS_WATCH
109-
&& xen_socket_reply_msg.r#type != XS_WATCH_EVENT
110-
&& xen_socket_reply_msg.r#type != XS_DIRECTORY
111-
{
112132
queue_message(
113133
&condvar,
114134
eventfd,
115-
Err(Error::new(ErrorKind::Other, "Xen Store transaction error")),
135+
Ok(XenStoreMessage {
136+
r#type: xen_socket_reply_msg.r#type,
137+
body: result,
138+
}),
116139
);
117-
continue;
118140
}
119-
120-
if xen_socket_reply_msg.r#type == XS_WATCH_EVENT {
121-
condvar = watch_condvar.clone();
122-
eventfd = Some(tx_eventfd.try_clone()?);
141+
Err(e) => {
142+
queue_message(&condvar, eventfd, Err(Error::new(ErrorKind::Other, e)));
123143
}
124-
125-
match String::from_utf8(buffer) {
126-
Ok(result) => {
127-
if result.len() != xen_socket_reply_msg.len as usize {
128-
queue_message(&condvar, eventfd, Err(Error::from(ErrorKind::InvalidData)));
129-
continue;
130-
}
131-
132-
queue_message(
133-
&condvar,
134-
eventfd,
135-
Ok(XenStoreMessage {
136-
r#type: xen_socket_reply_msg.r#type,
137-
body: result,
138-
}),
139-
);
140-
}
141-
Err(e) => {
142-
queue_message(&condvar, eventfd, Err(Error::new(ErrorKind::Other, e)));
143-
}
144-
};
145-
}
144+
};
146145
}
147146
}
148147

@@ -195,49 +194,55 @@ impl XenStoreHandle {
195194
iovec_buffers: &mut Vec<iovec>,
196195
) -> Result<String, std::io::Error> {
197196
let mut xen_socket_msg = XenSocketMessage::new(r#type, iovec_buffers)?;
198-
let xen_socket_msg_size = mem::size_of::<XenSocketMessage>();
199197
let (lock, cvar) = &*self.reply_condvar;
200198

201-
unsafe {
202-
let xen_socket_msg_slice = slice::from_raw_parts(
203-
&mut xen_socket_msg as *mut _ as *mut u8,
204-
xen_socket_msg_size,
205-
);
199+
let mut tx_socket = self.tx_socket.lock().unwrap();
200+
{
201+
// SAFETY: `xen_socket_msg` is `XenSocketMessage` bytes sized.
202+
let xen_socket_msg_slice: &[u8] = unsafe {
203+
std::slice::from_raw_parts(
204+
std::ptr::addr_of_mut!(xen_socket_msg).cast(),
205+
mem::size_of::<XenSocketMessage>(),
206+
)
207+
};
206208

207209
/*
208210
* Grabbing the mutex guarantees there will only be
209211
* one active transcation at a time.
210212
*/
211-
let mut tx_socket = self.tx_socket.lock().unwrap();
212213
tx_socket.write_all(xen_socket_msg_slice)?;
214+
}
213215

214-
let ret = writev(
216+
// SAFETY: tx_socket is a valid file descriptor and the pointer/length we pass
217+
// are valid allocated values.
218+
let ret = unsafe {
219+
libc::writev(
215220
tx_socket.as_raw_fd(),
216221
iovec_buffers.as_ptr(),
217222
iovec_buffers.len() as i32,
218-
);
223+
)
224+
};
219225

220-
if ret < 0 {
221-
return Err(Error::last_os_error());
222-
}
226+
if ret < 0 {
227+
return Err(Error::last_os_error());
228+
}
223229

224-
let mut reply_vec = lock.lock().unwrap();
225-
while reply_vec.is_empty() {
226-
reply_vec = cvar.wait(reply_vec).unwrap();
227-
}
230+
let mut reply_vec = lock.lock().unwrap();
231+
while reply_vec.is_empty() {
232+
reply_vec = cvar.wait(reply_vec).unwrap();
233+
}
228234

229-
match reply_vec.pop_front() {
230-
Some(result) => match result {
231-
Ok(xsm) => {
232-
if xsm.r#type != r#type {
233-
return Err(Error::from(ErrorKind::InvalidData));
234-
}
235-
Ok(xsm.body)
235+
match reply_vec.pop_front() {
236+
Some(result) => match result {
237+
Ok(xsm) => {
238+
if xsm.r#type != r#type {
239+
return Err(Error::from(ErrorKind::InvalidData));
236240
}
237-
Err(e) => Err(e),
238-
},
239-
None => Err(Error::new(ErrorKind::Other, "Xen Store transaction error")),
240-
}
241+
Ok(xsm.body)
242+
}
243+
Err(e) => Err(e),
244+
},
245+
None => Err(Error::new(ErrorKind::Other, "Xen Store transaction error")),
241246
}
242247
}
243248

0 commit comments

Comments
 (0)