From 13f6ea31d694067e12fa3edad5438b4fa67d736b Mon Sep 17 00:00:00 2001 From: Bryant Mairs Date: Thu, 30 Nov 2017 22:08:12 -0800 Subject: [PATCH 1/2] Fix UB in epoll_ctl When passing None as an argument to `epoll_ctl`, UB is elicited within the `Into<&EpollEvent>` impl because it passes a null pointer as a `&mut EpollEvent`. Instead we remove that implementation completely and handle this case directly within the `epoll_ctl` function. Thanks to Arnavion for helping to debug this. --- src/sys/epoll.rs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/sys/epoll.rs b/src/sys/epoll.rs index 5ab766dcb9..5d63e82f6c 100644 --- a/src/sys/epoll.rs +++ b/src/sys/epoll.rs @@ -65,16 +65,6 @@ impl EpollEvent { } } -impl<'a> Into<&'a mut EpollEvent> for Option<&'a mut EpollEvent> { - #[inline] - fn into(self) -> &'a mut EpollEvent { - match self { - Some(epoll_event) => epoll_event, - None => unsafe { &mut *ptr::null_mut::() } - } - } -} - #[inline] pub fn epoll_create() -> Result { let res = unsafe { libc::epoll_create(1024) }; @@ -91,13 +81,19 @@ pub fn epoll_create1(flags: EpollCreateFlags) -> Result { #[inline] pub fn epoll_ctl<'a, T>(epfd: RawFd, op: EpollOp, fd: RawFd, event: T) -> Result<()> - where T: Into<&'a mut EpollEvent> + where T: Into> { - let event: &mut EpollEvent = event.into(); - if event as *const EpollEvent == ptr::null() && op != EpollOp::EpollCtlDel { + let mut event: Option<&mut EpollEvent> = event.into(); + if event.is_none() && op != EpollOp::EpollCtlDel { Err(Error::Sys(Errno::EINVAL)) } else { - let res = unsafe { libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event) }; + let res = unsafe { + if let Some(ref mut event) = event { + libc::epoll_ctl(epfd, op as c_int, fd, &mut event.event) + } else { + libc::epoll_ctl(epfd, op as c_int, fd, ptr::null_mut()) + } + }; Errno::result(res).map(drop) } } From 54313a7a9318294bf22f4640476fb1195ec301f6 Mon Sep 17 00:00:00 2001 From: Bryant Mairs Date: Thu, 30 Nov 2017 22:12:29 -0800 Subject: [PATCH 2/2] Test with hard-fails on stable also --- .travis.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index f0aa93f157..c8caf483ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -93,15 +93,9 @@ matrix: rust: 1.13.0 os: osx - # Testing beta on main targets + # Make sure stable is always working too - env: TARGET=x86_64-unknown-linux-gnu - rust: beta - - allow_failures: - # We allow beta to fail here because a bug might crop up in rust that causes it. We will - # however be on the lookout for this and file those bugs with upstream. - - env: TARGET=x86_64-unknown-linux-gnu - rust: beta + rust: stable before_install: set -e