Skip to content

Commit 74b1099

Browse files
authored
Merge pull request #148 from brson/next
Rust 1.15.1
2 parents 00ff49c + 8b0e09b commit 74b1099

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed

_posts/2017-02-09-Rust-1.15.1.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
---
2+
layout: post
3+
title: "Announcing Rust 1.15.1"
4+
author: The Rust Core Team
5+
---
6+
7+
The Rust team is happy to announce the latest version of Rust, 1.15.1. Rust is a
8+
systems programming language focused on safety, speed, and concurrency.
9+
10+
If you have a previous version of Rust installed, getting Rust 1.15.1 is as easy as:
11+
12+
```bash
13+
$ rustup update stable
14+
```
15+
16+
If you don't have it already, you can [download Rust][install] from the
17+
appropriate page on our website, and check out the [detailed release notes for
18+
1.15.1][notes] on GitHub.
19+
20+
[install]: https://www.rust-lang.org/install.html
21+
[notes]: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1151-2017-02-09
22+
23+
### What's in 1.15.1 stable
24+
25+
This release fixes two issues, a soundness bug in the new
26+
`vec::IntoIter::as_mut_slice` method, and a regression wherein certain C
27+
components of the Rust distribution were [not compiled with `-fPIC`][fpic]. The
28+
latter results in the text section of executables being writable in some
29+
configurations, including common Linux configurations, subverting an important
30+
attack mitigation, and creating longer startup times by causing the linker to do
31+
more work. For mostly-Rust codebases, the practical impact of losing read-only
32+
text sections is relatively small (since Rust's type system is its first line of
33+
defense), but for Rust linked into other codebases the impact could be
34+
unexpectedly quite significant. [PIC] issues are well understood and not
35+
Rust-specific, so the rest of this post focuses on the soundness bug.
36+
37+
[fpic]: https://github.com/rust-lang/rust/pull/39523
38+
[PIC]: https://en.wikipedia.org/wiki/Position-independent_code
39+
40+
The problem with `as_mut_slice`, a three line function, was [discovered] just
41+
minutes after publishing Rust 1.15.0, and is a reminder of the perils of writing
42+
unsafe code.
43+
44+
[discovered]: https://www.reddit.com/r/rust/comments/5roiq7/announcing_rust_115/dd8vujs/
45+
46+
`as_mut_slice` is a method on the `IntoIter` iterator for the `Vec` type that
47+
offers a mutable view into the buffer being iterated over. Conceptually it is
48+
simple: just return a reference to the buffer; and indeed the implementation is
49+
simple, but it's unsafe because `IntoIter` is implemented with an unsafe pointer
50+
to the buffer:
51+
52+
```rust
53+
pub fn as_mut_slice(&self) -> &mut [T] {
54+
unsafe {
55+
slice::from_raw_parts_mut(self.ptr as *mut T, self.len())
56+
}
57+
}
58+
```
59+
60+
It's just about the simplest unsafe method one could ask for. Can you spot the
61+
error? Our reviewers didn't! This API slipped through the cracks because it is
62+
such a standard and small one. It's a copy-paste bug that the reviewers glossed
63+
over. This method takes a shared reference and unsafely derives from it a
64+
mutable reference. That is totally bogus because it means `as_mut_slice` can be
65+
used to produce multiple mutable references to the same buffer, which is the one
66+
single thing you must not do in Rust.
67+
68+
Here's a simple example of what this bug would let you write, incorrectly:
69+
70+
```rust
71+
fn main() {
72+
let v = vec![0];
73+
let v_iter = v.into_iter();
74+
let slice1: &mut [_] = v_iter.as_mut_slice();
75+
let slice2: &mut [_] = v_iter.as_mut_slice();
76+
slice1[0] = 1;
77+
slice2[0] = 2;
78+
}
79+
```
80+
81+
Here both `slice1` and `slice2` are referencing the same mutable slice. Also
82+
notice that the iterator they are created from, `v_iter` is not declared
83+
mutable, which is a good indication something fishy is going on.
84+
85+
The [solution] here is trivial, just change `&self` to `&mut self`:
86+
87+
```rust
88+
pub fn as_mut_slice(&mut self) -> &mut [T] {
89+
unsafe {
90+
slice::from_raw_parts_mut(self.ptr as *mut T, self.len())
91+
}
92+
}
93+
```
94+
95+
[solution]: https://github.com/rust-lang/rust/pull/39466
96+
97+
With that, proper uniqueness invariants are maintained, only one mutable slice
98+
can be created at a time, and `v_iter` must be declared mutable in order to pull
99+
out a mutable slice.
100+
101+
So we made that change, and we're releasing a fix. In Rust we take pride in not
102+
breaking APIs, but since this is a new, minor feature, and the present
103+
implementation is spectacularly unsound, we decided to go ahead and release the
104+
fix immediately, hopefully before too many codebases pick it up — that is, we
105+
don't consider this a breaking change that requires a careful transition, but a
106+
necessary bug fix. For more about Rust's approach to ensuring stability see the
107+
["Stability as a Deliverable"][stab] blog post, [RFC 1122], on language
108+
evolution, and [RFC 1105], on library evolution.
109+
110+
[stab]: https://blog.rust-lang.org/2014/10/30/Stability.html
111+
[RFC 1122]: https://github.com/rust-lang/rfcs/blob/master/text/1122-language-semver.md
112+
[RFC 1105]: https://github.com/rust-lang/rfcs/blob/master/text/1105-api-evolution.md
113+
114+
We're still evaluating what to learn from this, but this is a good reminder of
115+
the care that must be taken when writing unsafe code. We have some ideas for how
116+
to catch this kind of problem earlier in the development process, but haven't
117+
made any decisions yet.
118+
119+
We apologize for the inconvenience. Let's go hack.
120+
121+
### Contributors to 1.15.1
122+
123+
We had 2 individuals contribute to Rust 1.15.1.
124+
[Thanks!](https://thanks.rust-lang.org/rust/1.15.1)

0 commit comments

Comments
 (0)