Skip to content

BufWriter is not panic-safe #30888

Closed
Closed
@dgrunwald

Description

@dgrunwald

There is a panic safety issue in BufWriter: after a inner.write() call panics, the Drop impl of BufWriter calls inner.write() again, which means the buffer contents are potentially written twice. This may cause an application to overwrite parts of a file that it did not mean to overwrite (in a DB engine written in Rust, this could cause unrecoverable data corruption!).

Demonstration: https://play.rust-lang.org/?gist=9991550d3efb38c93df4&version=stable
The expected output of the demo program is File contents: aBBccc, the actual output is: File contents: aBBBBc

More generally, we need a story for panic safety in Rust.
My takeaway from the related discussions (e.g. RFC 1236, #27719, the RecoverSafe trait) was that only unsafe code and Drop impls should have to worry about panic safety. The demo app contains none of these, so I'd consider this a bug in impl Drop for BufWriter. (otherwise all Write implementations would need to provide the strong exception safety guarantee?)

Solution: BufWriter could use temporarily mark the buffer as empty during the inner.write calls; so that the Drop impl doesn't do anything after a panic.

However, this doesn't help if the panic occurs during a bufWriter.get_mut().write() call...

Metadata

Metadata

Assignees

No one assigned

    Labels

    P-mediumMedium priorityT-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions