Central traits
Drop
trait, the destructor
Types implement the trait std::ops::Drop
to perform some operations when the
memory associated with a value of this type is to be reclaimed. Drop
is the
Rust equivalent of a destructor in C++ or a finalizer in Java.
Dropping is done recursively from the outer value to the inner values.
When a value goes out of scope (or is explicitly dropped with std::mem::drop
),
the value is dropped in two steps. The first step happens only if the type of
this value implements Drop
. It consists in calling the drop
method on it.
The second step consists in repeating the dropping process recursively on any
field the value contains. Note that a Drop
implementation is
only responsible for the outer value.
First and foremost, implementing Drop
should not be systematic.
It is only needed if the type requires some destructor logic. In fact, Drop
is
typically used to release external resources (network connections, files, etc.)
or to release memory (e.g. in smart pointers such as Box
or Rc
).
As a result, Drop
trait implementations are likely to contain unsafe
code
blocks as well as other security-critical operations.
In a Rust secure development, the implementation of the
std::ops::Drop
trait should be justified, documented and peer-reviewed.
Second, Rust type system only ensures memory safety and, from the type system's standpoint, missing drops is allowed. In fact, several things may lead to missing drops, such as:
- a reference cycle (for instance, with
Rc
orArc
), - an explicit call to
std::mem::forget
(orcore::mem::forget
) (see paragraph on Forget and memory leaks, - a panic in drop,
- program aborts (and panics when abort-on-panic is on).
And missing drops may lead to exposing sensitive data or to lock limited resources leading to unavailability issues.
In a Rust secure development, the implementation of the
std::ops::Drop
trait must not panic.
Beside panics, secure-critical drop should be protected.
Value whose type implements
Drop
must not be embedded directly or indirectly in a cycle of reference-counted references.
Ensuring security operations at the end of some treatment (such as key erasure at the end of a cryptographic encryption) should not rely only on the
Drop
trait implementation.