@@ -46,6 +46,31 @@ unsafe impl ReadableFromBytes for i32 {}
46
46
unsafe impl ReadableFromBytes for i64 { }
47
47
unsafe impl ReadableFromBytes for isize { }
48
48
49
+ /// Specifies that a type can be safely writable to byte slices.
50
+ ///
51
+ /// This means that we don't read undefined values when reading the memory contents (which leads to
52
+ /// UB). It also ensures that no potentially sensitive information is leaked into the byte slices.
53
+ ///
54
+ /// # Safety
55
+ ///
56
+ /// A type must not include padding bytes and must be fully initialsed to safely implement
57
+ /// [`WritableToBytes`] (i.e., it doesn't contain [`MaybeUninit`] fields). A composition of
58
+ /// writable types in a structure is not necessarily writable because it may result in padding
59
+ /// bytes.
60
+ pub unsafe trait WritableToBytes { }
61
+
62
+ // SAFETY: Initialised instances of the following types have no uninitialised portions.
63
+ unsafe impl WritableToBytes for u8 { }
64
+ unsafe impl WritableToBytes for u16 { }
65
+ unsafe impl WritableToBytes for u32 { }
66
+ unsafe impl WritableToBytes for u64 { }
67
+ unsafe impl WritableToBytes for usize { }
68
+ unsafe impl WritableToBytes for i8 { }
69
+ unsafe impl WritableToBytes for i16 { }
70
+ unsafe impl WritableToBytes for i32 { }
71
+ unsafe impl WritableToBytes for i64 { }
72
+ unsafe impl WritableToBytes for isize { }
73
+
49
74
/// A reference to an area in userspace memory, which can be either
50
75
/// read-only or read-write.
51
76
///
@@ -246,4 +271,11 @@ impl UserSlicePtrWriter {
246
271
self . 1 -= len;
247
272
Ok ( ( ) )
248
273
}
274
+
275
+ /// Writes the contents of the given data into the user slice.
276
+ pub fn write < T : WritableToBytes > ( & mut self , data : & T ) -> KernelResult < ( ) > {
277
+ // SAFETY: The input buffer is valid as it's coming from a live
278
+ // reference to a type that implements `WritableToBytes`.
279
+ unsafe { self . write_raw ( data as * const T as _ , size_of :: < T > ( ) ) }
280
+ }
249
281
}
0 commit comments