From cafdcfc92785e15d157a5010cd863f27a95bcc93 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 27870cd9bc1ba8bd4c93f899e1dca5a0989b3e0c 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 02fc2601cae2c8cf9f1279dda779252399158414 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Sun, 30 Jan 2022 10:07:31 -0800 Subject: [PATCH 3/4] chore: make it easier to pin Rust versions in CI (#4448) When backporting patches to LTS branches, we often run into CI failures due to changes in rust. Newer rust versions add more lints, which break CI. We really don't want to also have to backport patches that fix CI, so instead, LTS branches should pin the stable rust version in CI (e.g. #4434). This PR restructures the CI config files to make it a bit easier to set a specific rust version in CI. --- .cirrus.yml | 8 ++- .github/workflows/ci.yml | 109 +++++++++++++++++++----------- .github/workflows/loom.yml | 9 ++- .github/workflows/stress-test.yml | 13 +++- 4 files changed, 91 insertions(+), 48 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 4bef869c24f..a2df2ddca8d 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,6 +1,8 @@ freebsd_instance: image: freebsd-12-2-release-amd64 env: + RUST_STABLE: 1.56.0 + RUST_NIGHTLY: nightly-2021-10-25 RUSTFLAGS: -D warnings # Test FreeBSD in a full VM on cirrus-ci.com. Test the i686 target too, in the @@ -12,7 +14,7 @@ task: 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_STABLE - . $HOME/.cargo/env - | echo "~~~~ rustc --version ~~~~" @@ -29,7 +31,7 @@ task: setup_script: - pkg install -y bash curl - curl https://sh.rustup.rs -sSf --output rustup.sh - - sh rustup.sh -y --profile minimal --default-toolchain nightly-2021-10-25 + - sh rustup.sh -y --profile minimal --default-toolchain $RUST_NIGHTLY - . $HOME/.cargo/env - | echo "~~~~ rustc --version ~~~~" @@ -43,7 +45,7 @@ task: 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_STABLE - . $HOME/.cargo/env - rustup target add i686-unknown-freebsd - | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9fec5837e3c..d5ae4d7c61f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,15 @@ env: RUSTFLAGS: -Dwarnings RUST_BACKTRACE: 1 nightly: nightly-2021-10-25 - minrust: 1.45.2 + # Change to specific Rust release to pin + rust_stable: 1.56.0 + rust_nightly: nightly-2021-10-25 + rust_clippy: 1.52.0 + rust_min: 1.45.2 + +defaults: + run: + shell: bash jobs: # Depends on all action sthat are required for a "successful" CI run. @@ -44,6 +52,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 - uses: Swatinem/rust-cache@v1 @@ -82,8 +95,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 - uses: Swatinem/rust-cache@v1 - name: Install Valgrind @@ -120,10 +136,12 @@ 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 - uses: Swatinem/rust-cache@v1 - # Run `tokio` with "unstable" cfg flag. - name: test tokio full --cfg unstable run: cargo test --all-features @@ -136,29 +154,29 @@ 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 }} + components: miri override: true - uses: Swatinem/rust-cache@v1 - - name: Install 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 }} + toolchain: ${{ env.rust_nightly }} override: true - uses: Swatinem/rust-cache@v1 - name: asan @@ -181,9 +199,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: Swatinem/rust-cache@v1 @@ -198,17 +217,17 @@ 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 - uses: Swatinem/rust-cache@v1 - 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 @@ -220,9 +239,10 @@ 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 - uses: Swatinem/rust-cache@v1 - name: "test --workspace --all-features" @@ -233,9 +253,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 - uses: Swatinem/rust-cache@v1 - name: Install cargo-hack @@ -264,12 +285,13 @@ 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 + components: rustfmt - uses: Swatinem/rust-cache@v1 - - name: Install rustfmt - run: rustup component add rustfmt - # Check fmt - name: "rustfmt --check" # Workaround for rust-lang/cargo#7732 @@ -284,12 +306,13 @@ 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 Rust ${{ env.rust_clippy }} + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ env.rust_clippy }} + override: true + components: clippy - uses: Swatinem/rust-cache@v1 - - name: Install clippy - run: rustup component add clippy - # Run clippy - name: "clippy --all" run: cargo clippy --all --tests --all-features @@ -299,9 +322,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 - uses: Swatinem/rust-cache@v1 - name: "doc --lib --all-features" @@ -315,8 +339,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 - uses: Swatinem/rust-cache@v1 - name: build --cfg loom run: cargo test --no-run --lib --features full diff --git a/.github/workflows/loom.yml b/.github/workflows/loom.yml index fde9f1114e1..704728f13fb 100644 --- a/.github/workflows/loom.yml +++ b/.github/workflows/loom.yml @@ -10,6 +10,8 @@ name: Loom env: RUSTFLAGS: -Dwarnings RUST_BACKTRACE: 1 + # Change to specific Rust release to pin + rust_stable: 1.56.0 jobs: loom: @@ -28,8 +30,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 - uses: Swatinem/rust-cache@v1 - name: loom ${{ matrix.scope }} run: cargo test --lib --release --features full -- --nocapture $SCOPE diff --git a/.github/workflows/stress-test.yml b/.github/workflows/stress-test.yml index 3619d419742..b456b39525d 100644 --- a/.github/workflows/stress-test.yml +++ b/.github/workflows/stress-test.yml @@ -5,6 +5,12 @@ on: branches: - master +env: + RUSTFLAGS: -Dwarnings + RUST_BACKTRACE: 1 + # Change to specific Rust release to pin + rust_stable: 1.56.0 + jobs: stess-test: name: Stress Test @@ -15,8 +21,11 @@ jobs: - simple_echo_tcp 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 - uses: Swatinem/rust-cache@v1 - name: Install Valgrind run: | From e03a7909494884e41811c1b941831d65548d7fbb 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.14.1 release --- README.md | 2 +- tokio/CHANGELOG.md | 29 +++++++++++++++++++++++++++++ tokio/Cargo.toml | 4 ++-- tokio/LICENSE | 2 +- tokio/README.md | 2 +- 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 19f049cba78..5d0e4ab8328 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.14.0", features = ["full"] } +tokio = { version = "1.14.1", features = ["full"] } ``` Then, on your main.rs: diff --git a/tokio/CHANGELOG.md b/tokio/CHANGELOG.md index afa8bf0ce18..d3cd0af2df4 100644 --- a/tokio/CHANGELOG.md +++ b/tokio/CHANGELOG.md @@ -1,3 +1,32 @@ +# 1.14.1 (January 30, 2022) + +This release backports a bug fix from 1.16.1 + +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.14.0 (November 15, 2021) ### Fixed diff --git a/tokio/Cargo.toml b/tokio/Cargo.toml index 18e9c1b97ae..c1e9ad80835 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.14.0" +version = "1.14.1" edition = "2018" authors = ["Tokio Contributors "] license = "MIT" readme = "README.md" -documentation = "https://docs.rs/tokio/1.14.0/tokio/" +documentation = "https://docs.rs/tokio/1.14.1/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 diff --git a/tokio/README.md b/tokio/README.md index 19f049cba78..5d0e4ab8328 100644 --- a/tokio/README.md +++ b/tokio/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.14.0", features = ["full"] } +tokio = { version = "1.14.1", features = ["full"] } ``` Then, on your main.rs: