-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add T: Copy and remove T: Default::default #3
Comments
I suppose this might work since
although I'd feel safer with another solution. |
I originally had a The problem with Even if the value is "going away", it's best to be careful to avoid UB, since there's no telling what the compiler is going to do in that case (and it would certainly break if/when someone decides to make an UBSAN for Rust). One could create a new In fact, I hadn't even thought of using Given all that, my opinion is that it's better for now to require the wrapper implementing If you want ease-of-use, how about giving the user a predefined set of wrappers for power-of-two arrays, since these are the common sizes in cryptography, and implement Or perhaps lobby the compiler to implement the traits not only for every size up to 32, but also for every power-of-two size up to 4096? It should be only seven more implementations, so wouldn't bloat libstd too much, and would catch a lot of common situations. |
I've just done a branch that does this https://github.com/burdges/clear_on_drop/tree/copy so it's only I suppose
which resets If powers of two were the issue, then we could both lobby for powers of two mid term and use this short term fix
It would not work for my use case however which involves manipulating the output of SHAKE or ChaCha in key derivation functions and key schedulers, but complex key derivation functions like that should be rare enough that doing an extra I'd be mildly annoyed if my code appeared as breaking any RFCs for type-level numerics, but a manual I suppose I'm still nervous about lacking |
Now there might be reasons to lack |
To me it seems like the only interesting problem is given (1) is std::ptr::drop_in_place (2) is write_bytes (memset) but (3) I'm not sure. A wrapper type ("NoDrop" / "ManuallyDrop") inside the box is a solution. |
I'd think you could do that with an enum like
It might not even consume additional space if I'm assuming here that the two assignments here do not trigger calls to Also, I'm wondering if there is any advantage to replacing
Are there cryptographic objects that should not satisfy |
I'd just overwrite with zero bytes. Using default and regular assignments doesn't guarantee overwriting padding in structs and so on. |
Right, so data can leak if anyone used a |
Adds support for unsized types and provides a possible answer to cesarb#3 However, the `impl<T> Clearable for T where T: Copy` remains problematic because `Shared<T>: Copy`. There are worse implementers for `Default` like `Box`, `Arc`, and `Rc`, but we could avoids all current pointer types with `impl<T> Clearable for T where T: Copy+Default`.
This might address the concerns exlained in cesarb#3 (comment) and cesarb#7 This reverts commit 88b4c4f. Conflicts: src/clearable.rs
I'm going to close this because my pull request for a |
We need type level numerics before
Default ::default()
, or any trait based approach, can work for large arrays, because users cannotimpl Default for [u8; 256]
since neitherDefault
nor[u8; 256]
were defined in their crate.We cannot create a macro that builds everything from
clear_on_drop.rs
andcore/default.rs
onto a user version ofDefault::default()
because then nobody can call across crate boundaries. In fact, users can still wrap their types so that they canimpl Default
for the wrapper, but that results in boilerplate code like this :You need
T: Copy
anyways because otherwiseClearOnDrop<T>
works withT: Drop
types. I initially tried to support a limited subset ofDrop
types in https://github.com/burdges/zerodrop-rs/blob/master/src/zdd.rs#L42 but @bluss pointed out irreparable problems burdges/zerodrop-rs#7 in fact, we do not know that*_place = Default::default()
does not read*_place
out onto the stack to call the destructor ifT: Drop
.I believe we can justify zeroing a
T: Copy
type with a simplememset
like operation. We might violate acore::nonzero::NonZero
bound applied to a non-pointer type, which afaik do not yet exist. That's okay ifP
isBox<T>
, etc. sinceT
is going away andCopy
types cannot beDrop
. About the only way to violate that assumption is with something likeI think the question now becomes: Which memset? You explained the problems with
core::intrinsics::volatile_set_memory
. We could calllibc::memset
or write a new one. Anything I'm missing?The text was updated successfully, but these errors were encountered: