Repository navigation
Add opt-in wiping of library-owned temporary buffers - #1365
Open
MattJackson wants to merge 6 commits into
Open
MattJackson wants to merge 6 commits into
MattJackson wants to merge 6 commits into
Conversation
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
serde_json can leave plaintext in allocations that applications cannot reach to wipe: parser scratch, custom error text, and old serialization buffers released during growth. This adds an opt-in
zeroizefeature for those library-owned temporary heap buffers. Related to #874 and #1093; it does not add wiping toValueitself.The feature covers parser scratch across slice, reader, and stream input; 128-bit and arbitrary-precision numeric scanning; binary heap arithmetic buffers used by float_roundtrip, including multiplication/Karatsuba temporaries; raw-value reader buffers and UTF-8 errors; hidden number/raw-value adapters before visitor ownership transfer; custom error text and Debug temporaries; and serialization output growth and failure before output is returned. Internal raw-value formatting and string-to-box shrinking also keep the temporary allocation under a wiping owner.
Growth copies into a new allocation, wipes the old allocation using the
zeroizecrate, then releases it. Private guarded fields handle early returns and unwinding. Public method signatures and returned value types are preserved, and no Drop implementation is added toDeserializer,Value,Number, orRawValue. With the feature disabled, the buffer helpers use the original Vec/String operations.The ownership boundary is documented in the crate docs and README. Input, caller-supplied readers/writers, external I/O errors, and arbitrary Serialize/Deserialize/Display implementations remain their owners' responsibility. Returned values and owned strings delivered to visitors retain normal ownership, including partially constructed output discarded by visitors. A live parser/error may retain its most recent text. This does not cover aborts, forgotten objects, OS/allocator copies, or copies left by moves, the compiler, stack storage, or registers.
The dependency is optional, uses only zeroize's alloc support, and works with std or alloc. Enabling it requires Rust 1.85 because zeroize 1.9 requires that compiler. The default feature set and its Rust 1.71 requirement are unchanged. Wiping and replacing allocations add work when the feature is enabled; performance has not been measured.
Tests add independent non-wiping controls and observe only registered initialized allocation prefixes at their matching live deallocation, never freed memory or inferred owners. Coverage includes growth/reuse/drop, numeric limb clones/replacement/Karatsuba arithmetic, malformed input, partial construction, visitor/formatter rejection, unwinding, error conversion, output ownership, and API/JSON compatibility. Existing upstream fixtures and the math interface are retained. The existing CI workflow gains permanent std/alloc feature combinations, optional-feature MSRV and no-std target checks, and Miri coverage for these tests.
Validation on
19cdf6c033827bd9b36feb61ef19ed301f6906f5: upstream PR CI passed nightly Linux/Windows tests with the selected std/alloc combinations, Rust 1.71/1.85/beta/stable checks, the aarch64 no-std target, documentation, fuzz compilation, minimal versions, and Miri on four 32/64-bit and little/big-endian targets with strict provenance. The combined zeroize feature suite has 42 unit tests. Normal fork push CI also passed, including default/all-feature Clippy. Local validation was limited tocargo fmt --checkandgit diff --check; compilation, tests, and dependency resolution were not run locally.