You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/en/unsafe/generalities.md
+1-89Lines changed: 1 addition & 89 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -119,7 +119,7 @@ without an `unsafe` block must be marked as `unsafe` if it breaks these
119
119
invariants. The choice and knowledge of these invariants are therefore crucial
120
120
for secure development.
121
121
122
-
###Example 1: Preserving a type invariant
122
+
## Example: Preserving a type invariant
123
123
124
124
The following code comes from the [Rustonomicon](https://doc.rust-lang.org/nomicon/working-with-unsafe.html).
125
125
It could be used to implement a custom `Vec` type.
@@ -137,91 +137,3 @@ This invariant can be broken with *safe* code. For instance
137
137
```
138
138
139
139
This function may be necessary for internal use, but it should not be exposed in the API, or it should be marked with the `unsafe` keyword, because its use can lead to UB.
140
-
141
-
### Example 2: Trust relationship between *safe* and *unsafe*
142
-
143
-
In the Rust paradigm:
144
-
145
-
> `unsafe`-free code cannot go wrong
146
-
147
-
which means it cannot result in UB.
148
-
This property is lost when developers use *unsafe* code, so they are responsible for not producing UB in any scenario.
149
-
Consequently, even *safe* functions must be handled carefully in *unsafe* contexts.
150
-
151
-
Suppose one wants to propose an API to find an object of a given type in memory.
152
-
This API could require implementing the following trait:
* If the `Locatable` implementation does not give the index of an object of type `T`, the `read_unaligned` may produce UB.
171
-
* If the `Locatable` implementation gives an out-of-bounds index or an index for which part of the object is out of bounds, the subsequent buffer overflow is UB.
172
-
173
-
</div>
174
-
175
-
For instance, the following `Locatable` implementation is incorrect, **but** it is the responsibility of the API author to take it into account.
error: Undefined Behavior: in-bounds pointer arithmetic failed: attempting to offset pointer by 101 bytes, but got alloc249 which is only 3 bytes from the end of the allocation
194
-
--> src/overflow.rs:16:29
195
-
|
196
-
16 | let ptr: *const T = buf.as_ptr().add(start).cast();
197
-
| ^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
198
-
|
199
-
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
200
-
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
201
-
help: alloc249 was allocated here:
202
-
--> src/overflow.rs:22:9
203
-
|
204
-
22 | let buf = [4, 1, 99];
205
-
| ^^^
206
-
= note: BACKTRACE (of the first span):
207
-
= note: inside `find::<bool>` at src/overflow.rs:16:29: 16:52
208
-
note: inside `main`
209
-
--> src/overflow.rs:23:38
210
-
|
211
-
23 | let located_bool: Option<bool> = find(&buf); // UB here!
212
-
| ^^^^^^^^^^
213
-
214
-
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
215
-
216
-
error: aborting due to 1 previous error
217
-
```
218
-
219
-
This example shows that developers using `unsafe` blocks
220
-
cannot assume that *safe* functions or traits they use are well implemented, and thus must prevent UB in case these *safe* functions have bad behavior.
221
-
222
-
If they cannot protect their function against poorly implemented *safe* functions or traits, they have two options:
223
-
224
-
* Mark the function they *write* as `unsafe`: thus, it is the user's responsibility to provide correct arguments (by checking the `unsafe` function's documentation).
225
-
* Mark the traits they *use* as `unsafe`: thus, it is the user's responsibility to implement the trait properly (again, by reading the trait documentation).
226
-
227
-
More examples can be found in [@rust-book] (in the [Unsafe Rust](https://doc.rust-lang.org/book/ch20-01-unsafe-rust.html) chapter) or the [nomicon](https://doc.rust-lang.org/nomicon/safe-unsafe-meaning.html).
Copy file name to clipboardExpand all lines: src/fr/unsafe/generalities.md
+1-96Lines changed: 1 addition & 96 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -133,7 +133,7 @@ tout code `unsafe` DOIT être encapsulé de manière :
133
133
134
134
Ainsi, une fonction utilisant des opérations `unsafe` peut-être sûre (et donc sans marque `unsafe`) si les opérations `unsafe` ne présentent pas d'*UB* étant donnés les invariants du composant (typiquement l'invariant de type pour une méthode). Inversement, une fonction sans bloc `unsafe` doit être marquée `unsafe` si elle casse ces invariants. Le choix et la connaissance de ces invariants sont donc cruciaux pour le développement sécurisé.
135
135
136
-
###Exemple 1 : préservation d'un invariant de type
136
+
## Exemple : préservation d'un invariant de type
137
137
138
138
La protection des invariants d'une bibliothèque est primordiale pour se prémunir de
139
139
bugs en général, d'*UB* en particulier.
@@ -158,98 +158,3 @@ Or, il est possible de casser cet invariant avec du code *safe*. Par exemple, co
158
158
Si elle peut être tout à fait légitime pour du code *interne* à l'API,
159
159
cette méthode ne doit pas être exposée par l'API ou alors doit être annotée
160
160
par `unsafe` car elle peut conduire à des *UB* (même si elle ne comporte pas de blocs *unsafe*s).
161
-
162
-
### Exemple 2 : relation de confiance *safe*/*unsafe*
163
-
164
-
La relation de confiance entre le code *safe* et le code `unsafe` est délicate.
165
-
Dans un composant logiciel, le code `unsafe` doit être écrit de manière à ce qu'aucun usage *safe* du composant ne puisse conduire à des *UB*.
166
-
167
-
Le cas suivant illustre ce principe.
168
-
On souhaite ici proposer une API générique permettant de localiser un objet dans une zone mémoire.
169
-
On demande donc à l'utilisateur de l'API de fournir une implémentation à ce trait :
L'API du trait `Locatable` est mauvaise pour deux raisons :
186
-
187
-
* si l'implémentation de `Locatable` ne donne pas l'index d'un objet de type `T`, alors la fonction `read_unaligned` peut produire un *UB*.
188
-
* si l'implémentation de `Locatable` renvoie un index en dehors du tableau ou un index tel que l'objet de type `T` ne soit pas entièrement contenu dans le tableau, alors un dépassement de tableau se produit.
189
-
190
-
</div>
191
-
192
-
Par exemple, cette implémentation de `Locatable` est fautive alors qu'elle n'est pas `unsafe` :
error: Undefined Behavior: in-bounds pointer arithmetic failed: attempting to offset pointer by 101 bytes, but got alloc249 which is only 3 bytes from the end of the allocation
211
-
--> src/overflow.rs:16:29
212
-
|
213
-
16 | let ptr: *const T = buf.as_ptr().add(start).cast();
214
-
| ^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
215
-
|
216
-
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
217
-
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
218
-
help: alloc249 was allocated here:
219
-
--> src/overflow.rs:22:9
220
-
|
221
-
22 | let buf = [4, 1, 99];
222
-
| ^^^
223
-
= note: BACKTRACE (of the first span):
224
-
= note: inside `find::<bool>` at src/overflow.rs:16:29: 16:52
225
-
note: inside `main`
226
-
--> src/overflow.rs:23:38
227
-
|
228
-
23 | let located_bool: Option<bool> = find(&buf); // UB here!
229
-
| ^^^^^^^^^^
230
-
231
-
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
232
-
233
-
error: aborting due to 1 previous error
234
-
```
235
-
236
-
Dans cet exemple, il est rappelé que la responsabilité de l'exécution *safe*
237
-
(sans *UB*) d'un code Rust incombe à la personne utilisant des blocs *unsafe*.
238
-
239
-
S'il n'est pas possible de se protéger contre les fonctions/traits *safe*s lors de l'écriture d'une fonction contenant un bloc *unsafe*, deux solutions sont possibles :
240
-
241
-
* marquer la fonction comme *unsafe* : ainsi la responsabilité de sa bonne exécution revient à la personne utilisant cette fonction, notamment en l'obligeant à vérifier dans la documentation de la fonction que les arguments fournis répondent bien à la spécification de la fonction
242
-
* marquer le trait dont dépend la fonction comme *unsafe* : ainsi, de même, la responsabilité de la bonne exécution du programme revient à l'implémenteur du trait en s'assurant que l'implémentation répond bien aux spécifications du trait (présente dans sa documentation).
243
-
244
-
On pourra se référer à [@rust-book] (au chapitre [Unsafe Rust](https://doc.rust-lang.org/book/ch20-01-unsafe-rust.html)) où au [nomicon](https://doc.rust-lang.org/nomicon/safe-unsafe-meaning.html) pour d'autres exemples.
245
-
246
-
<!--
247
-
Dans ce cas particulier, la solution la plus adaptée est sans doute de marquer le trait `Locatable` comme `unsafe` :
0 commit comments