-
Notifications
You must be signed in to change notification settings - Fork 43
Description
It appears that the DMA API described in Chapter 8 - DMA is unsafe.
Consider this example. It is basically the motivating example from the "Immovable buffers" section, but with the complete read_exact API from the end of the chapter, including Pining and the 'static bound. The example shows that it is still possible to pass a stack-allocated array into this (supposedly safe) read_exact function, which means the DMA operation will corrupt the stack. All you need to do is wrap the array in a newtype and impl DerefMut for it.
I believe the root of the issue is a misunderstanding of the Pin API. Contrary to intuition, Pin does in most cases not pin the pointed-to data in memory: If the target type implements Unpin, Pin does nothing at all:
Many types are always freely movable, even when pinned, because they do not rely on having a stable address. This includes all the basic types (like
bool,i32, and references) as well as types consisting solely of these types. Types that do not care about pinning implement theUnpinauto-trait, which cancels the effect ofPin<P>.
Basically all types we care about implement Unpin (I believe only self-referential types are supposed not to?). Which means Pining the buffer passed into the DMA doesn't help us make the code safe.
The DMA chapter also mentions the StableDeref trait as an alternative. As far as I see, using this would actually lead to a safe API, so we should change the chapter accordingly.