Skip to main content

kernel_api/ptr/
mod.rs

1//! Provides pointer wrappers for safely accessing userspace
2//! 
3//! All pointers provided from userspace should be accessed through a [`User`] to
4//! prevent kernelspace page faults from invalid or misaligned pointers.
5//! 
6//! # SMAP
7//! 
8//! When SMAP is supported on the system, all memory access through a [`User`] will
9//! automatically set and clear the `AC` flag to prevent trapping.
10
11use core::fmt;
12use core::marker::PhantomData;
13use core::ptr::NonNull;
14
15#[cfg(feature = "full")]
16mod user_ptr;
17#[cfg(feature = "full")]
18pub use user_ptr::*;
19
20#[cfg(feature = "full")]
21mod user_local;
22#[cfg(feature = "full")]
23pub use user_local::*;
24
25#[doc(hidden)]
26pub struct Unique<T: ?Sized> {
27	pointer: NonNull<T>,
28	_marker: PhantomData<T>,
29}
30
31/// `Unique` pointers are `Send` if `T` is `Send` because the data they
32/// reference is unaliased. Note that this aliasing invariant is
33/// unenforced by the type system; the abstraction using the
34/// `Unique` must enforce it.
35unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
36
37/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
38/// reference is unaliased. Note that this aliasing invariant is
39/// unenforced by the type system; the abstraction using the
40/// `Unique` must enforce it.
41unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
42
43impl<T: Sized> Unique<T> {
44	/// Creates a new `Unique` that is dangling, but well-aligned.
45	///
46	/// This is useful for initializing types which lazily allocate, like
47	/// `Vec::new` does.
48	pub fn empty() -> Self {
49		unsafe {
50			Unique::new(NonNull::dangling().as_ptr())
51		}
52	}
53}
54
55impl<T: ?Sized> Unique<T> {
56	/// Creates a new `Unique`.
57	///
58	/// # Safety
59	///
60	/// `ptr` must be non-null.
61	pub const unsafe fn new(ptr: *mut T) -> Unique<T> {
62		Unique { pointer: NonNull::new_unchecked(ptr), _marker: PhantomData }
63	}
64
65	/// Acquires the underlying `*mut` pointer.
66	pub fn as_ptr(self) -> *mut T {
67		self.pointer.as_ptr()
68	}
69
70	/// Dereferences the content.
71	///
72	/// The resulting lifetime is bound to self so this behaves "as if"
73	/// it were actually an instance of T that is getting borrowed. If a longer
74	/// (unbound) lifetime is needed, use `&*my_ptr.ptr()`.
75	pub unsafe fn as_ref(&self) -> &T {
76		&*self.as_ptr()
77	}
78
79	/// Mutably dereferences the content.
80	///
81	/// The resulting lifetime is bound to self so this behaves "as if"
82	/// it were actually an instance of T that is getting borrowed. If a longer
83	/// (unbound) lifetime is needed, use `&mut *my_ptr.ptr()`.
84	pub unsafe fn as_mut(&mut self) -> &mut T {
85		&mut *self.as_ptr()
86	}
87}
88
89impl<T: ?Sized> Clone for Unique<T> {
90	fn clone(&self) -> Self {
91		*self
92	}
93}
94
95impl<T: ?Sized> Copy for Unique<T> {}
96
97impl<T: ?Sized> fmt::Pointer for Unique<T> {
98	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99		fmt::Pointer::fmt(&self.as_ptr(), f)
100	}
101}
102
103#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
104#[path = "x86_64.rs"]
105#[cfg(feature = "full")]
106mod impls;
107
108/// The error returned when a memory access to userspace failed
109#[derive(Debug)]
110#[non_exhaustive]
111pub struct PointerError {}