Skip to content

Commit 39a7335

Browse files
authored
Merge branch 'main' into core_arch_x86-arbitrary
2 parents 3cae612 + b4f59e8 commit 39a7335

File tree

185 files changed

+9784
-5984
lines changed

Some content is hidden

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

185 files changed

+9784
-5984
lines changed

.github/workflows/kani-metrics.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ jobs:
2828
python-version: '3.x'
2929

3030
- name: Compute Kani Metrics
31-
run: ./scripts/run-kani.sh --run metrics --with-autoharness --path ${{github.workspace}}
31+
run: |
32+
./scripts/run-kani.sh --run metrics --with-autoharness --path ${{github.workspace}}
33+
rm kani-list.json
3234
3335
- name: Create Pull Request
3436
uses: peter-evans/create-pull-request@v7

.github/workflows/kani.yml

Lines changed: 128 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ jobs:
5555
- name: Run Kani Verification
5656
run: head/scripts/run-kani.sh --path ${{github.workspace}}/head
5757

58-
kani-autoharness:
58+
kani_autoharness:
5959
name: Verify std library using autoharness
6060
runs-on: ${{ matrix.os }}
6161
strategy:
@@ -83,11 +83,17 @@ jobs:
8383
# explicitly list all functions (or prefixes thereof) the proofs of which
8484
# are known to pass.
8585
# Notes:
86+
# - We use >::disjoint_bitor (and >::unchecked_disjoint_bitor) as pattern
87+
# as whitespace is not supported, cf.
88+
# https://github.com/model-checking/kani/issues/4046
8689
# - core_arch::x86::__m128d::as_f64x2 is just one example of hundreds of
8790
# core_arch::x86:: functions that are known to verify successfully.
8891
- name: Run Kani Verification
8992
run: |
9093
scripts/run-kani.sh --run autoharness --kani-args \
94+
--include-pattern ">::disjoint_bitor" \
95+
--include-pattern ">::unchecked_disjoint_bitor" \
96+
--include-pattern alloc::__default_lib_allocator:: \
9197
--include-pattern alloc::layout::Layout::from_size_align \
9298
--include-pattern ascii::ascii_char::AsciiChar::from_u8 \
9399
--include-pattern char::convert::from_u32_unchecked \
@@ -132,7 +138,121 @@ jobs:
132138
--exclude-pattern ::precondition_check \
133139
--harness-timeout 10m \
134140
--default-unwind 1000 \
135-
--jobs=3 --output-format=terse
141+
--jobs=3 --output-format=terse | tee autoharness-verification.log
142+
gzip autoharness-verification.log
143+
144+
- name: Upload Autoharness Verification Log
145+
uses: actions/upload-artifact@v4
146+
with:
147+
name: ${{ matrix.os }}-autoharness-verification.log.gz
148+
path: autoharness-verification.log.gz
149+
if-no-files-found: error
150+
# Aggressively short retention: we don't really need these
151+
retention-days: 3
152+
153+
run_kani_metrics:
154+
name: Kani Metrics
155+
runs-on: ${{ matrix.os }}
156+
strategy:
157+
matrix:
158+
os: [ubuntu-latest, macos-latest]
159+
include:
160+
- os: ubuntu-latest
161+
base: ubuntu
162+
- os: macos-latest
163+
base: macos
164+
fail-fast: true
165+
166+
steps:
167+
# Step 1: Check out the repository
168+
- name: Checkout Repository
169+
uses: actions/checkout@v4
170+
with:
171+
submodules: true
172+
173+
# The Kani metrics collection uses a Python script (kani_std_analysis.py), so make sure Python is installed
174+
- name: Set up Python
175+
uses: actions/setup-python@v4
176+
with:
177+
python-version: '3.x'
178+
179+
# Step 2: Run list on the std library
180+
- name: Run Kani Metrics
181+
run: |
182+
scripts/run-kani.sh --run metrics --with-autoharness
183+
pushd /tmp/std_lib_analysis
184+
tar czf results.tar.gz results
185+
popd
186+
187+
- name: Upload kani-list.json
188+
uses: actions/upload-artifact@v4
189+
with:
190+
name: ${{ matrix.os }}-kani-list.json
191+
path: kani-list.json
192+
if-no-files-found: error
193+
# Aggressively short retention: we don't really need these
194+
retention-days: 3
195+
196+
- name: Upload scanner results
197+
uses: actions/upload-artifact@v4
198+
with:
199+
name: ${{ matrix.os }}-results.tar.gz
200+
path: /tmp/std_lib_analysis/results.tar.gz
201+
if-no-files-found: error
202+
# Aggressively short retention: we don't really need these
203+
retention-days: 3
204+
205+
run-log-analysis:
206+
name: Build JSON from logs
207+
needs: [run_kani_metrics, kani_autoharness]
208+
runs-on: ${{ matrix.os }}
209+
strategy:
210+
matrix:
211+
os: [ubuntu-latest, macos-latest]
212+
include:
213+
- os: ubuntu-latest
214+
base: ubuntu
215+
- os: macos-latest
216+
base: macos
217+
fail-fast: false
218+
219+
steps:
220+
- name: Checkout Repository
221+
uses: actions/checkout@v4
222+
with:
223+
submodules: false
224+
225+
- name: Download log
226+
uses: actions/download-artifact@v4
227+
with:
228+
name: ${{ matrix.os }}-autoharness-verification.log.gz
229+
230+
- name: Download kani-list.json
231+
uses: actions/download-artifact@v4
232+
with:
233+
name: ${{ matrix.os }}-kani-list.json
234+
235+
- name: Download scanner results
236+
uses: actions/download-artifact@v4
237+
with:
238+
name: ${{ matrix.os }}-results.tar.gz
239+
240+
- name: Run log parser
241+
run: |
242+
gunzip autoharness-verification.log.gz
243+
tar xzf results.tar.gz
244+
python3 scripts/kani-std-analysis/log_parser.py \
245+
--kani-list-file kani-list.json \
246+
--analysis-results-dir results/ \
247+
autoharness-verification.log \
248+
-o results.json
249+
250+
- name: Upload JSON
251+
uses: actions/upload-artifact@v4
252+
with:
253+
name: ${{ matrix.os }}-results.json
254+
path: results.json
255+
if-no-files-found: error
136256

