summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn-John Tedro <udoprog@tedro.se>2020-10-20 11:14:02 +0200
committerGitHub <noreply@github.com>2020-10-20 11:14:02 +0200
commit6d99e1c7dec4c6a37c4c7bf2801bc82cc210351d (patch)
tree75c5c1afd5f080918095f3aeed61637119d4d119
parentf73a2ad238f1b0ef193be5dbcafd6f2c6a99e098 (diff)
util: prevent read buffer from being swapped during a read_poll (#2993)
-rw-r--r--tokio-util/src/io/poll_read_buf.rs18
1 files changed, 18 insertions, 0 deletions
diff --git a/tokio-util/src/io/poll_read_buf.rs b/tokio-util/src/io/poll_read_buf.rs
index fe7d14ca..efce7ced 100644
--- a/tokio-util/src/io/poll_read_buf.rs
+++ b/tokio-util/src/io/poll_read_buf.rs
@@ -58,7 +58,25 @@ where
let n = {
let mut buf = ReadBuf::uninit(buf.bytes_mut());
+ let before = buf.filled().as_ptr();
+
ready!(read.poll_read(cx, &mut buf)?);
+
+ // This prevents a malicious read implementation from swapping out the
+ // buffer being read, which would allow `filled` to be advanced without
+ // actually initializing the provided buffer.
+ //
+ // We avoid this by asserting that the `ReadBuf` instance wraps the same
+ // memory address both before and after the poll. Which will panic in
+ // case its swapped.
+ //
+ // See https://github.com/tokio-rs/tokio/issues/2827 for more info.
+ assert! {
+ std::ptr::eq(before, buf.filled().as_ptr()),
+ "Read buffer must not be changed during a read poll. \
+ See https://github.com/tokio-rs/tokio/issues/2827 for more info."
+ };
+
buf.filled().len()
};