Skip to content

Commit 70b7511

Browse files
authored
Merge branch 'main' into qinheping-patch-2
2 parents ca3e13d + 90d304b commit 70b7511

File tree

556 files changed

+17873
-8154
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

556 files changed

+17873
-8154
lines changed

doc/src/SUMMARY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@
2525
- [10: Memory safety of String](./challenges/0010-string.md)
2626
- [11: Safety of Methods for Numeric Primitive Types](./challenges/0011-floats-ints.md)
2727
- [12: Safety of `NonZero`](./challenges/0012-nonzero.md)
28-
28+
- [13: Safety of `CStr`](./challenges/0013-cstr.md)
2929

doc/src/challenges/0013-cstr.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Challenge 13: Safety of `CStr`
2+
3+
- **Status:** Open
4+
- **Solution:**
5+
- **Tracking Issue:** [#150](https://github.com/model-checking/verify-rust-std/issues/150)
6+
- **Start date:** 2024/11/04
7+
- **End date:** 2025/01/31
8+
9+
-------------------
10+
## Goal
11+
12+
Verify that `CStr` safely represents a borrowed reference to a null-terminated array of bytes sequences similar to
13+
the C string representation.
14+
15+
## Motivation
16+
17+
The `CStr` structure is meant to be used to build safe wrappers of FFI functions that may leverage `CStr::as_ptr`
18+
and the unsafe `CStr::from_ptr` constructor to provide a safe interface to other consumers.
19+
It provides safe methods to convert `CStr` to a Rust `&str` by performing UTF-8 validation, or into an owned `CString`.
20+
21+
Any issue with this structure or misusage of its unsafe methods could trigger an invalid memory access, which poses
22+
a security risk for their users.
23+
24+
## Description
25+
26+
The goal of this challenge is to ensure the safety of the `CStr` struct implementation.
27+
First, we need to specify a safety invariant that captures the essential safety properties that must be maintained.
28+
29+
Next, we should verify that all the safe, public methods respect this invariant.
30+
For example, we can check that creating a `CStr` from a byte slice with method `from_bytes_with_nul` will only yield
31+
safe values of `CStr`.
32+
33+
Finally, for unsafe methods like `from_ptr()` and `from_bytes_with_nul_unchecked`, we need to specify appropriate safety contracts.
34+
These contracts should ensure no undefined behavior occurs within the unsafe methods themselves,
35+
and that they maintain the overall safety invariant of `CStr` when called correctly.
36+
37+
### Assumptions
38+
39+
- Harnesses may be bounded.
40+
41+
### Success Criteria
42+
43+
1. Implement the `Invariant` trait for `CStr`.
44+
45+
2. Verify that the `CStr` safety invariant holds after calling any of the following public safe methods.
46+
47+
| Function | Location |
48+
|------------------------|--------------------|
49+
| `from_bytes_until_nul` | `core::ffi::c_str` |
50+
| `from_bytes_with_nul` | `core::ffi::c_str` |
51+
| `count_bytes` | `core::ffi::c_str` |
52+
| `is_empty` | `core::ffi::c_str` |
53+
| `to_bytes` | `core::ffi::c_str` |
54+
| `to_bytes_with_nul` | `core::ffi::c_str` |
55+
| `bytes` | `core::ffi::c_str` |
56+
| `to_str` | `core::ffi::c_str` |
57+
| `as_ptr` | `core::ffi::c_str` |
58+
59+
3. Annotate and verify the safety contracts for the following unsafe functions:
60+
61+
| Function | Location |
62+
|--------------------------------|---------------------|
63+
| `from_ptr` | `core::ffi::c_str` |
64+
| `from_bytes_with_nul_uncheked` | `core::ffi::c_str` |
65+
| `strlen` | `core::ffi::c_str` |
66+
67+
4. Verify that the following trait implementations for the `CStr` type are safe:
68+
69+
70+
| Trait | Implementation Location |
71+
|-------------------------------------|-------------------------|
72+
| `CloneToUninit` [^unsafe-fn] | `core::clone` |
73+
| `ops::Index<ops::RangeFrom<usize>>` | `core::ffi::c_str` |
74+
75+
[^unsafe-fn]: Unsafe functions will require safety contracts.
76+
77+
All proofs must automatically ensure the absence of the following undefined behaviors [ref](https://github.com/rust-lang/reference/blob/142b2ed77d33f37a9973772bd95e6144ed9dce43/src/behavior-considered-undefined.md):
78+
79+
- Accessing (loading from or storing to) a place that is dangling or based on a misaligned pointer.
80+
- Performing a place projection that violates the requirements of in-bounds pointer arithmetic.
81+
- Mutating immutable bytes.
82+
- Accessing uninitialized memory.
83+
84+
Note: All solutions to verification challenges need to satisfy the criteria established in the
85+
[challenge book](../general-rules.md) in addition to the ones listed above.

doc/src/tool_template.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ _Please list the license(s) that are used by your tool, and if to your knowledge
2020

2121
## Steps to Use the Tool
2222

23-
1. [First Step]
24-
2. [Second Step]
25-
3. [and so on...]
23+
1. \[First Step\]
24+
2. \[Second Step\]
25+
3. \[and so on...\]
2626

2727
## Artifacts
2828
_If there are noteworthy examples of using the tool to perform verificaiton, please include them in this section.Links, papers, etc._

library/Cargo.lock

+50-40
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

library/alloc/benches/binary_heap.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::collections::BinaryHeap;
22

33
use rand::seq::SliceRandom;
4-
use test::{black_box, Bencher};
4+
use test::{Bencher, black_box};
55

66
#[bench]
77
fn bench_find_smallest_1000(b: &mut Bencher) {

library/alloc/benches/btree/map.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use std::collections::BTreeMap;
22
use std::ops::RangeBounds;
33

4-
use rand::seq::SliceRandom;
54
use rand::Rng;
6-
use test::{black_box, Bencher};
5+
use rand::seq::SliceRandom;
6+
use test::{Bencher, black_box};
77

88
macro_rules! map_insert_rand_bench {
99
($name: ident, $n: expr, $map: ident) => {

library/alloc/benches/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
#![feature(iter_next_chunk)]
55
#![feature(repr_simd)]
66
#![feature(slice_partition_dedup)]
7-
#![feature(strict_provenance)]
7+
#![cfg_attr(bootstrap, feature(strict_provenance))]
8+
#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
89
#![feature(test)]
910
#![deny(fuzzy_provenance_casts)]
1011

0 commit comments

Comments
 (0)