Give schemes a dangling address for empty slices.

This allows schemes to avoid checking the length against zero before
constructing a slice from pointer+len that the kernel gave.
Additionally, the address is now non-canonical on x86, meaning that
userspace will fail instead of continuing with UB, if they would ever
forget to check the length.
This commit is contained in:
4lDO2
2021-02-20 17:14:39 +01:00
parent a283160c14
commit ad58ca1de6

View File

@@ -131,7 +131,18 @@ impl UserInner {
// TODO: More abstractions over grant creation!
if size == 0 {
return Ok(VirtualAddress::new(0));
// NOTE: Rather than returning NULL, we return a dummy dangling address, that is also
// non-canonical on x86. This means that scheme handlers do not need to check the
// length before creating a Rust slice (which cannot have NULL as address regardless of
// the length; this actually made nulld think that an empty path was invalid UTF-8
// because of enum layout optimization), independent of whatever alignment this slice
// will have. Additionally, they would generate a general protection fault immediately
// if they ever tried to access this dangling address.
// Set the most significant bit.
let dangling: usize = 1 << (core::mem::size_of::<usize>() * 8 - 1);
return Ok(VirtualAddress::new(dangling));
}
let context_lock = context_weak.upgrade().ok_or(Error::new(ESRCH))?;