In the wasi crate, I noticed fd_read takes a &[IoVec] (IoVec is basically a *mut [u8]) and writes into it from the given file descriptor.
No mutable reference is created, and the mutation is done by an extern fn call, but this still seems odd to me, as it looks like a way to perform mutation behind a shared reference outside of UnsafeCell.
Does the fact that it's a raw pointer rather than a reference make it okay?
Creating a mutable reference would be valid, too. (Provided the pointer is valid for reading+writing and only one mutable reference is created and used at a time across all copies of the same pointer. And many other ways of using the pointer may not overlap/interleave with the active lifetime of such a mutable reference either.)
There are lots of similarities between *mut T and &UnsafeCell<T>; both allow shared mutable access.
Indeed. Raw pointers basically are another kind of interior mutability primitive. So as long as you don't create overlapping &muts out of them, mutation through a *mutin itself should not be unsound.
What determines whether it's safe to write through a raw pointer is how the raw pointer was originally created - things that just move it around (including copying or casting it) do not change what you can do with a particular raw pointer.
The reason that UnsafeCell exists even though raw pointers can do the same thing is that an UnsafeCell works without a pointer-indirection, whereas a raw pointer requires, well, that you have a pointer.