From 6d552e24d8fe6ac6af28e7727aa20cd51a569f3f Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Thu, 27 Jan 2022 11:45:04 +0100 Subject: [PATCH 1/4] io: fix `take` when using evil reader (#4428) --- tokio/src/io/util/take.rs | 5 +++++ tokio/tests/io_take.rs | 30 +++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/tokio/src/io/util/take.rs b/tokio/src/io/util/take.rs index b5e90c936fa..d73512bdfaf 100644 --- a/tokio/src/io/util/take.rs +++ b/tokio/src/io/util/take.rs @@ -84,9 +84,14 @@ impl AsyncRead for Take { return Poll::Ready(Ok(())); } + let buf_ptr = buf.filled().as_ptr(); + let me = self.project(); let mut b = buf.take(*me.limit_ as usize); + ready!(me.inner.poll_read(cx, &mut b))?; + assert_eq!(b.filled().as_ptr(), buf_ptr); + let n = b.filled().len(); // We need to update the original ReadBuf diff --git a/tokio/tests/io_take.rs b/tokio/tests/io_take.rs index 683606f7272..45c61f276b1 100644 --- a/tokio/tests/io_take.rs +++ b/tokio/tests/io_take.rs @@ -1,7 +1,9 @@ #![warn(rust_2018_idioms)] #![cfg(feature = "full")] -use tokio::io::AsyncReadExt; +use std::pin::Pin; +use std::task::{Context, Poll}; +use tokio::io::{self, AsyncRead, AsyncReadExt, ReadBuf}; use tokio_test::assert_ok; #[tokio::test] @@ -14,3 +16,29 @@ async fn take() { assert_eq!(n, 4); assert_eq!(&buf, &b"hell\0\0"[..]); } + +struct BadReader; + +impl AsyncRead for BadReader { + fn poll_read( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + read_buf: &mut ReadBuf<'_>, + ) -> Poll> { + let vec = vec![0; 10]; + + let mut buf = ReadBuf::new(vec.leak()); + buf.put_slice(&[123; 10]); + *read_buf = buf; + + Poll::Ready(Ok(())) + } +} + +#[tokio::test] +#[should_panic] +async fn bad_reader_fails() { + let mut buf = Vec::with_capacity(10); + + BadReader.take(10).read_buf(&mut buf).await.unwrap(); +} From 300095c8329c748c1b5ff29378fe19385b0b2814 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Fri, 28 Jan 2022 10:04:13 +0100 Subject: [PATCH 2/4] io: fix take pointer check (#4437) --- tokio/src/io/util/take.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tokio/src/io/util/take.rs b/tokio/src/io/util/take.rs index d73512bdfaf..df2f61b9e60 100644 --- a/tokio/src/io/util/take.rs +++ b/tokio/src/io/util/take.rs @@ -84,11 +84,10 @@ impl AsyncRead for Take { return Poll::Ready(Ok(())); } - let buf_ptr = buf.filled().as_ptr(); - let me = self.project(); let mut b = buf.take(*me.limit_ as usize); + let buf_ptr = b.filled().as_ptr(); ready!(me.inner.poll_read(cx, &mut b))?; assert_eq!(b.filled().as_ptr(), buf_ptr); From 8b36db0bfbb5f10c679a030814afc1e4bf6e5894 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Fri, 28 Jan 2022 13:48:03 -0800 Subject: [PATCH 3/4] chore: pin Rust versions in CI --- .cirrus.yml | 3 +- .github/workflows/ci.yml | 110 +++++++++++++++++++++++---------------- 2 files changed, 66 insertions(+), 47 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index ed54d2943b0..b0d8e10585a 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -10,10 +10,11 @@ task: env: LOOM_MAX_PREEMPTIONS: 2 RUSTFLAGS: -Dwarnings + RUST_TOOLCHAIN: 1.56.0 setup_script: - pkg install -y bash curl - curl https://sh.rustup.rs -sSf --output rustup.sh - - sh rustup.sh -y --profile minimal --default-toolchain stable + - sh rustup.sh -y --profile minimal --default-toolchain $RUST_TOOLCHAIN - . $HOME/.cargo/env - rustup target add i686-unknown-freebsd - | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6bfb3b72704..aca605dedfc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,8 +9,10 @@ name: CI env: RUSTFLAGS: -Dwarnings RUST_BACKTRACE: 1 - nightly: nightly-2021-04-25 - minrust: 1.45.2 + rust_stable: 1.56.0 + rust_nightly: nightly-2021-04-25 + rust_clippy: 1.52.0 + rust_min: 1.45.2 jobs: # Depends on all action sthat are required for a "successful" CI run. @@ -43,6 +45,11 @@ jobs: - macos-latest steps: - uses: actions/checkout@v2 + - name: Install Rust ${{ env.rust_stable }} + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.rust_stable }} + override: true - name: Install Rust run: rustup update stable - name: Install cargo-hack @@ -80,8 +87,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Install Rust - run: rustup update stable + - name: Install Rust ${{ env.rust_stable }} + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.rust_stable }} + override: true - name: Install Valgrind run: | @@ -117,9 +127,11 @@ jobs: - macos-latest steps: - uses: actions/checkout@v2 - - name: Install Rust - run: rustup update stable - + - name: Install Rust ${{ env.rust_stable }} + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.rust_stable }} + override: true # Run `tokio` with "unstable" cfg flag. - name: test tokio full --cfg unstable run: cargo test --all-features @@ -132,29 +144,28 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - name: Install Rust ${{ env.rust_nightly }} + uses: actions-rs/toolchain@v1 with: - toolchain: ${{ env.nightly }} - override: true - - name: Install Miri + toolchain: ${{ env.rust_nightly }} + override: true + components: miri + - name: miri run: | set -e - rustup component add miri - cargo miri setup - rm -rf tokio/tests - - - name: miri - run: cargo miri test --features rt,rt-multi-thread,sync task + rm -rf tests + cargo miri test --features rt,rt-multi-thread,sync task working-directory: tokio san: name: san runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - name: Install Rust ${{ env.rust_nightly }} + uses: actions-rs/toolchain@v1 with: - toolchain: ${{ env.nightly }} - override: true + toolchain: ${{ env.rust_nightly }} + override: true - name: asan run: cargo test --all-features --target x86_64-unknown-linux-gnu --lib -- --test-threads 1 working-directory: tokio @@ -175,9 +186,10 @@ jobs: - arm-linux-androideabi steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - name: Install Rust ${{ env.rust_stable }} + uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: ${{ env.rust_stable }} target: ${{ matrix.target }} override: true - uses: actions-rs/cargo@v1 @@ -191,16 +203,16 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - name: Install Rust ${{ env.rust_nightly }} + uses: actions-rs/toolchain@v1 with: - toolchain: ${{ env.nightly }} + toolchain: ${{ env.rust_nightly }} + target: ${{ matrix.target }} override: true - name: Install cargo-hack run: cargo install cargo-hack - - name: check --each-feature run: cargo hack check --all --each-feature -Z avoid-dev-deps - # Try with unstable feature flags - name: check --each-feature --unstable run: cargo hack check --all --each-feature -Z avoid-dev-deps @@ -212,11 +224,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - name: Install Rust ${{ env.rust_min }} + uses: actions-rs/toolchain@v1 with: - toolchain: ${{ env.minrust }} + toolchain: ${{ env.rust_min }} override: true - - name: "test --workspace --all-features" run: cargo check --workspace --all-features @@ -225,9 +237,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - name: Install Rust ${{ env.rust_nightly }} + uses: actions-rs/toolchain@v1 with: - toolchain: ${{ env.nightly }} + toolchain: ${{ env.rust_nightly }} override: true - name: Install cargo-hack run: cargo install cargo-hack @@ -245,11 +258,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Install Rust - run: rustup update stable - - name: Install rustfmt - run: rustup component add rustfmt - + - name: Install Rust ${{ env.rust_stable }} + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.rust_stable }} + override: true + components: rustfmt # Check fmt - name: "rustfmt --check" # Workaround for rust-lang/cargo#7732 @@ -264,10 +278,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Install Rust - run: rustup update 1.52.1 && rustup default 1.52.1 - - name: Install clippy - run: rustup component add clippy + - name: Install Rust ${{ env.rust_clippy }} + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.rust_clippy }} + override: true + components: clippy # Run clippy - name: "clippy --all" @@ -278,11 +294,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - name: Install Rust ${{ env.rust_nightly }} + uses: actions-rs/toolchain@v1 with: - toolchain: ${{ env.nightly }} + toolchain: ${{ env.rust_nightly }} override: true - - name: "doc --lib --all-features" run: cargo doc --lib --no-deps --all-features --document-private-items env: @@ -302,9 +318,11 @@ jobs: - time::driver steps: - uses: actions/checkout@v2 - - name: Install Rust - run: rustup update stable - + - name: Install Rust ${{ env.rust_stable }} + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.rust_stable }} + override: true - name: loom ${{ matrix.scope }} run: cargo test --lib --release --features full -- --nocapture $SCOPE working-directory: tokio From b30bc9cb3533d6cf0b9a3756896129ffeb05411b Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 27 Jan 2022 15:53:57 -0800 Subject: [PATCH 4/4] chore: prepare Tokio 1.8.5 release --- README.md | 2 +- tokio/CHANGELOG.md | 29 +++++++++++++++++++++++++++++ tokio/Cargo.toml | 4 ++-- tokio/LICENSE | 2 +- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ddad6d3127e..d35e2e6994c 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Make sure you activated the full features of the tokio crate on Cargo.toml: ```toml [dependencies] -tokio = { version = "1.8.0", features = ["full"] } +tokio = { version = "1.8.5", features = ["full"] } ``` Then, on your main.rs: diff --git a/tokio/CHANGELOG.md b/tokio/CHANGELOG.md index 806d440766b..149c7918258 100644 --- a/tokio/CHANGELOG.md +++ b/tokio/CHANGELOG.md @@ -1,3 +1,32 @@ +# 1.8.5 (January 27, 2022) + +This release backports a bug fix from 1.16.0 + +Fixes a soundness bug in `io::Take` ([#4428]). The unsoundness is exposed when +leaking memory in the given `AsyncRead` implementation and then overwriting the +supplied buffer: + +```rust +impl AsyncRead for Buggy { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_> + ) -> Poll> { + let new_buf = vec![0; 5].leak(); + *buf = ReadBuf::new(new_buf); + buf.put_slice(b"hello"); + Poll::Ready(Ok(())) + } +} +``` + +### Fixed + +- io: **soundness** don't expose uninitialized memory when using `io::Take` in edge case ([#4428]) + +[#4428]: https://github.com/tokio-rs/tokio/pull/4428 + # 1.8.4 (November 15, 2021) This release backports a bug fix from 1.13.1. diff --git a/tokio/Cargo.toml b/tokio/Cargo.toml index 26f1a9ddfb2..c6ccbac225b 100644 --- a/tokio/Cargo.toml +++ b/tokio/Cargo.toml @@ -7,12 +7,12 @@ name = "tokio" # - README.md # - Update CHANGELOG.md. # - Create "v1.0.x" git tag. -version = "1.8.4" +version = "1.8.5" edition = "2018" authors = ["Tokio Contributors "] license = "MIT" readme = "README.md" -documentation = "https://docs.rs/tokio/1.8.4/tokio/" +documentation = "https://docs.rs/tokio/1.8.5/tokio/" repository = "https://github.com/tokio-rs/tokio" homepage = "https://tokio.rs" description = """ diff --git a/tokio/LICENSE b/tokio/LICENSE index ffa38bb61cc..8af5baf01ea 100644 --- a/tokio/LICENSE +++ b/tokio/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2021 Tokio Contributors +Copyright (c) 2022 Tokio Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated