Mark try_from_bytes function as unsafe
kitcatier opened this issue · 4 comments
Hello, I found a soundness issue in this crate.
Lines 249 to 259 in b19f8ab
Lines 140 to 150 in b19f8ab
The unsafe function called needs to ensure that the parameter must be :
-
If the slice isn't aligned for the new type
-
If the slice's length isn’t exactly the size of the new type
and the developer who calls the try_from_bytes function may not notice this safety requirement.
Marking them unsafe also means that callers must make sure they know what they're doing.
The unsafe function called needs to ensure that the parameter must be:
- If the slice isn't aligned for the new type
- If the slice's length isn’t exactly the size of the new type
and the developer who calls the try_from_bytes function may not notice this safety requirement
These are listed as "Failure" cases for internal::try_from_bytes
Lines 133 to 140 in b19f8ab
internal::try_from_bytes
, and failing one of them will not cause unsoundness (since it will always be caught).
Note that all of the internal::*
functions are pub(crate)
, meaning they cannot be called from outside bytemuck
itself, and are essentially implementation details.
The publicly-exported functions in bytemuck
do not need to be marked unsafe fn
because they uphold their safety preconditions through their trait bounds; e.g. cast
ing from u8
to bool
would be unsound in general, but let x: bool = bytemuck::cast(3u8);
does not compile because bool
does not implement AnyBitPattern
. Thus, it is up to the implementors of AnyBitPattern
/NoUninit
to ensure soundness (which is valid, since they are unsafe trait
s, which require unsafe impl
to implement).
(Perhaps the documentation for the internal::*
functions could be updated to contain their safety preconditions for clarity, and // SAFETY
comments could be added to their usages, but this would have no effect on the public API of the crate, so it would not be necessary to mark any publicly-exported functions as unsafe
).
I do not believe any of these snippets indicate unsoundness in this crate. Do you have a concrete example of unsoundness caused by this crate (e.g. a program that has undefined behavior because of this crate)?
The unsafe function called needs to ensure that the parameter must be:
- If the slice isn't aligned for the new type
- If the slice's length isn’t exactly the size of the new type
and the developer who calls the try_from_bytes function may not notice this safety requirement
These are listed as "Failure" cases for
internal::try_from_bytes
Lines 133 to 140 in b19f8ab
I.e. they are situations where the function will return an error (guaranteed). They are not safety preconditions of
internal::try_from_bytes
, and failing one of them will not cause unsoundness (since it will always be caught).
Note that all of theinternal::*
functions arepub(crate)
, meaning they cannot be called from outsidebytemuck
itself, and are essentially implementation details.The publicly-exported functions in
bytemuck
do not need to be markedunsafe fn
because they uphold their safety preconditions through their trait bounds; e.g.cast
ing fromu8
tobool
would be unsound in general, butlet x: bool = bytemuck::cast(3u8);
does not compile becausebool
does not implementAnyBitPattern
. Thus, it is up to the implementors ofAnyBitPattern
/NoUninit
to ensure soundness (which is valid, since they areunsafe trait
s, which requireunsafe impl
to implement).(Perhaps the documentation for the
internal::*
functions could be updated to contain their safety preconditions for clarity, and// SAFETY
comments could be added to their usages, but this would have no effect on the public API of the crate, so it would not be necessary to mark any publicly-exported functions asunsafe
).I do not believe any of these snippets indicate unsoundness in this crate. Do you have a concrete example of unsoundness caused by this crate (e.g. a program that has undefined behavior because of this crate)?
That's right, I see, thanks
If you're satisfied we could close the issue, but I'd also be happy if you wanted to send in a PR that better explains the safety invariants of the internal functions.