137257
run-kani-list:
138258
name: Kani List
@@ -188,12 +308,14 @@ jobs:
188308
# Step 3: Add output to job summary
189309
- name: Add Autoharness Analyzer output to job summary
190310
run: |
311+
pushd scripts/autoharness_analyzer
191312
echo "# Autoharness Failure Summary" >> "$GITHUB_STEP_SUMMARY"
192313
echo "## Crate core, all functions" >> "$GITHUB_STEP_SUMMARY"
193-
cat autoharness_analyzer/core_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"
314+
cat core_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"
194315
echo "## Crate core, unsafe functions" >> "$GITHUB_STEP_SUMMARY"
195-
cat autoharness_analyzer/core_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"
316+
cat core_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"
196317
echo "## Crate std, all functions" >> "$GITHUB_STEP_SUMMARY"
197-
cat autoharness_analyzer/std_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"
318+
cat std_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"
198319
echo "## Crate std, unsafe functions" >> "$GITHUB_STEP_SUMMARY"
199-
cat autoharness_analyzer/std_unsafe_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"
320+
cat std_unsafe_autoharness_data.md >> "$GITHUB_STEP_SUMMARY"
321+
popd

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Session.vim
2222
/kani_build/
2323
/target
2424
library/target
25+
scripts/autoharness_analyzer/target/
2526
*.rlib
2627
*.rmeta
2728
*.mir

doc/mdbook-metrics/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ edition = "2021"
55

66
[dependencies]
77
mdbook = { version = "^0.4" }
8+
mdbook-linkcheck = "0.7.7"
89
serde_json = "1.0.132"

doc/src/SUMMARY.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,8 @@
3232
- [16: Verify the safety of Iterator functions](./challenges/0016-iter.md)
3333
- [17: Verify the safety of slice functions](./challenges/0017-slice.md)
3434
- [18: Verify the safety of slice iter functions](./challenges/0018-slice-iter.md)
35+
- [19: Safety of `RawVec`](./challenges/0019-rawvec.md)
36+
- [20: Verify the safety of char-related functions in str::pattern](./challenges/0020-str-pattern-pt1.md)
37+
- [21: Verify the safety of substring-related functions in str::pattern](./challenges/0021-str-pattern-pt2.md)
38+
- [22: Verify the safety of str iter functions](./challenges/0022-str-iter.md)
39+
- [25: Verify the safety of `VecDeque` functions](./challenges/0025-vecdeque.md)

