|
|
|
|
|
by tyoverby
3330 days ago
|
|
> I think the generalization of "use-after-free" to "use-after-invalidation" is the most important > I wonder if this sort of vulnerability is possible in Rust Rusts borrow checker is designed for the more general case of "use-after-invalidation" and `free` is treated as a simple invalidation of what happens to be a heap allocated structure. Interestingly, the borrow checker also prevents invalidations that are still common in memory-safe languages such as iterator invalidation. |
|
The trick here is that the decode() method consumes the decoder, and then returns it in the output. In the case of decoding an IO stream, the D::Done type is the IO stream itself, which means that in the event of an error, we ensure that the user can't accidentally use the IO stream again in an incompletely decoded state because all they have is the error type, D::Error (they can intentionally use the IO stream again by recovering the IO stream handle from the D::Error type).
In practice, the above results in decode() implementations that look like the following:
This is a bit more verbose, but as I also make use of Rust's procedural macros you'd also never actually write the above code; it's auto-derived/auto-generated for you 99% of the time. Equally, if I ever do make a mistake in the auto-generation this state-machine-like approach makes it very likely that the resulting auto-generated code won't even compile.