From 5d988efe8605cda1b515d5f7c037f440c7b3e7c6 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 12 Jun 2020 10:27:49 +0900 Subject: [PATCH] io: fix unsound pin projection in read_buf and write_buf --- tokio/src/io/util/async_read_ext.rs | 2 +- tokio/src/io/util/async_write_ext.rs | 2 +- tokio/src/io/util/read_buf.rs | 13 +++++-------- tokio/src/io/util/write_buf.rs | 13 +++++-------- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/tokio/src/io/util/async_read_ext.rs b/tokio/src/io/util/async_read_ext.rs index d4402db621b..fcd2cce4f7e 100644 --- a/tokio/src/io/util/async_read_ext.rs +++ b/tokio/src/io/util/async_read_ext.rs @@ -221,7 +221,7 @@ cfg_io_util! { /// ``` fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B> where - Self: Sized, + Self: Sized + Unpin, B: BufMut, { read_buf(self, buf) diff --git a/tokio/src/io/util/async_write_ext.rs b/tokio/src/io/util/async_write_ext.rs index 377f4ecaf80..9c7ec7f7bd8 100644 --- a/tokio/src/io/util/async_write_ext.rs +++ b/tokio/src/io/util/async_write_ext.rs @@ -180,7 +180,7 @@ cfg_io_util! { /// ``` fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B> where - Self: Sized, + Self: Sized + Unpin, B: Buf, { write_buf(self, src) diff --git a/tokio/src/io/util/read_buf.rs b/tokio/src/io/util/read_buf.rs index 550499b9334..97e670de0a3 100644 --- a/tokio/src/io/util/read_buf.rs +++ b/tokio/src/io/util/read_buf.rs @@ -8,7 +8,7 @@ use std::task::{Context, Poll}; pub(crate) fn read_buf<'a, R, B>(reader: &'a mut R, buf: &'a mut B) -> ReadBuf<'a, R, B> where - R: AsyncRead, + R: AsyncRead + Unpin, B: BufMut, { ReadBuf { reader, buf } @@ -26,16 +26,13 @@ cfg_io_util! { impl Future for ReadBuf<'_, R, B> where - R: AsyncRead, + R: AsyncRead + Unpin, B: BufMut, { type Output = io::Result; - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - // safety: no data is moved from self - unsafe { - let me = self.get_unchecked_mut(); - Pin::new_unchecked(&mut *me.reader).poll_read_buf(cx, &mut me.buf) - } + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let me = &mut *self; + Pin::new(&mut *me.reader).poll_read_buf(cx, me.buf) } } diff --git a/tokio/src/io/util/write_buf.rs b/tokio/src/io/util/write_buf.rs index e49282fe0c4..cedfde64e6e 100644 --- a/tokio/src/io/util/write_buf.rs +++ b/tokio/src/io/util/write_buf.rs @@ -20,7 +20,7 @@ cfg_io_util! { /// asynchronous manner, returning a future. pub(crate) fn write_buf<'a, W, B>(writer: &'a mut W, buf: &'a mut B) -> WriteBuf<'a, W, B> where - W: AsyncWrite, + W: AsyncWrite + Unpin, B: Buf, { WriteBuf { writer, buf } @@ -28,16 +28,13 @@ where impl Future for WriteBuf<'_, W, B> where - W: AsyncWrite, + W: AsyncWrite + Unpin, B: Buf, { type Output = io::Result; - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - // safety: no data is moved from self - unsafe { - let me = self.get_unchecked_mut(); - Pin::new_unchecked(&mut *me.writer).poll_write_buf(cx, &mut me.buf) - } + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let me = &mut *self; + Pin::new(&mut *me.writer).poll_write_buf(cx, me.buf) } }