doc/src/challenges/0007-atomic-types.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,18 @@ Write and verify safety contracts for the unsafe functions:
8787
- `atomic_umax`
8888
- `atomic_umin`
8989

90+
##### Panicking (Optional)
9091
Then, for each of the safe abstractions that invoke the unsafe functions listed above, write contracts that ensure that they are not invoked with `order`s that would cause panics.
9192

9293
For example, `atomic_store` panics if invoked with `Acquire` or `AcqRel` ordering.
9394
In this case, you would write contracts on the safe `store` methods that enforce that they are not called with either of those `order`s.
9495

96+
This section is not required to complete the challenge, since panicking is not undefined behavior.
97+
However, it would be incorrect for someone to call these functions with the wrong arguments, so we encourage providing these specifications.
98+
9599
#### Part 3: Atomic Intrinsics
96100

97-
Write and verify safety contracts for the intrinsics invoked by the unsafe functions from Part 2 (in `core::intrinsics`):
101+
Write safety contracts for the intrinsics invoked by the unsafe functions from Part 2 (in `core::intrinsics`):
98102

99103
| Operations | Functions |
100104
|-----------------------|-------------|

doc/src/challenges/0019-rawvec.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Challenge 25: Verify the safety of `RawVec` functions
2+
3+
- **Status:** Open
4+
- **Tracking Issue:** [#283](https://github.com/model-checking/verify-rust-std/issues/283)
5+
- **Start date:** *2025-03-07*
6+
- **End date:** *2025-10-17*
7+
- **Reward:** *10000 USD*
8+
9+
-------------------
10+
11+
12+
## Goal
13+
14+
Verify the safety of `RawVec` functions in (library/alloc/src/raw_vec/mod.rs).
15+
16+
## Motivation
17+
18+
`RawVec` is the type of the main component of both `Vec` and `VecDeque`: the buffer. Therefore, the safety of the functions of `Vec` and `VecDeque` depend on the safety of `RawVec`.
19+
20+
### Success Criteria
21+
22+
Verify the safety of the following functions in (library/alloc/src/raw_vec/mod.rs):
23+
24+
Write and prove the contract for the safety of the following unsafe functions:
25+
26+
| Function |
27+
|---------|
28+
|new_cap|
29+
|into_box|
30+
|from_raw_parts_in|
31+
|from_nonnull_in|
32+
|set_ptr_and_cap|
33+
|shrink_unchecked|
34+
|deallocate|
35+
36+
Prove the absence of undefined behavior for following safe abstractions:
37+
38+
| Function |
39+
|---------|
40+
|drop|
41+
|new_in|
42+
|with_capacity_in|
43+
|try_allocate_in|
44+
|current_memory|
45+
|try_reserve|
46+
|try_reserve_exact|
47+
|grow_amortized|
48+
|grow_exact|
49+
|shrink|
50+
|finish_grow|
51+
52+
The verification must be unbounded---it must hold for slices of arbitrary length.
53+
54+
The verification must hold for generic type `T` (no monomorphization).
55+
56+
### List of UBs
57+
58+
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):
59+
60+
* Accessing (loading from or storing to) a place that is dangling or based on a misaligned pointer.
61+
* Reading from uninitialized memory except for padding or unions.
62+
* Mutating immutable bytes.
63+
* Producing an invalid value
64+
65+
66+
Note: All solutions to verification challenges need to satisfy the criteria established in the [challenge book](../general-rules.md)
67+
in addition to the ones listed above.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Challenge 20: Verify the safety of char-related functions in str::pattern
2+
3+
- **Status:** Open
4+
- **Tracking Issue:** [#277](https://github.com/model-checking/verify-rust-std/issues/277)
5+
- **Start date:** *2025-03-07*
6+
- **End date:** *2025-10-17*
7+
- **Reward:** *25000 USD*
8+
9+
-------------------
10+
## Goal
11+
Verify the safety of char-related `Searcher` methods in `str::pattern`.
12+
13+
## Motivation
14+
15+
String and `str` types are widely used in Rust programs, so it is important that their associated functions do not cause undefined behavior.
16+
17+
## Description
18+
19+
The following str library functions are generic over the `Pattern` trait (https://doc.rust-lang.org/std/str/pattern/trait.Pattern.html):
20+
- `contains`
21+
- `starts_with`
22+
- `ends_with`
23+
- `find`
24+
- `rfind`
25+
- `split`
26+
- `split_inclusive`
27+
- `rsplit`
28+
- `split_terminator`
29+
- `rsplit_terminator`
30+
- `splitn`
31+
- `rsplitn`
32+
- `split_once`
33+
- `rsplit_once`
34+
- `rmatches`
35+
- `match_indices`
36+
- `rmatch_indices`
37+
- `trim_matches`
38+
- `trim_start_matches`
39+
- `strip_prefix`
40+
- `strip_suffix`
41+
- `trim_end_matches`
42+
These functions accept a pattern as input, then call [into_searcher](https://doc.rust-lang.org/std/str/pattern/trait.Pattern.html#tymethod.into_searcher) to create a [Searcher](https://doc.rust-lang.org/std/str/pattern/trait.Pattern.html#associatedtype.Searcher) for the pattern. They use this `Searcher` to perform their desired operations (split, find, etc.).
43+
Those functions are implemented in (library/core/src/str/mod.rs), but the core of them are the searching algorithms which are implemented in (library/core/src/str/pattern.rs).
44+
45+
### Assumptions
46+
47+
**Important note:** for this challenge, you can assume:
48+
1. The safety and functional correctness of all functions in `slice` module.
49+
2. That all functions in (library/core/src/str/validations.rs) are functionally correct (consistent with the UTF-8 encoding description in https://en.wikipedia.org/wiki/UTF-8).
50+
3. That all the Searchers in (library/core/src/str/iter.rs) are created by the into_searcher(_, haystack) with haystack being a valid UTF-8 string (str). You can assume any UTF-8 string property of haystack.
51+
52+
Verify the safety of the functions in (library/core/src/str/pattern.rs) listed in the next section.
53+
54+
The safety properties we are targeting are:
55+
1. No undefined behavior occurs after the Searcher is created.
56+
2. The impls of unsafe traits `Searcher` and `ReverseSearcher` satisfy the SAFETY condition stated in the file:
57+
```
58+
/// The trait is marked unsafe because the indices returned by the
59+
/// [`next()`][Searcher::next] methods are required to lie on valid utf8
60+
/// boundaries in the haystack. This enables consumers of this trait to
61+
/// slice the haystack without additional runtime checks.
62+
```
63+
This property should hold for next_back() of `ReverseSearcher` too.
64+
65+
66+
### Success Criteria
67+
68+
Verify the safety of the following functions in (library/core/src/str/pattern.rs) :
69+
- `next`
70+
- `next_match`
71+
- `next_back`
72+
- `next_match_back`
73+
- `next_reject`
74+
- `next_back_reject`
75+
for the following `Searcher`s:
76+
- `CharSearcher`
77+
- `MultiCharEqSearcher`
78+
- `CharArraySearcher`
79+
- `CharArrayRefSearcher`
80+
- `CharSliceSearcher`
81+
- `CharPredicateSearcher`
82+
83+
The verification is considered successful if for each `Searcher` above, you can specify a condition (a "type invariant") `C` and prove that:
84+
1. If the `Searcher` is created from any valid UTF-8 haystack, it satisfies `C`.
85+
2. If the `Searcher` satisfies `C`, it ensures the two safety properties mentioned in the previous section.
86+
3. If the `Searcher` satisfies `C`, after it calls any function above and gets modified, it still satisfies `C`.
87+
88+
Furthermore, you must prove the absence of undefined behaviors listed in the next section.
89+
90+
The verification must be unbounded---it must hold for inputs of arbitrary size.
91+
92+
### List of UBs
93+
94+
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):
95+
96+
* Accessing (loading from or storing to) a place that is dangling or based on a misaligned pointer.
97+
* Reading from uninitialized memory except for padding or unions.
98+
* Mutating immutable bytes.
99+
* Producing an invalid value
100+
101+
102+
Note: All solutions to verification challenges need to satisfy the criteria established in the [challenge book](../general-rules.md)
103+
in addition to the ones listed above.

0 commit comments

Comments
 (0)